winevt_c 0.7.2 → 0.9.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/README.md +55 -0
- data/Rakefile +1 -1
- data/example/eventlog.rb +7 -1
- data/example/locale.rb +13 -0
- data/example/rate_limit.rb +1 -1
- data/example/tailing.rb +10 -2
- data/ext/winevt/winevt.c +7 -0
- data/ext/winevt/winevt_bookmark.c +2 -0
- data/ext/winevt/winevt_c.h +46 -8
- data/ext/winevt/winevt_channel.c +2 -0
- data/ext/winevt/winevt_locale.c +92 -0
- data/ext/winevt/winevt_locale_info.c +68 -0
- data/ext/winevt/winevt_query.c +138 -9
- data/ext/winevt/winevt_session.c +425 -0
- data/ext/winevt/winevt_subscribe.c +136 -10
- data/ext/winevt/winevt_utils.cpp +42 -8
- data/lib/winevt.rb +1 -0
- data/lib/winevt/session.rb +15 -0
- data/lib/winevt/subscribe.rb +5 -2
- data/lib/winevt/version.rb +1 -1
- data/winevt_c.gemspec +1 -1
- metadata +9 -4
@@ -57,6 +57,9 @@ subscribe_free(void* ptr)
|
|
57
57
|
}
|
58
58
|
}
|
59
59
|
|
60
|
+
if (winevtSubscribe->remoteHandle)
|
61
|
+
EvtClose(winevtSubscribe->remoteHandle);
|
62
|
+
|
60
63
|
xfree(ptr);
|
61
64
|
}
|
62
65
|
|
@@ -89,6 +92,8 @@ rb_winevt_subscribe_initialize(VALUE self)
|
|
89
92
|
winevtSubscribe->currentRate = 0;
|
90
93
|
winevtSubscribe->renderAsXML = TRUE;
|
91
94
|
winevtSubscribe->readExistingEvents = TRUE;
|
95
|
+
winevtSubscribe->preserveQualifiers = FALSE;
|
96
|
+
winevtSubscribe->localeInfo = &default_locale;
|
92
97
|
|
93
98
|
return Qnil;
|
94
99
|
}
|
@@ -130,23 +135,27 @@ rb_winevt_subscribe_read_existing_events_p(VALUE self)
|
|
130
135
|
/*
|
131
136
|
* Subscribe into a Windows EventLog channel.
|
132
137
|
*
|
133
|
-
* @overload subscribe(path, query,
|
138
|
+
* @overload subscribe(path, query, bookmark=nil, session=nil)
|
134
139
|
* @param path [String] Subscribe Channel
|
135
140
|
* @param query [String] Query string for channel
|
136
|
-
* @
|
141
|
+
* @param bookmark [Bookmark] bookmark Bookmark class instance.
|
142
|
+
* @param session [Session] Session information for remoting access.
|
137
143
|
* @return [Boolean]
|
138
144
|
*
|
139
145
|
*/
|
140
146
|
static VALUE
|
141
147
|
rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
|
142
148
|
{
|
143
|
-
VALUE rb_path, rb_query, rb_bookmark;
|
149
|
+
VALUE rb_path, rb_query, rb_bookmark, rb_session;
|
144
150
|
EVT_HANDLE hSubscription = NULL, hBookmark = NULL;
|
145
151
|
HANDLE hSignalEvent;
|
152
|
+
EVT_HANDLE hRemoteHandle = NULL;
|
146
153
|
DWORD len, flags = 0L;
|
154
|
+
DWORD err = ERROR_SUCCESS;
|
147
155
|
VALUE wpathBuf, wqueryBuf, wBookmarkBuf;
|
148
156
|
PWSTR path, query, bookmarkXml;
|
149
157
|
DWORD status = ERROR_SUCCESS;
|
158
|
+
struct WinevtSession* winevtSession;
|
150
159
|
struct WinevtSubscribe* winevtSubscribe;
|
151
160
|
|
152
161
|
hSignalEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
@@ -154,7 +163,7 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
|
|
154
163
|
TypedData_Get_Struct(
|
155
164
|
self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
156
165
|
|
157
|
-
rb_scan_args(argc, argv, "
|
166
|
+
rb_scan_args(argc, argv, "22", &rb_path, &rb_query, &rb_bookmark, &rb_session);
|
158
167
|
Check_Type(rb_path, T_STRING);
|
159
168
|
Check_Type(rb_query, T_STRING);
|
160
169
|
|
@@ -177,6 +186,19 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
|
|
177
186
|
raise_system_error(rb_eWinevtQueryError, status);
|
178
187
|
}
|
179
188
|
}
|
189
|
+
if (rb_obj_is_kind_of(rb_session, rb_cSession)) {
|
190
|
+
winevtSession = EventSession(rb_session);
|
191
|
+
hRemoteHandle = connect_to_remote(winevtSession->server,
|
192
|
+
winevtSession->domain,
|
193
|
+
winevtSession->username,
|
194
|
+
winevtSession->password,
|
195
|
+
winevtSession->flags);
|
196
|
+
|
197
|
+
err = GetLastError();
|
198
|
+
if (err != ERROR_SUCCESS) {
|
199
|
+
raise_system_error(rb_eRuntimeError, err);
|
200
|
+
}
|
201
|
+
}
|
180
202
|
|
181
203
|
// path : To wide char
|
182
204
|
len =
|
@@ -202,7 +224,7 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
|
|
202
224
|
}
|
203
225
|
|
204
226
|
hSubscription =
|
205
|
-
EvtSubscribe(
|
227
|
+
EvtSubscribe(hRemoteHandle, hSignalEvent, path, query, hBookmark, NULL, NULL, flags);
|
206
228
|
if (!hSubscription) {
|
207
229
|
if (hBookmark != NULL) {
|
208
230
|
EvtClose(hBookmark);
|
@@ -211,7 +233,11 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
|
|
211
233
|
CloseHandle(hSignalEvent);
|
212
234
|
}
|
213
235
|
status = GetLastError();
|
214
|
-
|
236
|
+
if (rb_obj_is_kind_of(rb_session, rb_cSession)) {
|
237
|
+
rb_raise(rb_eRemoteHandlerError, "Remoting subscription is not working. errCode: %ld\n", status);
|
238
|
+
} else {
|
239
|
+
raise_system_error(rb_eWinevtQueryError, status);
|
240
|
+
}
|
215
241
|
}
|
216
242
|
|
217
243
|
if (winevtSubscribe->subscription != NULL) {
|
@@ -224,6 +250,7 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
|
|
224
250
|
|
225
251
|
winevtSubscribe->signalEvent = hSignalEvent;
|
226
252
|
winevtSubscribe->subscription = hSubscription;
|
253
|
+
winevtSubscribe->remoteHandle = hRemoteHandle;
|
227
254
|
if (hBookmark) {
|
228
255
|
winevtSubscribe->bookmark = hBookmark;
|
229
256
|
} else {
|
@@ -339,17 +366,17 @@ rb_winevt_subscribe_render(VALUE self, EVT_HANDLE event)
|
|
339
366
|
if (winevtSubscribe->renderAsXML) {
|
340
367
|
return render_to_rb_str(event, EvtRenderEventXml);
|
341
368
|
} else {
|
342
|
-
return render_system_event(event);
|
369
|
+
return render_system_event(event, winevtSubscribe->preserveQualifiers);
|
343
370
|
}
|
344
371
|
}
|
345
372
|
|
346
373
|
static VALUE
|
347
|
-
rb_winevt_subscribe_message(EVT_HANDLE event)
|
374
|
+
rb_winevt_subscribe_message(EVT_HANDLE event, LocaleInfo* localeInfo, EVT_HANDLE hRemote)
|
348
375
|
{
|
349
376
|
WCHAR* wResult;
|
350
377
|
VALUE utf8str;
|
351
378
|
|
352
|
-
wResult = get_description(event);
|
379
|
+
wResult = get_description(event, localeInfo->langID, hRemote);
|
353
380
|
utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1);
|
354
381
|
free(wResult);
|
355
382
|
|
@@ -392,7 +419,8 @@ rb_winevt_subscribe_each_yield(VALUE self)
|
|
392
419
|
for (int i = 0; i < winevtSubscribe->count; i++) {
|
393
420
|
rb_yield_values(3,
|
394
421
|
rb_winevt_subscribe_render(self, winevtSubscribe->hEvents[i]),
|
395
|
-
rb_winevt_subscribe_message(winevtSubscribe->hEvents[i]
|
422
|
+
rb_winevt_subscribe_message(winevtSubscribe->hEvents[i], winevtSubscribe->localeInfo,
|
423
|
+
winevtSubscribe->remoteHandle),
|
396
424
|
rb_winevt_subscribe_string_inserts(winevtSubscribe->hEvents[i]));
|
397
425
|
}
|
398
426
|
|
@@ -517,6 +545,84 @@ rb_winevt_subscribe_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
|
|
517
545
|
return Qnil;
|
518
546
|
}
|
519
547
|
|
548
|
+
/*
|
549
|
+
* This method specifies whether preserving qualifiers key or not.
|
550
|
+
*
|
551
|
+
* @since 0.7.3
|
552
|
+
* @param rb_preserve_qualifiers [Boolean]
|
553
|
+
*/
|
554
|
+
static VALUE
|
555
|
+
rb_winevt_subscribe_set_preserve_qualifiers(VALUE self, VALUE rb_preserve_qualifiers)
|
556
|
+
{
|
557
|
+
struct WinevtSubscribe* winevtSubscribe;
|
558
|
+
|
559
|
+
TypedData_Get_Struct(
|
560
|
+
self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
561
|
+
|
562
|
+
winevtSubscribe->preserveQualifiers = RTEST(rb_preserve_qualifiers);
|
563
|
+
|
564
|
+
return Qnil;
|
565
|
+
}
|
566
|
+
|
567
|
+
/*
|
568
|
+
* This method returns whether preserving qualifiers or not.
|
569
|
+
*
|
570
|
+
* @since 0.7.3
|
571
|
+
* @return [Integer]
|
572
|
+
*/
|
573
|
+
static VALUE
|
574
|
+
rb_winevt_subscribe_get_preserve_qualifiers_p(VALUE self)
|
575
|
+
{
|
576
|
+
struct WinevtSubscribe* winevtSubscribe;
|
577
|
+
|
578
|
+
TypedData_Get_Struct(
|
579
|
+
self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
580
|
+
|
581
|
+
return winevtSubscribe->preserveQualifiers ? Qtrue : Qfalse;
|
582
|
+
}
|
583
|
+
|
584
|
+
/*
|
585
|
+
* This method specifies locale with [String].
|
586
|
+
*
|
587
|
+
* @since 0.8.0
|
588
|
+
* @param rb_locale_str [String]
|
589
|
+
*/
|
590
|
+
static VALUE
|
591
|
+
rb_winevt_subscribe_set_locale(VALUE self, VALUE rb_locale_str)
|
592
|
+
{
|
593
|
+
struct WinevtSubscribe* winevtSubscribe;
|
594
|
+
LocaleInfo* locale_info = &default_locale;
|
595
|
+
|
596
|
+
TypedData_Get_Struct(
|
597
|
+
self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
598
|
+
|
599
|
+
locale_info = get_locale_info_from_rb_str(rb_locale_str);
|
600
|
+
|
601
|
+
winevtSubscribe->localeInfo = locale_info;
|
602
|
+
|
603
|
+
return Qnil;
|
604
|
+
}
|
605
|
+
|
606
|
+
/*
|
607
|
+
* This method obtains specified locale with [String].
|
608
|
+
*
|
609
|
+
* @since 0.8.0
|
610
|
+
*/
|
611
|
+
static VALUE
|
612
|
+
rb_winevt_subscribe_get_locale(VALUE self)
|
613
|
+
{
|
614
|
+
struct WinevtSubscribe* winevtSubscribe;
|
615
|
+
|
616
|
+
TypedData_Get_Struct(
|
617
|
+
self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
618
|
+
|
619
|
+
if (winevtSubscribe->localeInfo->langCode) {
|
620
|
+
return rb_str_new2(winevtSubscribe->localeInfo->langCode);
|
621
|
+
} else {
|
622
|
+
return rb_str_new2(default_locale.langCode);
|
623
|
+
}
|
624
|
+
}
|
625
|
+
|
520
626
|
void
|
521
627
|
Init_winevt_subscribe(VALUE rb_cEventLog)
|
522
628
|
{
|
@@ -549,4 +655,24 @@ Init_winevt_subscribe(VALUE rb_cEventLog)
|
|
549
655
|
rb_cSubscribe, "render_as_xml?", rb_winevt_subscribe_render_as_xml_p, 0);
|
550
656
|
rb_define_method(
|
551
657
|
rb_cSubscribe, "render_as_xml=", rb_winevt_subscribe_set_render_as_xml, 1);
|
658
|
+
/*
|
659
|
+
* @since 0.7.3
|
660
|
+
*/
|
661
|
+
rb_define_method(
|
662
|
+
rb_cSubscribe, "preserve_qualifiers?", rb_winevt_subscribe_get_preserve_qualifiers_p, 0);
|
663
|
+
/*
|
664
|
+
* @since 0.7.3
|
665
|
+
*/
|
666
|
+
rb_define_method(
|
667
|
+
rb_cSubscribe, "preserve_qualifiers=", rb_winevt_subscribe_set_preserve_qualifiers, 1);
|
668
|
+
/*
|
669
|
+
* @since 0.8.0
|
670
|
+
*/
|
671
|
+
rb_define_method(
|
672
|
+
rb_cSubscribe, "locale", rb_winevt_subscribe_get_locale, 0);
|
673
|
+
/*
|
674
|
+
* @since 0.8.0
|
675
|
+
*/
|
676
|
+
rb_define_method(
|
677
|
+
rb_cSubscribe, "locale=", rb_winevt_subscribe_set_locale, 1);
|
552
678
|
}
|
data/ext/winevt/winevt_utils.cpp
CHANGED
@@ -76,6 +76,28 @@ render_to_rb_str(EVT_HANDLE handle, DWORD flags)
|
|
76
76
|
return result;
|
77
77
|
}
|
78
78
|
|
79
|
+
EVT_HANDLE
|
80
|
+
connect_to_remote(LPWSTR computerName, LPWSTR domain, LPWSTR username, LPWSTR password,
|
81
|
+
EVT_RPC_LOGIN_FLAGS flags)
|
82
|
+
{
|
83
|
+
EVT_HANDLE hRemote = NULL;
|
84
|
+
EVT_RPC_LOGIN Credentials;
|
85
|
+
|
86
|
+
RtlZeroMemory(&Credentials, sizeof(EVT_RPC_LOGIN));
|
87
|
+
|
88
|
+
Credentials.Server = computerName;
|
89
|
+
Credentials.Domain = domain;
|
90
|
+
Credentials.User = username;
|
91
|
+
Credentials.Password = password;
|
92
|
+
Credentials.Flags = flags;
|
93
|
+
|
94
|
+
hRemote = EvtOpenSession(EvtRpcLogin, &Credentials, 0, 0);
|
95
|
+
|
96
|
+
SecureZeroMemory(&Credentials, sizeof(EVT_RPC_LOGIN));
|
97
|
+
|
98
|
+
return hRemote;
|
99
|
+
}
|
100
|
+
|
79
101
|
static std::wstring
|
80
102
|
guid_to_wstr(const GUID& guid)
|
81
103
|
{
|
@@ -433,7 +455,7 @@ cleanup:
|
|
433
455
|
}
|
434
456
|
|
435
457
|
WCHAR*
|
436
|
-
get_description(EVT_HANDLE handle)
|
458
|
+
get_description(EVT_HANDLE handle, LANGID langID, EVT_HANDLE hRemote)
|
437
459
|
{
|
438
460
|
#define BUFSIZE 4096
|
439
461
|
std::vector<WCHAR> buffer(BUFSIZE);
|
@@ -470,10 +492,10 @@ get_description(EVT_HANDLE handle)
|
|
470
492
|
|
471
493
|
// Open publisher metadata
|
472
494
|
hMetadata = EvtOpenPublisherMetadata(
|
473
|
-
|
495
|
+
hRemote,
|
474
496
|
values[0].StringVal,
|
475
497
|
nullptr,
|
476
|
-
MAKELCID(
|
498
|
+
MAKELCID(langID, SORT_DEFAULT),
|
477
499
|
0);
|
478
500
|
if (hMetadata == nullptr) {
|
479
501
|
// When winevt_c cannot open metadata, then give up to obtain
|
@@ -497,7 +519,7 @@ cleanup:
|
|
497
519
|
}
|
498
520
|
|
499
521
|
VALUE
|
500
|
-
render_system_event(EVT_HANDLE hEvent)
|
522
|
+
render_system_event(EVT_HANDLE hEvent, BOOL preserve_qualifiers)
|
501
523
|
{
|
502
524
|
DWORD status = ERROR_SUCCESS;
|
503
525
|
EVT_HANDLE hContext = NULL;
|
@@ -572,11 +594,23 @@ render_system_event(EVT_HANDLE hEvent)
|
|
572
594
|
}
|
573
595
|
|
574
596
|
EventID = pRenderedValues[EvtSystemEventID].UInt16Val;
|
575
|
-
if (
|
576
|
-
|
577
|
-
|
597
|
+
if (preserve_qualifiers) {
|
598
|
+
if (EvtVarTypeNull != pRenderedValues[EvtSystemQualifiers].Type) {
|
599
|
+
rb_hash_aset(hash, rb_str_new2("Qualifiers"),
|
600
|
+
INT2NUM(pRenderedValues[EvtSystemQualifiers].UInt16Val));
|
601
|
+
} else {
|
602
|
+
rb_hash_aset(hash, rb_str_new2("Qualifiers"), rb_str_new2(""));
|
603
|
+
}
|
604
|
+
|
605
|
+
rb_hash_aset(hash, rb_str_new2("EventID"), INT2NUM(EventID));
|
606
|
+
} else {
|
607
|
+
if (EvtVarTypeNull != pRenderedValues[EvtSystemQualifiers].Type) {
|
608
|
+
EventID = MAKELONG(pRenderedValues[EvtSystemEventID].UInt16Val,
|
609
|
+
pRenderedValues[EvtSystemQualifiers].UInt16Val);
|
610
|
+
}
|
611
|
+
|
612
|
+
rb_hash_aset(hash, rb_str_new2("EventID"), ULONG2NUM(EventID));
|
578
613
|
}
|
579
|
-
rb_hash_aset(hash, rb_str_new2("EventID"), LONG2NUM(EventID));
|
580
614
|
|
581
615
|
rb_hash_aset(hash,
|
582
616
|
rb_str_new2("Version"),
|
data/lib/winevt.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Winevt
|
2
|
+
class EventLog
|
3
|
+
class Session
|
4
|
+
alias_method :initialize_raw, :initialize
|
5
|
+
|
6
|
+
def initialize(server, domain = nil, username = nil, password = nil)
|
7
|
+
initialize_raw
|
8
|
+
self.server = server
|
9
|
+
self.domain = domain if domain.is_a?(String)
|
10
|
+
self.username = username if username.is_a?(String)
|
11
|
+
self.password = password if password.is_a?(String)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/winevt/subscribe.rb
CHANGED
@@ -3,8 +3,11 @@ module Winevt
|
|
3
3
|
class Subscribe
|
4
4
|
alias_method :subscribe_raw, :subscribe
|
5
5
|
|
6
|
-
def subscribe(path, query, bookmark = nil)
|
7
|
-
if bookmark.is_a?(Winevt::EventLog::Bookmark)
|
6
|
+
def subscribe(path, query, bookmark = nil, session = nil)
|
7
|
+
if bookmark.is_a?(Winevt::EventLog::Bookmark) &&
|
8
|
+
session.is_a?(Winevt::EventLog::Session)
|
9
|
+
subscribe_raw(path, query, bookmark.render, session)
|
10
|
+
elsif bookmark.is_a?(Winevt::EventLog::Bookmark)
|
8
11
|
subscribe_raw(path, query, bookmark.render)
|
9
12
|
else
|
10
13
|
subscribe_raw(path, query)
|
data/lib/winevt/version.rb
CHANGED
data/winevt_c.gemspec
CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency "bundler", [">= 1.16", "< 3"]
|
29
29
|
spec.add_development_dependency "rake", "~> 12.0"
|
30
30
|
spec.add_development_dependency "rake-compiler", "~> 1.0"
|
31
|
-
spec.add_development_dependency "rake-compiler-dock", "~> 0.
|
31
|
+
spec.add_development_dependency "rake-compiler-dock", "~> 1.0.0"
|
32
32
|
spec.add_development_dependency "test-unit", "~> 3.2"
|
33
33
|
spec.add_development_dependency "yard", "~> 0.9"
|
34
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: winevt_c
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hiroshi Hatake
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -64,14 +64,14 @@ dependencies:
|
|
64
64
|
requirements:
|
65
65
|
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: 0.
|
67
|
+
version: 1.0.0
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: 0.
|
74
|
+
version: 1.0.0
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: test-unit
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- example/bookmark.rb
|
122
122
|
- example/enumerate_channels.rb
|
123
123
|
- example/eventlog.rb
|
124
|
+
- example/locale.rb
|
124
125
|
- example/rate_limit.rb
|
125
126
|
- example/tailing.rb
|
126
127
|
- ext/winevt/extconf.rb
|
@@ -128,12 +129,16 @@ files:
|
|
128
129
|
- ext/winevt/winevt_bookmark.c
|
129
130
|
- ext/winevt/winevt_c.h
|
130
131
|
- ext/winevt/winevt_channel.c
|
132
|
+
- ext/winevt/winevt_locale.c
|
133
|
+
- ext/winevt/winevt_locale_info.c
|
131
134
|
- ext/winevt/winevt_query.c
|
135
|
+
- ext/winevt/winevt_session.c
|
132
136
|
- ext/winevt/winevt_subscribe.c
|
133
137
|
- ext/winevt/winevt_utils.cpp
|
134
138
|
- lib/winevt.rb
|
135
139
|
- lib/winevt/bookmark.rb
|
136
140
|
- lib/winevt/query.rb
|
141
|
+
- lib/winevt/session.rb
|
137
142
|
- lib/winevt/subscribe.rb
|
138
143
|
- lib/winevt/version.rb
|
139
144
|
- winevt_c.gemspec
|