winevt_c 0.7.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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