winevt_c 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.clang-format +4 -4
- data/.github/workflows/linux.yml +26 -0
- data/Gemfile +6 -6
- data/LICENSE.txt +202 -202
- data/README.md +97 -97
- data/Rakefile +37 -37
- data/appveyor.yml +48 -26
- data/example/bookmark.rb +9 -9
- data/example/enumerate_channels.rb +13 -13
- data/example/eventlog.rb +13 -13
- data/example/locale.rb +13 -13
- data/example/rate_limit.rb +14 -14
- data/example/tailing.rb +21 -21
- data/ext/winevt/extconf.rb +24 -24
- data/ext/winevt/winevt.c +30 -30
- data/ext/winevt/winevt_bookmark.c +149 -149
- data/ext/winevt/winevt_c.h +133 -132
- data/ext/winevt/winevt_channel.c +327 -327
- data/ext/winevt/winevt_locale.c +92 -92
- data/ext/winevt/winevt_locale_info.c +68 -68
- data/ext/winevt/winevt_query.c +649 -650
- data/ext/winevt/winevt_session.c +425 -425
- data/ext/winevt/winevt_subscribe.c +756 -757
- data/ext/winevt/winevt_utils.cpp +790 -718
- data/lib/winevt/bookmark.rb +6 -6
- data/lib/winevt/query.rb +6 -6
- data/lib/winevt/session.rb +15 -15
- data/lib/winevt/subscribe.rb +18 -18
- data/lib/winevt/version.rb +3 -3
- data/lib/winevt.rb +14 -14
- data/winevt_c.gemspec +34 -34
- metadata +8 -9
- data/.travis.yml +0 -15
data/ext/winevt/winevt_query.c
CHANGED
@@ -1,650 +1,649 @@
|
|
1
|
-
#include <winevt_c.h>
|
2
|
-
|
3
|
-
/* clang-format off */
|
4
|
-
/*
|
5
|
-
* Document-class: Winevt::EventLog::Query
|
6
|
-
*
|
7
|
-
* Query Windows EventLog channel.
|
8
|
-
*
|
9
|
-
* @example
|
10
|
-
* require 'winevt'
|
11
|
-
*
|
12
|
-
* @query = Winevt::EventLog::Query.new("Application", "*[System[(Level <= 3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]")
|
13
|
-
*
|
14
|
-
* @query.each do |eventlog, message, string_inserts|
|
15
|
-
* puts ({eventlog: eventlog, data: message})
|
16
|
-
* end
|
17
|
-
*/
|
18
|
-
/* clang-format on */
|
19
|
-
|
20
|
-
VALUE rb_cFlag;
|
21
|
-
|
22
|
-
static void query_free(void* ptr);
|
23
|
-
|
24
|
-
static const rb_data_type_t rb_winevt_query_type = { "winevt/query",
|
25
|
-
{
|
26
|
-
0,
|
27
|
-
query_free,
|
28
|
-
0,
|
29
|
-
},
|
30
|
-
NULL,
|
31
|
-
NULL,
|
32
|
-
RUBY_TYPED_FREE_IMMEDIATELY };
|
33
|
-
|
34
|
-
static void
|
35
|
-
close_handles(struct WinevtQuery* winevtQuery)
|
36
|
-
{
|
37
|
-
if (winevtQuery->query) {
|
38
|
-
EvtClose(winevtQuery->query);
|
39
|
-
winevtQuery->query = NULL;
|
40
|
-
}
|
41
|
-
|
42
|
-
for (int i = 0; i < winevtQuery->count; i++) {
|
43
|
-
if (winevtQuery->hEvents[i]) {
|
44
|
-
EvtClose(winevtQuery->hEvents[i]);
|
45
|
-
winevtQuery->hEvents[i] = NULL;
|
46
|
-
}
|
47
|
-
}
|
48
|
-
|
49
|
-
if (winevtQuery->remoteHandle) {
|
50
|
-
EvtClose(winevtQuery->remoteHandle);
|
51
|
-
winevtQuery->remoteHandle = NULL;
|
52
|
-
}
|
53
|
-
}
|
54
|
-
|
55
|
-
static void
|
56
|
-
query_free(void* ptr)
|
57
|
-
{
|
58
|
-
struct WinevtQuery* winevtQuery = (struct WinevtQuery*)ptr;
|
59
|
-
close_handles(winevtQuery);
|
60
|
-
|
61
|
-
xfree(ptr);
|
62
|
-
}
|
63
|
-
|
64
|
-
static VALUE
|
65
|
-
rb_winevt_query_alloc(VALUE klass)
|
66
|
-
{
|
67
|
-
VALUE obj;
|
68
|
-
struct WinevtQuery* winevtQuery;
|
69
|
-
obj =
|
70
|
-
TypedData_Make_Struct(klass, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
71
|
-
return obj;
|
72
|
-
}
|
73
|
-
|
74
|
-
/*
|
75
|
-
* Initalize Query class.
|
76
|
-
*
|
77
|
-
* @overload initialize(channel, xpath, session=nil)
|
78
|
-
* @param channel [String] Querying EventLog channel.
|
79
|
-
* @param xpath [String] Querying XPath.
|
80
|
-
* @param session [Session] Session information for remoting access.
|
81
|
-
* @return [Query]
|
82
|
-
*
|
83
|
-
*/
|
84
|
-
static VALUE
|
85
|
-
rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
|
86
|
-
{
|
87
|
-
PWSTR evtChannel, evtXPath;
|
88
|
-
VALUE channel, xpath, session;
|
89
|
-
struct WinevtQuery* winevtQuery;
|
90
|
-
struct WinevtSession* winevtSession;
|
91
|
-
EVT_HANDLE hRemoteHandle = NULL;
|
92
|
-
DWORD len;
|
93
|
-
VALUE wchannelBuf, wpathBuf;
|
94
|
-
DWORD err;
|
95
|
-
|
96
|
-
rb_scan_args(argc, argv, "21", &channel, &xpath, &session);
|
97
|
-
Check_Type(channel, T_STRING);
|
98
|
-
Check_Type(xpath, T_STRING);
|
99
|
-
|
100
|
-
if (rb_obj_is_kind_of(session, rb_cSession)) {
|
101
|
-
winevtSession = EventSession(session);
|
102
|
-
|
103
|
-
hRemoteHandle = connect_to_remote(winevtSession->server,
|
104
|
-
winevtSession->domain,
|
105
|
-
winevtSession->username,
|
106
|
-
winevtSession->password,
|
107
|
-
winevtSession->flags
|
108
|
-
|
109
|
-
err
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
err
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
winevtQuery->
|
138
|
-
winevtQuery->
|
139
|
-
winevtQuery->
|
140
|
-
winevtQuery->
|
141
|
-
winevtQuery->
|
142
|
-
|
143
|
-
|
144
|
-
ALLOCV_END(
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
*
|
152
|
-
*
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
*
|
167
|
-
*
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
*
|
184
|
-
*
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
*
|
199
|
-
*
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
*
|
216
|
-
*
|
217
|
-
*
|
218
|
-
*
|
219
|
-
*
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
*
|
310
|
-
*
|
311
|
-
* @
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
struct
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
*
|
395
|
-
*
|
396
|
-
*
|
397
|
-
*
|
398
|
-
*
|
399
|
-
*
|
400
|
-
*
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
*
|
417
|
-
*
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
*
|
432
|
-
*
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
*
|
449
|
-
*
|
450
|
-
* @
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
*
|
468
|
-
*
|
469
|
-
* @
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
*
|
485
|
-
*
|
486
|
-
* @
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
*
|
507
|
-
*
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
*
|
527
|
-
*
|
528
|
-
* @
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
*
|
553
|
-
*
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
rb_cQuery
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
/*
|
578
|
-
|
579
|
-
*
|
580
|
-
* @
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
*
|
586
|
-
* @
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
*
|
592
|
-
* @
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
*
|
598
|
-
* @
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
*
|
604
|
-
* @
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
*
|
610
|
-
* @
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
rb_define_method(rb_cQuery, "
|
617
|
-
rb_define_method(rb_cQuery, "
|
618
|
-
rb_define_method(rb_cQuery, "
|
619
|
-
rb_define_method(rb_cQuery, "offset",
|
620
|
-
rb_define_method(rb_cQuery, "
|
621
|
-
rb_define_method(rb_cQuery, "timeout",
|
622
|
-
rb_define_method(rb_cQuery, "
|
623
|
-
rb_define_method(rb_cQuery, "
|
624
|
-
rb_define_method(rb_cQuery, "render_as_xml
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
}
|
1
|
+
#include <winevt_c.h>
|
2
|
+
|
3
|
+
/* clang-format off */
|
4
|
+
/*
|
5
|
+
* Document-class: Winevt::EventLog::Query
|
6
|
+
*
|
7
|
+
* Query Windows EventLog channel.
|
8
|
+
*
|
9
|
+
* @example
|
10
|
+
* require 'winevt'
|
11
|
+
*
|
12
|
+
* @query = Winevt::EventLog::Query.new("Application", "*[System[(Level <= 3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]")
|
13
|
+
*
|
14
|
+
* @query.each do |eventlog, message, string_inserts|
|
15
|
+
* puts ({eventlog: eventlog, data: message})
|
16
|
+
* end
|
17
|
+
*/
|
18
|
+
/* clang-format on */
|
19
|
+
|
20
|
+
VALUE rb_cFlag;
|
21
|
+
|
22
|
+
static void query_free(void* ptr);
|
23
|
+
|
24
|
+
static const rb_data_type_t rb_winevt_query_type = { "winevt/query",
|
25
|
+
{
|
26
|
+
0,
|
27
|
+
query_free,
|
28
|
+
0,
|
29
|
+
},
|
30
|
+
NULL,
|
31
|
+
NULL,
|
32
|
+
RUBY_TYPED_FREE_IMMEDIATELY };
|
33
|
+
|
34
|
+
static void
|
35
|
+
close_handles(struct WinevtQuery* winevtQuery)
|
36
|
+
{
|
37
|
+
if (winevtQuery->query) {
|
38
|
+
EvtClose(winevtQuery->query);
|
39
|
+
winevtQuery->query = NULL;
|
40
|
+
}
|
41
|
+
|
42
|
+
for (int i = 0; i < winevtQuery->count; i++) {
|
43
|
+
if (winevtQuery->hEvents[i]) {
|
44
|
+
EvtClose(winevtQuery->hEvents[i]);
|
45
|
+
winevtQuery->hEvents[i] = NULL;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
if (winevtQuery->remoteHandle) {
|
50
|
+
EvtClose(winevtQuery->remoteHandle);
|
51
|
+
winevtQuery->remoteHandle = NULL;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
static void
|
56
|
+
query_free(void* ptr)
|
57
|
+
{
|
58
|
+
struct WinevtQuery* winevtQuery = (struct WinevtQuery*)ptr;
|
59
|
+
close_handles(winevtQuery);
|
60
|
+
|
61
|
+
xfree(ptr);
|
62
|
+
}
|
63
|
+
|
64
|
+
static VALUE
|
65
|
+
rb_winevt_query_alloc(VALUE klass)
|
66
|
+
{
|
67
|
+
VALUE obj;
|
68
|
+
struct WinevtQuery* winevtQuery;
|
69
|
+
obj =
|
70
|
+
TypedData_Make_Struct(klass, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
71
|
+
return obj;
|
72
|
+
}
|
73
|
+
|
74
|
+
/*
|
75
|
+
* Initalize Query class.
|
76
|
+
*
|
77
|
+
* @overload initialize(channel, xpath, session=nil)
|
78
|
+
* @param channel [String] Querying EventLog channel.
|
79
|
+
* @param xpath [String] Querying XPath.
|
80
|
+
* @param session [Session] Session information for remoting access.
|
81
|
+
* @return [Query]
|
82
|
+
*
|
83
|
+
*/
|
84
|
+
static VALUE
|
85
|
+
rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
|
86
|
+
{
|
87
|
+
PWSTR evtChannel, evtXPath;
|
88
|
+
VALUE channel, xpath, session;
|
89
|
+
struct WinevtQuery* winevtQuery;
|
90
|
+
struct WinevtSession* winevtSession;
|
91
|
+
EVT_HANDLE hRemoteHandle = NULL;
|
92
|
+
DWORD len;
|
93
|
+
VALUE wchannelBuf, wpathBuf;
|
94
|
+
DWORD err = ERROR_SUCCESS;
|
95
|
+
|
96
|
+
rb_scan_args(argc, argv, "21", &channel, &xpath, &session);
|
97
|
+
Check_Type(channel, T_STRING);
|
98
|
+
Check_Type(xpath, T_STRING);
|
99
|
+
|
100
|
+
if (rb_obj_is_kind_of(session, rb_cSession)) {
|
101
|
+
winevtSession = EventSession(session);
|
102
|
+
|
103
|
+
hRemoteHandle = connect_to_remote(winevtSession->server,
|
104
|
+
winevtSession->domain,
|
105
|
+
winevtSession->username,
|
106
|
+
winevtSession->password,
|
107
|
+
winevtSession->flags,
|
108
|
+
&err);
|
109
|
+
if (err != ERROR_SUCCESS) {
|
110
|
+
raise_system_error(rb_eRuntimeError, err);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
// channel : To wide char
|
115
|
+
len =
|
116
|
+
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
|
117
|
+
evtChannel = ALLOCV_N(WCHAR, wchannelBuf, len + 1);
|
118
|
+
MultiByteToWideChar(
|
119
|
+
CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), evtChannel, len);
|
120
|
+
evtChannel[len] = L'\0';
|
121
|
+
|
122
|
+
// xpath : To wide char
|
123
|
+
len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), NULL, 0);
|
124
|
+
evtXPath = ALLOCV_N(WCHAR, wpathBuf, len + 1);
|
125
|
+
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), evtXPath, len);
|
126
|
+
evtXPath[len] = L'\0';
|
127
|
+
|
128
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
129
|
+
|
130
|
+
winevtQuery->query = EvtQuery(
|
131
|
+
hRemoteHandle, evtChannel, evtXPath, EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
|
132
|
+
err = GetLastError();
|
133
|
+
if (err != ERROR_SUCCESS) {
|
134
|
+
raise_system_error(rb_eRuntimeError, err);
|
135
|
+
}
|
136
|
+
winevtQuery->offset = 0L;
|
137
|
+
winevtQuery->timeout = 0L;
|
138
|
+
winevtQuery->renderAsXML = TRUE;
|
139
|
+
winevtQuery->preserveQualifiers = FALSE;
|
140
|
+
winevtQuery->localeInfo = &default_locale;
|
141
|
+
winevtQuery->remoteHandle = hRemoteHandle;
|
142
|
+
|
143
|
+
ALLOCV_END(wchannelBuf);
|
144
|
+
ALLOCV_END(wpathBuf);
|
145
|
+
|
146
|
+
return Qnil;
|
147
|
+
}
|
148
|
+
|
149
|
+
/*
|
150
|
+
* This method returns querying event offset.
|
151
|
+
*
|
152
|
+
* @return [Integer]
|
153
|
+
*/
|
154
|
+
static VALUE
|
155
|
+
rb_winevt_query_get_offset(VALUE self)
|
156
|
+
{
|
157
|
+
struct WinevtQuery* winevtQuery;
|
158
|
+
|
159
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
160
|
+
|
161
|
+
return LONG2NUM(winevtQuery->offset);
|
162
|
+
}
|
163
|
+
|
164
|
+
/*
|
165
|
+
* This method specifies querying event offset.
|
166
|
+
*
|
167
|
+
* @param offset [Integer] offset value
|
168
|
+
*/
|
169
|
+
static VALUE
|
170
|
+
rb_winevt_query_set_offset(VALUE self, VALUE offset)
|
171
|
+
{
|
172
|
+
struct WinevtQuery* winevtQuery;
|
173
|
+
|
174
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
175
|
+
|
176
|
+
winevtQuery->offset = NUM2LONG(offset);
|
177
|
+
|
178
|
+
return Qnil;
|
179
|
+
}
|
180
|
+
|
181
|
+
/*
|
182
|
+
* This method returns timeout value.
|
183
|
+
*
|
184
|
+
* @return [Integer]
|
185
|
+
*/
|
186
|
+
static VALUE
|
187
|
+
rb_winevt_query_get_timeout(VALUE self)
|
188
|
+
{
|
189
|
+
struct WinevtQuery* winevtQuery;
|
190
|
+
|
191
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
192
|
+
|
193
|
+
return LONG2NUM(winevtQuery->timeout);
|
194
|
+
}
|
195
|
+
|
196
|
+
/*
|
197
|
+
* This method specifies timeout value.
|
198
|
+
*
|
199
|
+
* @param timeout [Integer] timeout value
|
200
|
+
*/
|
201
|
+
static VALUE
|
202
|
+
rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
|
203
|
+
{
|
204
|
+
struct WinevtQuery* winevtQuery;
|
205
|
+
|
206
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
207
|
+
|
208
|
+
winevtQuery->timeout = NUM2LONG(timeout);
|
209
|
+
|
210
|
+
return Qnil;
|
211
|
+
}
|
212
|
+
|
213
|
+
/*
|
214
|
+
* Handle the next values. Since v0.6.0, this method is used for
|
215
|
+
* testing only. Please use #each instead.
|
216
|
+
*
|
217
|
+
* @return [Boolean]
|
218
|
+
*
|
219
|
+
* @see each
|
220
|
+
*/
|
221
|
+
static VALUE
|
222
|
+
rb_winevt_query_next(VALUE self)
|
223
|
+
{
|
224
|
+
EVT_HANDLE hEvents[QUERY_ARRAY_SIZE];
|
225
|
+
ULONG count;
|
226
|
+
DWORD status = ERROR_SUCCESS;
|
227
|
+
struct WinevtQuery* winevtQuery;
|
228
|
+
|
229
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
230
|
+
|
231
|
+
if (!EvtNext(winevtQuery->query, QUERY_ARRAY_SIZE, hEvents, INFINITE, 0, &count)) {
|
232
|
+
status = GetLastError();
|
233
|
+
if (ERROR_CANCELLED == status) {
|
234
|
+
return Qfalse;
|
235
|
+
}
|
236
|
+
if (ERROR_NO_MORE_ITEMS != status) {
|
237
|
+
return Qfalse;
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
if (status == ERROR_SUCCESS) {
|
242
|
+
winevtQuery->count = count;
|
243
|
+
for (int i = 0; i < count; i++) {
|
244
|
+
winevtQuery->hEvents[i] = hEvents[i];
|
245
|
+
}
|
246
|
+
|
247
|
+
return Qtrue;
|
248
|
+
}
|
249
|
+
|
250
|
+
return Qfalse;
|
251
|
+
}
|
252
|
+
|
253
|
+
static VALUE
|
254
|
+
rb_winevt_query_render(VALUE self, EVT_HANDLE event)
|
255
|
+
{
|
256
|
+
struct WinevtQuery* winevtQuery;
|
257
|
+
|
258
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
259
|
+
|
260
|
+
if (winevtQuery->renderAsXML) {
|
261
|
+
return render_to_rb_str(event, EvtRenderEventXml);
|
262
|
+
} else {
|
263
|
+
return render_system_event(event, winevtQuery->preserveQualifiers);
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
static VALUE
|
268
|
+
rb_winevt_query_message(EVT_HANDLE event, LocaleInfo* localeInfo, EVT_HANDLE hRemote)
|
269
|
+
{
|
270
|
+
WCHAR* wResult;
|
271
|
+
VALUE utf8str;
|
272
|
+
|
273
|
+
wResult = get_description(event, localeInfo->langID, hRemote);
|
274
|
+
utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1);
|
275
|
+
free(wResult);
|
276
|
+
|
277
|
+
return utf8str;
|
278
|
+
}
|
279
|
+
|
280
|
+
static VALUE
|
281
|
+
rb_winevt_query_string_inserts(EVT_HANDLE event)
|
282
|
+
{
|
283
|
+
return get_values(event);
|
284
|
+
}
|
285
|
+
|
286
|
+
static DWORD
|
287
|
+
get_evt_seek_flag_from_cstr(char* flag_str)
|
288
|
+
{
|
289
|
+
if (strcmp(flag_str, "first") == 0)
|
290
|
+
return EvtSeekRelativeToFirst;
|
291
|
+
else if (strcmp(flag_str, "last") == 0)
|
292
|
+
return EvtSeekRelativeToLast;
|
293
|
+
else if (strcmp(flag_str, "current") == 0)
|
294
|
+
return EvtSeekRelativeToCurrent;
|
295
|
+
else if (strcmp(flag_str, "bookmark") == 0)
|
296
|
+
return EvtSeekRelativeToBookmark;
|
297
|
+
else if (strcmp(flag_str, "originmask") == 0)
|
298
|
+
return EvtSeekOriginMask;
|
299
|
+
else if (strcmp(flag_str, "strict") == 0)
|
300
|
+
return EvtSeekStrict;
|
301
|
+
else
|
302
|
+
rb_raise(rb_eArgError, "Unknown seek flag: %s", flag_str);
|
303
|
+
|
304
|
+
return 0;
|
305
|
+
}
|
306
|
+
|
307
|
+
/*
|
308
|
+
* This method specifies seek strategy.
|
309
|
+
*
|
310
|
+
* @param bookmark_or_flag [Bookmark|Query::Flag]
|
311
|
+
* @return [Boolean]
|
312
|
+
*/
|
313
|
+
static VALUE
|
314
|
+
rb_winevt_query_seek(VALUE self, VALUE bookmark_or_flag)
|
315
|
+
{
|
316
|
+
struct WinevtQuery* winevtQuery;
|
317
|
+
struct WinevtBookmark* winevtBookmark = NULL;
|
318
|
+
DWORD flag = 0;
|
319
|
+
|
320
|
+
switch (TYPE(bookmark_or_flag)) {
|
321
|
+
case T_SYMBOL:
|
322
|
+
flag = get_evt_seek_flag_from_cstr(RSTRING_PTR(rb_sym2str(bookmark_or_flag)));
|
323
|
+
break;
|
324
|
+
case T_STRING:
|
325
|
+
flag = get_evt_seek_flag_from_cstr(StringValueCStr(bookmark_or_flag));
|
326
|
+
break;
|
327
|
+
case T_FIXNUM:
|
328
|
+
flag = NUM2LONG(bookmark_or_flag);
|
329
|
+
break;
|
330
|
+
default:
|
331
|
+
if (!rb_obj_is_kind_of(bookmark_or_flag, rb_cBookmark))
|
332
|
+
rb_raise(rb_eArgError, "Expected a String or a Symbol or a Bookmark instance");
|
333
|
+
|
334
|
+
winevtBookmark = EventBookMark(bookmark_or_flag);
|
335
|
+
}
|
336
|
+
|
337
|
+
if (winevtBookmark) {
|
338
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
339
|
+
if (EvtSeek(winevtQuery->query,
|
340
|
+
winevtQuery->offset,
|
341
|
+
winevtBookmark->bookmark,
|
342
|
+
winevtQuery->timeout,
|
343
|
+
EvtSeekRelativeToBookmark))
|
344
|
+
return Qtrue;
|
345
|
+
} else {
|
346
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
347
|
+
if (EvtSeek(
|
348
|
+
winevtQuery->query, winevtQuery->offset, NULL, winevtQuery->timeout, flag)) {
|
349
|
+
return Qtrue;
|
350
|
+
}
|
351
|
+
}
|
352
|
+
|
353
|
+
return Qfalse;
|
354
|
+
}
|
355
|
+
|
356
|
+
static VALUE
|
357
|
+
rb_winevt_query_close_handle(VALUE self)
|
358
|
+
{
|
359
|
+
struct WinevtQuery* winevtQuery;
|
360
|
+
|
361
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
362
|
+
|
363
|
+
for (int i = 0; i < winevtQuery->count; i++) {
|
364
|
+
if (winevtQuery->hEvents[i] != NULL) {
|
365
|
+
EvtClose(winevtQuery->hEvents[i]);
|
366
|
+
winevtQuery->hEvents[i] = NULL;
|
367
|
+
}
|
368
|
+
}
|
369
|
+
|
370
|
+
return Qnil;
|
371
|
+
}
|
372
|
+
|
373
|
+
static VALUE
|
374
|
+
rb_winevt_query_each_yield(VALUE self)
|
375
|
+
{
|
376
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
377
|
+
|
378
|
+
struct WinevtQuery* winevtQuery;
|
379
|
+
|
380
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
381
|
+
|
382
|
+
for (int i = 0; i < winevtQuery->count; i++) {
|
383
|
+
rb_yield_values(3,
|
384
|
+
rb_winevt_query_render(self, winevtQuery->hEvents[i]),
|
385
|
+
rb_winevt_query_message(winevtQuery->hEvents[i], winevtQuery->localeInfo,
|
386
|
+
winevtQuery->remoteHandle),
|
387
|
+
rb_winevt_query_string_inserts(winevtQuery->hEvents[i]));
|
388
|
+
}
|
389
|
+
return Qnil;
|
390
|
+
}
|
391
|
+
|
392
|
+
/*
|
393
|
+
* Enumerate to obtain Windows EventLog contents.
|
394
|
+
*
|
395
|
+
* This method yields the following:
|
396
|
+
* (Stringified EventLog, Stringified detail message, Stringified
|
397
|
+
* insert values)
|
398
|
+
*
|
399
|
+
* @yield (String,String,String)
|
400
|
+
*
|
401
|
+
*/
|
402
|
+
static VALUE
|
403
|
+
rb_winevt_query_each(VALUE self)
|
404
|
+
{
|
405
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
406
|
+
|
407
|
+
while (rb_winevt_query_next(self)) {
|
408
|
+
rb_ensure(rb_winevt_query_each_yield, self, rb_winevt_query_close_handle, self);
|
409
|
+
}
|
410
|
+
|
411
|
+
return Qnil;
|
412
|
+
}
|
413
|
+
|
414
|
+
/*
|
415
|
+
* This method returns whether render as xml or not.
|
416
|
+
*
|
417
|
+
* @return [Boolean]
|
418
|
+
*/
|
419
|
+
static VALUE
|
420
|
+
rb_winevt_query_render_as_xml_p(VALUE self)
|
421
|
+
{
|
422
|
+
struct WinevtQuery* winevtQuery;
|
423
|
+
|
424
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
425
|
+
|
426
|
+
return winevtQuery->renderAsXML ? Qtrue : Qfalse;
|
427
|
+
}
|
428
|
+
|
429
|
+
/*
|
430
|
+
* This method specifies whether render as xml or not.
|
431
|
+
*
|
432
|
+
* @param rb_render_as_xml [Boolean]
|
433
|
+
*/
|
434
|
+
static VALUE
|
435
|
+
rb_winevt_query_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
|
436
|
+
{
|
437
|
+
struct WinevtQuery* winevtQuery;
|
438
|
+
|
439
|
+
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
440
|
+
|
441
|
+
winevtQuery->renderAsXML = RTEST(rb_render_as_xml);
|
442
|
+
|
443
|
+
return Qnil;
|
444
|
+
}
|
445
|
+
|
446
|
+
/*
|
447
|
+
* This method specifies whether preserving qualifiers key or not.
|
448
|
+
*
|
449
|
+
* @since 0.7.3
|
450
|
+
* @param rb_preserve_qualifiers [Boolean]
|
451
|
+
*/
|
452
|
+
static VALUE
|
453
|
+
rb_winevt_query_set_preserve_qualifiers(VALUE self, VALUE rb_preserve_qualifiers)
|
454
|
+
{
|
455
|
+
struct WinevtQuery* winevtQuery;
|
456
|
+
|
457
|
+
TypedData_Get_Struct(
|
458
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
459
|
+
|
460
|
+
winevtQuery->preserveQualifiers = RTEST(rb_preserve_qualifiers);
|
461
|
+
|
462
|
+
return Qnil;
|
463
|
+
}
|
464
|
+
|
465
|
+
/*
|
466
|
+
* This method returns whether preserving qualifiers or not.
|
467
|
+
*
|
468
|
+
* @since 0.7.3
|
469
|
+
* @return [Integer]
|
470
|
+
*/
|
471
|
+
static VALUE
|
472
|
+
rb_winevt_query_get_preserve_qualifiers_p(VALUE self)
|
473
|
+
{
|
474
|
+
struct WinevtQuery* winevtQuery;
|
475
|
+
|
476
|
+
TypedData_Get_Struct(
|
477
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
478
|
+
|
479
|
+
return winevtQuery->preserveQualifiers ? Qtrue : Qfalse;
|
480
|
+
}
|
481
|
+
|
482
|
+
/*
|
483
|
+
* This method specifies locale with [String].
|
484
|
+
*
|
485
|
+
* @since 0.8.0
|
486
|
+
* @param rb_locale_str [String]
|
487
|
+
*/
|
488
|
+
static VALUE
|
489
|
+
rb_winevt_query_set_locale(VALUE self, VALUE rb_locale_str)
|
490
|
+
{
|
491
|
+
struct WinevtQuery* winevtQuery;
|
492
|
+
LocaleInfo* locale_info = &default_locale;
|
493
|
+
|
494
|
+
TypedData_Get_Struct(
|
495
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
496
|
+
|
497
|
+
locale_info = get_locale_info_from_rb_str(rb_locale_str);
|
498
|
+
|
499
|
+
winevtQuery->localeInfo = locale_info;
|
500
|
+
|
501
|
+
return Qnil;
|
502
|
+
}
|
503
|
+
|
504
|
+
/*
|
505
|
+
* This method obtains specified locale with [String].
|
506
|
+
*
|
507
|
+
* @since 0.8.0
|
508
|
+
*/
|
509
|
+
static VALUE
|
510
|
+
rb_winevt_query_get_locale(VALUE self)
|
511
|
+
{
|
512
|
+
struct WinevtQuery* winevtQuery;
|
513
|
+
|
514
|
+
TypedData_Get_Struct(
|
515
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
516
|
+
|
517
|
+
if (winevtQuery->localeInfo->langCode) {
|
518
|
+
return rb_str_new2(winevtQuery->localeInfo->langCode);
|
519
|
+
} else {
|
520
|
+
return rb_str_new2(default_locale.langCode);
|
521
|
+
}
|
522
|
+
}
|
523
|
+
|
524
|
+
/*
|
525
|
+
* This method cancels channel query.
|
526
|
+
*
|
527
|
+
* @return [Boolean]
|
528
|
+
* @since 0.9.1
|
529
|
+
*/
|
530
|
+
static VALUE
|
531
|
+
rb_winevt_query_cancel(VALUE self)
|
532
|
+
{
|
533
|
+
struct WinevtQuery* winevtQuery;
|
534
|
+
BOOL result = FALSE;
|
535
|
+
|
536
|
+
TypedData_Get_Struct(
|
537
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
538
|
+
|
539
|
+
if (winevtQuery->query) {
|
540
|
+
result = EvtCancel(winevtQuery->query);
|
541
|
+
}
|
542
|
+
|
543
|
+
if (result) {
|
544
|
+
return Qtrue;
|
545
|
+
} else {
|
546
|
+
return Qfalse;
|
547
|
+
}
|
548
|
+
}
|
549
|
+
|
550
|
+
/*
|
551
|
+
* This method closes channel handles forcibly.
|
552
|
+
*
|
553
|
+
* @since 0.9.1
|
554
|
+
*/
|
555
|
+
static VALUE
|
556
|
+
rb_winevt_query_close(VALUE self)
|
557
|
+
{
|
558
|
+
struct WinevtQuery* winevtQuery;
|
559
|
+
|
560
|
+
TypedData_Get_Struct(
|
561
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
562
|
+
|
563
|
+
close_handles(winevtQuery);
|
564
|
+
|
565
|
+
return Qnil;
|
566
|
+
}
|
567
|
+
|
568
|
+
void
|
569
|
+
Init_winevt_query(VALUE rb_cEventLog)
|
570
|
+
{
|
571
|
+
rb_cQuery = rb_define_class_under(rb_cEventLog, "Query", rb_cObject);
|
572
|
+
rb_define_alloc_func(rb_cQuery, rb_winevt_query_alloc);
|
573
|
+
|
574
|
+
rb_cFlag = rb_define_module_under(rb_cQuery, "Flag");
|
575
|
+
|
576
|
+
/* clang-format off */
|
577
|
+
/*
|
578
|
+
* EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToFirst
|
579
|
+
* @since 0.6.0
|
580
|
+
* @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToFirst
|
581
|
+
*/
|
582
|
+
rb_define_const(rb_cFlag, "RelativeToFirst", LONG2NUM(EvtSeekRelativeToFirst));
|
583
|
+
/*
|
584
|
+
* EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToLast
|
585
|
+
* @since 0.6.0
|
586
|
+
* @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToLast
|
587
|
+
*/
|
588
|
+
rb_define_const(rb_cFlag, "RelativeToLast", LONG2NUM(EvtSeekRelativeToLast));
|
589
|
+
/*
|
590
|
+
* EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToCurrent
|
591
|
+
* @since 0.6.0
|
592
|
+
* @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToCurrent
|
593
|
+
*/
|
594
|
+
rb_define_const(rb_cFlag, "RelativeToCurrent", LONG2NUM(EvtSeekRelativeToCurrent));
|
595
|
+
/*
|
596
|
+
* EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToBookmark
|
597
|
+
* @since 0.6.0
|
598
|
+
* @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToBookmark
|
599
|
+
*/
|
600
|
+
rb_define_const(rb_cFlag, "RelativeToBookmark", LONG2NUM(EvtSeekRelativeToBookmark));
|
601
|
+
/*
|
602
|
+
* EVT_SEEK_FLAGS enumeration: EvtSeekOriginMask
|
603
|
+
* @since 0.6.0
|
604
|
+
* @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekOriginMask
|
605
|
+
*/
|
606
|
+
rb_define_const(rb_cFlag, "OriginMask", LONG2NUM(EvtSeekOriginMask));
|
607
|
+
/*
|
608
|
+
* EVT_SEEK_FLAGS enumeration: EvtSeekStrict
|
609
|
+
* @since 0.6.0
|
610
|
+
* @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekStrict
|
611
|
+
*/
|
612
|
+
rb_define_const(rb_cFlag, "Strict", LONG2NUM(EvtSeekStrict));
|
613
|
+
/* clang-format on */
|
614
|
+
|
615
|
+
rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, -1);
|
616
|
+
rb_define_method(rb_cQuery, "next", rb_winevt_query_next, 0);
|
617
|
+
rb_define_method(rb_cQuery, "seek", rb_winevt_query_seek, 1);
|
618
|
+
rb_define_method(rb_cQuery, "offset", rb_winevt_query_get_offset, 0);
|
619
|
+
rb_define_method(rb_cQuery, "offset=", rb_winevt_query_set_offset, 1);
|
620
|
+
rb_define_method(rb_cQuery, "timeout", rb_winevt_query_get_timeout, 0);
|
621
|
+
rb_define_method(rb_cQuery, "timeout=", rb_winevt_query_set_timeout, 1);
|
622
|
+
rb_define_method(rb_cQuery, "each", rb_winevt_query_each, 0);
|
623
|
+
rb_define_method(rb_cQuery, "render_as_xml?", rb_winevt_query_render_as_xml_p, 0);
|
624
|
+
rb_define_method(rb_cQuery, "render_as_xml=", rb_winevt_query_set_render_as_xml, 1);
|
625
|
+
/*
|
626
|
+
* @since 0.7.3
|
627
|
+
*/
|
628
|
+
rb_define_method(rb_cQuery, "preserve_qualifiers?", rb_winevt_query_get_preserve_qualifiers_p, 0);
|
629
|
+
/*
|
630
|
+
* @since 0.7.3
|
631
|
+
*/
|
632
|
+
rb_define_method(rb_cQuery, "preserve_qualifiers=", rb_winevt_query_set_preserve_qualifiers, 1);
|
633
|
+
/*
|
634
|
+
* @since 0.8.0
|
635
|
+
*/
|
636
|
+
rb_define_method(rb_cQuery, "locale", rb_winevt_query_get_locale, 0);
|
637
|
+
/*
|
638
|
+
* @since 0.8.0
|
639
|
+
*/
|
640
|
+
rb_define_method(rb_cQuery, "locale=", rb_winevt_query_set_locale, 1);
|
641
|
+
/*
|
642
|
+
* @since 0.9.1
|
643
|
+
*/
|
644
|
+
rb_define_method(rb_cQuery, "cancel", rb_winevt_query_cancel, 0);
|
645
|
+
/*
|
646
|
+
* @since 0.9.1
|
647
|
+
*/
|
648
|
+
rb_define_method(rb_cQuery, "close", rb_winevt_query_close, 0);
|
649
|
+
}
|