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.
@@ -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, options={})
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
- * @option options [Bookmark] bookmark Bookmark class instance.
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, "21", &rb_path, &rb_query, &rb_bookmark);
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(NULL, hSignalEvent, path, query, hBookmark, NULL, NULL, flags);
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
- raise_system_error(rb_eWinevtQueryError, status);
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
  }
@@ -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
- nullptr,
495
+ hRemote,
474
496
  values[0].StringVal,
475
497
  nullptr,
476
- MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT),
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 (EvtVarTypeNull != pRenderedValues[EvtSystemQualifiers].Type) {
576
- EventID = MAKELONG(pRenderedValues[EvtSystemEventID].UInt16Val,
577
- pRenderedValues[EvtSystemQualifiers].UInt16Val);
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"),
@@ -7,6 +7,7 @@ require "winevt/bookmark"
7
7
  require "winevt/query"
8
8
  require "winevt/subscribe"
9
9
  require "winevt/version"
10
+ require "winevt/session"
10
11
 
11
12
  module Winevt
12
13
  # Your code goes here...
@@ -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
@@ -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)
@@ -1,3 +1,3 @@
1
1
  module Winevt
2
- VERSION = "0.7.2"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -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.7.2"
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.7.2
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-02-28 00:00:00.000000000 Z
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.7.2
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.7.2
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