winevt_c 0.6.0 → 0.6.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12f9385269dcef7feb299a038947855285d7ffb76d8d331941dfa2d30f56fdb4
4
- data.tar.gz: f122b6172ae73587a3a518d79d25a7a64daa735a552fb998cfd5f9e2a5fddc07
3
+ metadata.gz: b390dc340de45facd91c7de698c1d72f7f706e961f6beb776a748499886fa4c2
4
+ data.tar.gz: cb6bb22241cb81551cbb84363e7c9bddb205f38fb6aa138da2c6c4489667044c
5
5
  SHA512:
6
- metadata.gz: 92d91fafb48fe5a4cc63ad82a9eca050cac7e2db38538347f6a9c247b5218604360a155233d1f37c38ce9967ca6af46f150fedb0d77c261e201fb99a675c0996
7
- data.tar.gz: 5fcc3b81d00788d63380692942fe29822fe6a53d058463ce7848409310abb242a187dfb24414c5cdfc17943d6b57f027a9e1ddbeb2ae03c7eee2594215080eb1
6
+ metadata.gz: b8e2666c0d51dcf9bfc114c1bd73b1f075a1702999d44e8dd318878d837b762a568aceffffadfc89f0ce33010629fb677f0edd040a312d32a5f35a20c6f3f0cc
7
+ data.tar.gz: 6adec333c1e0998a712b149f470091ed24f441806b5454a05e80d937bca63de7346b806ddd1904835428344158e81108b12a1cc2aa628a595299ed243ce83abc
data/README.md CHANGED
@@ -24,6 +24,10 @@ Or install it yourself as:
24
24
 
25
25
  $ ridk exec gem install winevt_c
26
26
 
27
+ ## Fat gems building
28
+
29
+ * Docker is needed to build fat gem due to rake-compiler-dock uses docker container.
30
+
27
31
  ## Usage
28
32
 
29
33
  Usage examples are found in [example directory](example).
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ desc 'Build gems for Windows per rake-compiler-dock'
27
27
  task 'gem:native' do
28
28
  # See RUBY_CC_VERSION in https://github.com/rake-compiler/rake-compiler-dock/blob/master/Dockerfile.mri
29
29
  RakeCompilerDock.sh <<-EOS
30
- bundle --local
30
+ gem install bundler --no-doc && bundle --local
31
31
  bundle exec rake cross native gem RUBY_CC_VERSION=2.4.0:2.5.0:2.6.0
32
32
  EOS
33
33
  end
@@ -1,5 +1,24 @@
1
1
  #include <winevt_c.h>
2
2
 
3
+ /* clang-format off */
4
+ /*
5
+ * Document-class: Winevt::EventLog::Bookmark
6
+ *
7
+ * Bookmark for querying/subscribing Windows EventLog progress.
8
+ *
9
+ * @example
10
+ * require 'winevt'
11
+ *
12
+ * @query = Winevt::EventLog::Query.new("Application", "*[System[(Level <= 3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]")
13
+ * @bookmark = Winevt::EventLog::Bookmark.new
14
+ * @query.each do |xml|
15
+ * @bookmark.update(@query)
16
+ * end
17
+ *
18
+ * puts @bookmark.render
19
+ */
20
+ /* clang-format pn */
21
+
3
22
  static void bookmark_free(void* ptr);
4
23
 
5
24
  static const rb_data_type_t rb_winevt_bookmark_type = { "winevt/bookmark",
@@ -32,6 +51,14 @@ rb_winevt_bookmark_alloc(VALUE klass)
32
51
  return obj;
33
52
  }
34
53
 
54
+ /*
55
+ * Initalize Bookmark class. Receive XML string or nil.
56
+ *
57
+ * @overload initailize(options={})
58
+ * @option options [String] XML rendered Bookmark string.
59
+ * @return [Bookmark]
60
+ *
61
+ */
35
62
  static VALUE
36
63
  rb_winevt_bookmark_initialize(int argc, VALUE* argv, VALUE self)
37
64
  {
@@ -68,6 +95,12 @@ rb_winevt_bookmark_initialize(int argc, VALUE* argv, VALUE self)
68
95
  return Qnil;
69
96
  }
70
97
 
98
+ /*
99
+ * This method updates bookmark and returns Bookmark instance.
100
+ *
101
+ * @param event [Query]
102
+ * @return [Bookmark]
103
+ */
71
104
  static VALUE
72
105
  rb_winevt_bookmark_update(VALUE self, VALUE event)
73
106
  {
@@ -86,6 +119,11 @@ rb_winevt_bookmark_update(VALUE self, VALUE event)
86
119
  return Qtrue;
87
120
  }
88
121
 
122
+ /*
123
+ * This method renders bookmark class content.
124
+ *
125
+ * @return [String]
126
+ */
89
127
  static VALUE
90
128
  rb_winevt_bookmark_render(VALUE self)
91
129
  {
@@ -27,6 +27,7 @@ extern "C" {
27
27
  #endif /* __cplusplus */
28
28
 
29
29
  VALUE wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen);
30
+ void raise_system_error(VALUE error, DWORD errorCode);
30
31
  VALUE render_to_rb_str(EVT_HANDLE handle, DWORD flags);
31
32
  WCHAR* get_description(EVT_HANDLE handle);
32
33
  VALUE get_values(EVT_HANDLE handle);
@@ -1,5 +1,20 @@
1
1
  #include <winevt_c.h>
2
2
 
3
+ /*
4
+ * Document-class: Winevt::EventLog::Channel
5
+ *
6
+ * Retrieve Windows EventLog channel name.
7
+ *
8
+ * @example
9
+ * require 'winevt'
10
+ * channels = []
11
+ * @channel = Winevt::EventLog::Channel.new
12
+ * @channel.each do |channel|
13
+ * channels << channel
14
+ * end
15
+ * print channels
16
+ */
17
+
3
18
  static void channel_free(void* ptr);
4
19
 
5
20
  static const rb_data_type_t rb_winevt_channel_type = { "winevt/channel",
@@ -32,12 +47,24 @@ rb_winevt_channel_alloc(VALUE klass)
32
47
  return obj;
33
48
  }
34
49
 
50
+ /*
51
+ * Initalize Channel class.
52
+ *
53
+ * @return [Channel]
54
+ *
55
+ */
35
56
  static VALUE
36
57
  rb_winevt_channel_initialize(VALUE klass)
37
58
  {
38
59
  return Qnil;
39
60
  }
40
61
 
62
+ /*
63
+ * Enumerate Windows EventLog channels
64
+ *
65
+ * @yield (String)
66
+ *
67
+ */
41
68
  static VALUE
42
69
  rb_winevt_channel_each(VALUE self)
43
70
  {
@@ -1,5 +1,23 @@
1
1
  #include <winevt_c.h>
2
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
+
3
21
  static void query_free(void* ptr);
4
22
 
5
23
  static const rb_data_type_t rb_winevt_query_type = { "winevt/query",
@@ -36,6 +54,14 @@ rb_winevt_query_alloc(VALUE klass)
36
54
  return obj;
37
55
  }
38
56
 
57
+ /*
58
+ * Initalize Query class.
59
+ *
60
+ * @param channel [String] Querying EventLog channel.
61
+ * @param xpath [String] Querying XPath.
62
+ * @return [Query]
63
+ *
64
+ */
39
65
  static VALUE
40
66
  rb_winevt_query_initialize(VALUE self, VALUE channel, VALUE xpath)
41
67
  {
@@ -75,8 +101,13 @@ rb_winevt_query_initialize(VALUE self, VALUE channel, VALUE xpath)
75
101
  return Qnil;
76
102
  }
77
103
 
104
+ /*
105
+ * This method returns querying event offset.
106
+ *
107
+ * @return [Integer]
108
+ */
78
109
  static VALUE
79
- rb_winevt_query_get_offset(VALUE self, VALUE offset)
110
+ rb_winevt_query_get_offset(VALUE self)
80
111
  {
81
112
  struct WinevtQuery* winevtQuery;
82
113
 
@@ -85,6 +116,11 @@ rb_winevt_query_get_offset(VALUE self, VALUE offset)
85
116
  return LONG2NUM(winevtQuery->offset);
86
117
  }
87
118
 
119
+ /*
120
+ * This method specifies querying event offset.
121
+ *
122
+ * @param offset [Integer] offset value
123
+ */
88
124
  static VALUE
89
125
  rb_winevt_query_set_offset(VALUE self, VALUE offset)
90
126
  {
@@ -97,8 +133,13 @@ rb_winevt_query_set_offset(VALUE self, VALUE offset)
97
133
  return Qnil;
98
134
  }
99
135
 
136
+ /*
137
+ * This method returns timeout value.
138
+ *
139
+ * @return [Integer]
140
+ */
100
141
  static VALUE
101
- rb_winevt_query_get_timeout(VALUE self, VALUE timeout)
142
+ rb_winevt_query_get_timeout(VALUE self)
102
143
  {
103
144
  struct WinevtQuery* winevtQuery;
104
145
 
@@ -107,6 +148,11 @@ rb_winevt_query_get_timeout(VALUE self, VALUE timeout)
107
148
  return LONG2NUM(winevtQuery->timeout);
108
149
  }
109
150
 
151
+ /*
152
+ * This method specifies timeout value.
153
+ *
154
+ * @param timeout [Integer] timeout value
155
+ */
110
156
  static VALUE
111
157
  rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
112
158
  {
@@ -119,6 +165,14 @@ rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
119
165
  return Qnil;
120
166
  }
121
167
 
168
+ /*
169
+ * Handle the next values. Since v0.6.0, this method is used for
170
+ * testing only. Please use #each instead.
171
+ *
172
+ * @return [Boolean]
173
+ *
174
+ * @see each
175
+ */
122
176
  static VALUE
123
177
  rb_winevt_query_next(VALUE self)
124
178
  {
@@ -138,7 +192,7 @@ rb_winevt_query_next(VALUE self)
138
192
 
139
193
  if (status == ERROR_SUCCESS) {
140
194
  winevtQuery->count = count;
141
- for (int i = 0; i < count; i++){
195
+ for (int i = 0; i < count; i++) {
142
196
  winevtQuery->hEvents[i] = hEvents[i];
143
197
  }
144
198
 
@@ -202,6 +256,12 @@ get_evt_seek_flag_from_cstr(char* flag_str)
202
256
  return 0;
203
257
  }
204
258
 
259
+ /*
260
+ * This method specifies seek strategy.
261
+ *
262
+ * @param bookmark_or_flag [Bookmark|Query::Flag]
263
+ * @return [Boolean]
264
+ */
205
265
  static VALUE
206
266
  rb_winevt_query_seek(VALUE self, VALUE bookmark_or_flag)
207
267
  {
@@ -252,7 +312,7 @@ rb_winevt_query_close_handle(VALUE self)
252
312
 
253
313
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
254
314
 
255
- for (int i = 0; i < winevtQuery->count; i++){
315
+ for (int i = 0; i < winevtQuery->count; i++) {
256
316
  if (winevtQuery->hEvents[i] != NULL) {
257
317
  EvtClose(winevtQuery->hEvents[i]);
258
318
  winevtQuery->hEvents[i] = NULL;
@@ -280,6 +340,16 @@ rb_winevt_query_each_yield(VALUE self)
280
340
  return Qnil;
281
341
  }
282
342
 
343
+ /*
344
+ * Enumerate to obtain Windows EventLog contents.
345
+ *
346
+ * This method yields the following:
347
+ * (Stringified EventLog, Stringified detail message, Stringified
348
+ * insert values)
349
+ *
350
+ * @yield (String,String,String)
351
+ *
352
+ */
283
353
  static VALUE
284
354
  rb_winevt_query_each(VALUE self)
285
355
  {
@@ -292,6 +362,11 @@ rb_winevt_query_each(VALUE self)
292
362
  return Qnil;
293
363
  }
294
364
 
365
+ /*
366
+ * This method returns whether render as xml or not.
367
+ *
368
+ * @return [Boolean]
369
+ */
295
370
  static VALUE
296
371
  rb_winevt_query_render_as_xml_p(VALUE self)
297
372
  {
@@ -302,6 +377,11 @@ rb_winevt_query_render_as_xml_p(VALUE self)
302
377
  return winevtQuery->renderAsXML ? Qtrue : Qfalse;
303
378
  }
304
379
 
380
+ /*
381
+ * This method specifies whether render as xml or not.
382
+ *
383
+ * @param rb_render_as_xml [Boolean]
384
+ */
305
385
  static VALUE
306
386
  rb_winevt_query_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
307
387
  {
@@ -322,12 +402,44 @@ Init_winevt_query(VALUE rb_cEventLog)
322
402
 
323
403
  rb_cFlag = rb_define_module_under(rb_cQuery, "Flag");
324
404
 
405
+ /* clang-format off */
406
+ /*
407
+ * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToFirst
408
+ * @since 0.6.0
409
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToFirst
410
+ */
325
411
  rb_define_const(rb_cFlag, "RelativeToFirst", LONG2NUM(EvtSeekRelativeToFirst));
412
+ /*
413
+ * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToLast
414
+ * @since 0.6.0
415
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToLast
416
+ */
326
417
  rb_define_const(rb_cFlag, "RelativeToLast", LONG2NUM(EvtSeekRelativeToLast));
418
+ /*
419
+ * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToCurrent
420
+ * @since 0.6.0
421
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToCurrent
422
+ */
327
423
  rb_define_const(rb_cFlag, "RelativeToCurrent", LONG2NUM(EvtSeekRelativeToCurrent));
424
+ /*
425
+ * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToBookmark
426
+ * @since 0.6.0
427
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToBookmark
428
+ */
328
429
  rb_define_const(rb_cFlag, "RelativeToBookmark", LONG2NUM(EvtSeekRelativeToBookmark));
430
+ /*
431
+ * EVT_SEEK_FLAGS enumeration: EvtSeekOriginMask
432
+ * @since 0.6.0
433
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekOriginMask
434
+ */
329
435
  rb_define_const(rb_cFlag, "OriginMask", LONG2NUM(EvtSeekOriginMask));
436
+ /*
437
+ * EVT_SEEK_FLAGS enumeration: EvtSeekStrict
438
+ * @since 0.6.0
439
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekStrict
440
+ */
330
441
  rb_define_const(rb_cFlag, "Strict", LONG2NUM(EvtSeekStrict));
442
+ /* clang-format on */
331
443
 
332
444
  rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, 2);
333
445
  rb_define_method(rb_cQuery, "next", rb_winevt_query_next, 0);
@@ -1,5 +1,31 @@
1
1
  #include <winevt_c.h>
2
2
 
3
+ /* clang-format off */
4
+ /*
5
+ * Document-class: Winevt::EventLog::Subscribe
6
+ *
7
+ * Subscribe Windows EventLog channel.
8
+ *
9
+ * @example
10
+ * require 'winevt'
11
+ *
12
+ * @subscribe = Winevt::EventLog::Subscribe.new
13
+ * @subscribe.tail = true
14
+ * @subscribe.rate_limit = 80
15
+ * @subscribe.subscribe(
16
+ * "Application", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]"
17
+ * )
18
+ * while true do
19
+ * @subscribe.each do |eventlog, message, string_inserts|
20
+ * puts ({eventlog: eventlog, data: message})
21
+ * end
22
+ * sleep(0.1)
23
+ * end
24
+ *
25
+ * @see https://docs.microsoft.com/en-us/windows/win32/api/winevt/nf-winevt-evtsubscribe
26
+ */
27
+ /* clang-format on */
28
+
3
29
  static void subscribe_free(void* ptr);
4
30
 
5
31
  static const rb_data_type_t rb_winevt_subscribe_type = { "winevt/subscribe",
@@ -44,6 +70,12 @@ rb_winevt_subscribe_alloc(VALUE klass)
44
70
  return obj;
45
71
  }
46
72
 
73
+ /*
74
+ * Initalize Subscribe class.
75
+ *
76
+ * @return [Subscribe]
77
+ *
78
+ */
47
79
  static VALUE
48
80
  rb_winevt_subscribe_initialize(VALUE self)
49
81
  {
@@ -60,6 +92,11 @@ rb_winevt_subscribe_initialize(VALUE self)
60
92
  return Qnil;
61
93
  }
62
94
 
95
+ /*
96
+ * This method specifies whether tailing or not.
97
+ *
98
+ * @param rb_tailing_p [Boolean]
99
+ */
63
100
  static VALUE
64
101
  rb_winevt_subscribe_set_tail(VALUE self, VALUE rb_tailing_p)
65
102
  {
@@ -73,8 +110,13 @@ rb_winevt_subscribe_set_tail(VALUE self, VALUE rb_tailing_p)
73
110
  return Qnil;
74
111
  }
75
112
 
113
+ /*
114
+ * This method returns whether tailing or not.
115
+ *
116
+ * @return [Boolean]
117
+ */
76
118
  static VALUE
77
- rb_winevt_subscribe_tail_p(VALUE self, VALUE rb_flag)
119
+ rb_winevt_subscribe_tail_p(VALUE self)
78
120
  {
79
121
  struct WinevtSubscribe* winevtSubscribe;
80
122
 
@@ -84,6 +126,16 @@ rb_winevt_subscribe_tail_p(VALUE self, VALUE rb_flag)
84
126
  return winevtSubscribe->tailing ? Qtrue : Qfalse;
85
127
  }
86
128
 
129
+ /*
130
+ * Subscribe into a Windows EventLog channel.
131
+ *
132
+ * @overload subscribe(path, query, options={})
133
+ * @param path [String] Subscribe Channel
134
+ * @param query [String] Query string for channel
135
+ * @option options [Bookmark] bookmark Bookmark class instance.
136
+ * @return [Boolean]
137
+ *
138
+ */
87
139
  static VALUE
88
140
  rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
89
141
  {
@@ -91,8 +143,8 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
91
143
  EVT_HANDLE hSubscription = NULL, hBookmark = NULL;
92
144
  HANDLE hSignalEvent;
93
145
  DWORD len, flags = 0L;
94
- VALUE wpathBuf, wqueryBuf;
95
- PWSTR path, query;
146
+ VALUE wpathBuf, wqueryBuf, wBookmarkBuf;
147
+ PWSTR path, query, bookmarkXml;
96
148
  DWORD status = ERROR_SUCCESS;
97
149
  struct WinevtSubscribe* winevtSubscribe;
98
150
 
@@ -105,8 +157,24 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
105
157
  Check_Type(rb_path, T_STRING);
106
158
  Check_Type(rb_query, T_STRING);
107
159
 
108
- if (rb_obj_is_kind_of(rb_bookmark, rb_cBookmark)) {
109
- hBookmark = EventBookMark(rb_bookmark)->bookmark;
160
+ if (rb_obj_is_kind_of(rb_bookmark, rb_cString)) {
161
+ // bookmarkXml : To wide char
162
+ len = MultiByteToWideChar(
163
+ CP_UTF8, 0, RSTRING_PTR(rb_bookmark), RSTRING_LEN(rb_bookmark), NULL, 0);
164
+ bookmarkXml = ALLOCV_N(WCHAR, wBookmarkBuf, len + 1);
165
+ MultiByteToWideChar(CP_UTF8,
166
+ 0,
167
+ RSTRING_PTR(rb_bookmark),
168
+ RSTRING_LEN(rb_bookmark),
169
+ bookmarkXml,
170
+ len);
171
+ bookmarkXml[len] = L'\0';
172
+ hBookmark = EvtCreateBookmark(bookmarkXml);
173
+ ALLOCV_END(wBookmarkBuf);
174
+ if (hBookmark == NULL) {
175
+ status = GetLastError();
176
+ raise_system_error(rb_eWinevtQueryError, status);
177
+ }
110
178
  }
111
179
 
112
180
  // path : To wide char
@@ -134,6 +202,10 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
134
202
 
135
203
  hSubscription =
136
204
  EvtSubscribe(NULL, hSignalEvent, path, query, hBookmark, NULL, NULL, flags);
205
+ if (!hSubscription) {
206
+ status = GetLastError();
207
+ raise_system_error(rb_eWinevtQueryError, status);
208
+ }
137
209
 
138
210
  ALLOCV_END(wpathBuf);
139
211
  ALLOCV_END(wqueryBuf);
@@ -144,18 +216,17 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
144
216
  winevtSubscribe->bookmark = hBookmark;
145
217
  } else {
146
218
  winevtSubscribe->bookmark = EvtCreateBookmark(NULL);
219
+ if (winevtSubscribe->bookmark == NULL) {
220
+ status = GetLastError();
221
+ raise_system_error(rb_eWinevtQueryError, status);
222
+ }
147
223
  }
148
224
 
149
- status = GetLastError();
150
-
151
- if (status == ERROR_SUCCESS)
152
- return Qtrue;
153
-
154
- return Qfalse;
225
+ return Qtrue;
155
226
  }
156
227
 
157
228
  BOOL
158
- is_rate_limit_exceeded(struct WinevtSubscribe *winevtSubscribe)
229
+ is_rate_limit_exceeded(struct WinevtSubscribe* winevtSubscribe)
159
230
  {
160
231
  time_t now;
161
232
 
@@ -176,7 +247,7 @@ is_rate_limit_exceeded(struct WinevtSubscribe *winevtSubscribe)
176
247
  }
177
248
 
178
249
  void
179
- update_to_reflect_rate_limit_state(struct WinevtSubscribe *winevtSubscribe, ULONG count)
250
+ update_to_reflect_rate_limit_state(struct WinevtSubscribe* winevtSubscribe, ULONG count)
180
251
  {
181
252
  time_t lastTime = 0;
182
253
 
@@ -188,6 +259,15 @@ update_to_reflect_rate_limit_state(struct WinevtSubscribe *winevtSubscribe, ULON
188
259
  winevtSubscribe->currentRate += count;
189
260
  }
190
261
 
262
+ /*
263
+ * Handle the next values. Since v0.6.0, this method is used for
264
+ * testing only. Please use #each instead.
265
+ *
266
+ * @return [Boolean]
267
+ *
268
+ * @see each
269
+ */
270
+
191
271
  static VALUE
192
272
  rb_winevt_subscribe_next(VALUE self)
193
273
  {
@@ -203,8 +283,12 @@ rb_winevt_subscribe_next(VALUE self)
203
283
  return Qfalse;
204
284
  }
205
285
 
206
- if (!EvtNext(winevtSubscribe->subscription, SUBSCRIBE_ARRAY_SIZE,
207
- hEvents, INFINITE, 0, &count)) {
286
+ if (!EvtNext(winevtSubscribe->subscription,
287
+ SUBSCRIBE_ARRAY_SIZE,
288
+ hEvents,
289
+ INFINITE,
290
+ 0,
291
+ &count)) {
208
292
  status = GetLastError();
209
293
  if (ERROR_NO_MORE_ITEMS != status) {
210
294
  return Qfalse;
@@ -297,6 +381,16 @@ rb_winevt_subscribe_each_yield(VALUE self)
297
381
  return Qnil;
298
382
  }
299
383
 
384
+ /*
385
+ * Enumerate to obtain Windows EventLog contents.
386
+ *
387
+ * This method yields the following:
388
+ * (Stringified EventLog, Stringified detail message, Stringified
389
+ * insert values)
390
+ *
391
+ * @yield (String,String,String)
392
+ *
393
+ */
300
394
  static VALUE
301
395
  rb_winevt_subscribe_each(VALUE self)
302
396
  {
@@ -310,6 +404,11 @@ rb_winevt_subscribe_each(VALUE self)
310
404
  return Qnil;
311
405
  }
312
406
 
407
+ /*
408
+ * This method renders bookmark content which is related to Subscribe class instance.
409
+ *
410
+ * @return [String]
411
+ */
313
412
  static VALUE
314
413
  rb_winevt_subscribe_get_bookmark(VALUE self)
315
414
  {
@@ -321,6 +420,12 @@ rb_winevt_subscribe_get_bookmark(VALUE self)
321
420
  return render_to_rb_str(winevtSubscribe->bookmark, EvtRenderBookmark);
322
421
  }
323
422
 
423
+ /*
424
+ * This method returns rate limit value.
425
+ *
426
+ * @since 0.6.0
427
+ * @return [Integer]
428
+ */
324
429
  static VALUE
325
430
  rb_winevt_subscribe_get_rate_limit(VALUE self)
326
431
  {
@@ -332,6 +437,12 @@ rb_winevt_subscribe_get_rate_limit(VALUE self)
332
437
  return INT2NUM(winevtSubscribe->rateLimit);
333
438
  }
334
439
 
440
+ /*
441
+ * This method specifies rate limit value.
442
+ *
443
+ * @since 0.6.0
444
+ * @param rb_rate_limit [Integer] rate_limit value
445
+ */
335
446
  static VALUE
336
447
  rb_winevt_subscribe_set_rate_limit(VALUE self, VALUE rb_rate_limit)
337
448
  {
@@ -343,10 +454,8 @@ rb_winevt_subscribe_set_rate_limit(VALUE self, VALUE rb_rate_limit)
343
454
 
344
455
  rateLimit = NUM2LONG(rb_rate_limit);
345
456
 
346
- if ((rateLimit != SUBSCRIBE_RATE_INFINITE) &&
347
- (rateLimit < 10 || rateLimit % 10)) {
348
- rb_raise(rb_eArgError,
349
- "Specify a multiples of 10 or RATE_INFINITE constant");
457
+ if ((rateLimit != SUBSCRIBE_RATE_INFINITE) && (rateLimit < 10 || rateLimit % 10)) {
458
+ rb_raise(rb_eArgError, "Specify a multiples of 10 or RATE_INFINITE constant");
350
459
  } else {
351
460
  winevtSubscribe->rateLimit = rateLimit;
352
461
  }
@@ -354,6 +463,12 @@ rb_winevt_subscribe_set_rate_limit(VALUE self, VALUE rb_rate_limit)
354
463
  return Qnil;
355
464
  }
356
465
 
466
+ /*
467
+ * This method returns whether render as xml or not.
468
+ *
469
+ * @since 0.6.0
470
+ * @return [Boolean]
471
+ */
357
472
  static VALUE
358
473
  rb_winevt_subscribe_render_as_xml_p(VALUE self)
359
474
  {
@@ -365,6 +480,12 @@ rb_winevt_subscribe_render_as_xml_p(VALUE self)
365
480
  return winevtSubscribe->renderAsXML ? Qtrue : Qfalse;
366
481
  }
367
482
 
483
+ /*
484
+ * This method specifies whether render as xml or not.
485
+ *
486
+ * @since 0.6.0
487
+ * @param rb_render_as_xml [Boolean]
488
+ */
368
489
  static VALUE
369
490
  rb_winevt_subscribe_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
370
491
  {
@@ -385,6 +506,10 @@ Init_winevt_subscribe(VALUE rb_cEventLog)
385
506
 
386
507
  rb_define_alloc_func(rb_cSubscribe, rb_winevt_subscribe_alloc);
387
508
 
509
+ /*
510
+ * For Subscribe#rate_limit=. It represents unspecified rate limit.
511
+ * @since 0.6.0
512
+ */
388
513
  rb_define_const(rb_cSubscribe, "RATE_INFINITE", SUBSCRIBE_RATE_INFINITE);
389
514
 
390
515
  rb_define_method(rb_cSubscribe, "initialize", rb_winevt_subscribe_initialize, 0);
@@ -396,6 +521,8 @@ Init_winevt_subscribe(VALUE rb_cEventLog)
396
521
  rb_define_method(rb_cSubscribe, "tail=", rb_winevt_subscribe_set_tail, 1);
397
522
  rb_define_method(rb_cSubscribe, "rate_limit", rb_winevt_subscribe_get_rate_limit, 0);
398
523
  rb_define_method(rb_cSubscribe, "rate_limit=", rb_winevt_subscribe_set_rate_limit, 1);
399
- rb_define_method(rb_cSubscribe, "render_as_xml?", rb_winevt_subscribe_render_as_xml_p, 0);
400
- rb_define_method(rb_cSubscribe, "render_as_xml=", rb_winevt_subscribe_set_render_as_xml, 1);
524
+ rb_define_method(
525
+ rb_cSubscribe, "render_as_xml?", rb_winevt_subscribe_render_as_xml_p, 0);
526
+ rb_define_method(
527
+ rb_cSubscribe, "render_as_xml=", rb_winevt_subscribe_set_render_as_xml, 1);
401
528
  }
@@ -19,6 +19,28 @@ wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen)
19
19
  return str;
20
20
  }
21
21
 
22
+ void
23
+ raise_system_error(VALUE error, DWORD errorCode)
24
+ {
25
+ WCHAR msgBuf[256] = { 0 };
26
+ VALUE errorMessage;
27
+
28
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
29
+ NULL,
30
+ errorCode,
31
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
32
+ msgBuf,
33
+ _countof(msgBuf),
34
+ NULL);
35
+ errorMessage = wstr_to_rb_str(CP_UTF8, msgBuf, -1);
36
+
37
+ #pragma GCC diagnostic push
38
+ #pragma GCC diagnostic ignored "-Wformat="
39
+ #pragma GCC diagnostic ignored "-Wformat-extra-args"
40
+ rb_raise(error, "ErrorCode: %lu\nError: %" PRIsVALUE "\n", errorCode, errorMessage);
41
+ #pragma GCC diagnostic pop
42
+ }
43
+
22
44
  VALUE
23
45
  render_to_rb_str(EVT_HANDLE handle, DWORD flags)
24
46
  {
@@ -44,17 +66,8 @@ render_to_rb_str(EVT_HANDLE handle, DWORD flags)
44
66
  EvtRender(nullptr, handle, flags, bufferSize, buffer, &bufferSizeUsed, &count);
45
67
  if (!succeeded) {
46
68
  DWORD status = GetLastError();
47
- CHAR msgBuf[256];
48
-
49
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
50
- nullptr,
51
- status,
52
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
53
- msgBuf,
54
- _countof(msgBuf),
55
- nullptr);
56
69
  ALLOCV_END(vbuffer);
57
- rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu\nError: %s\n", status, msgBuf);
70
+ raise_system_error(rb_eWinevtQueryError, status);
58
71
  }
59
72
 
60
73
  result = wstr_to_rb_str(CP_UTF8, buffer, -1);
@@ -284,19 +297,9 @@ get_values(EVT_HANDLE handle)
284
297
  &propCount);
285
298
  if (!succeeded) {
286
299
  DWORD status = GetLastError();
287
- CHAR msgBuf[256];
288
-
289
300
  ALLOCV_END(vbuffer);
290
301
  EvtClose(renderContext);
291
-
292
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
293
- nullptr,
294
- status,
295
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
296
- msgBuf,
297
- _countof(msgBuf),
298
- nullptr);
299
- rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu\nError: %s\n", status, msgBuf);
302
+ raise_system_error(rb_eWinevtQueryError, status);
300
303
  }
301
304
 
302
305
  userValues = extract_user_evt_variants(pRenderedValues, propCount);
@@ -437,7 +440,6 @@ get_description(EVT_HANDLE handle)
437
440
  ULONG bufferSizeNeeded = 0;
438
441
  ULONG status, count;
439
442
  std::vector<WCHAR> result;
440
- CHAR msgBuf[256];
441
443
  EVT_HANDLE hMetadata = nullptr;
442
444
 
443
445
  static PCWSTR eventProperties[] = { L"Event/System/Provider/@Name" };
@@ -460,14 +462,7 @@ get_description(EVT_HANDLE handle)
460
462
  }
461
463
 
462
464
  if (status != ERROR_SUCCESS) {
463
- FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
464
- nullptr,
465
- status,
466
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
467
- msgBuf,
468
- sizeof(msgBuf),
469
- nullptr);
470
- rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu\nError: %s\n", status, msgBuf);
465
+ raise_system_error(rb_eWinevtQueryError, status);
471
466
  }
472
467
 
473
468
  // Obtain buffer as EVT_VARIANT pointer. To avoid ErrorCide 87 in EvtRender.
@@ -524,8 +519,8 @@ render_system_event(EVT_HANDLE hEvent)
524
519
 
525
520
  hContext = EvtCreateRenderContext(0, NULL, EvtRenderContextSystem);
526
521
  if (NULL == hContext) {
527
- rb_raise(rb_eWinevtQueryError,
528
- "Failed to create renderContext with %lu\n", GetLastError());
522
+ rb_raise(
523
+ rb_eWinevtQueryError, "Failed to create renderContext with %lu\n", GetLastError());
529
524
  }
530
525
 
531
526
  if (!EvtRender(hContext,
@@ -549,8 +544,7 @@ render_system_event(EVT_HANDLE hEvent)
549
544
  &dwPropertyCount);
550
545
  } else {
551
546
  EvtClose(hContext);
552
- rb_raise(rb_eRuntimeError,
553
- "Failed to malloc memory with %lu\n", status);
547
+ rb_raise(rb_eRuntimeError, "Failed to malloc memory with %lu\n", status);
554
548
  }
555
549
  }
556
550
 
@@ -559,8 +553,7 @@ render_system_event(EVT_HANDLE hEvent)
559
553
  EvtClose(hContext);
560
554
  ALLOCV_END(vRenderedValues);
561
555
 
562
- rb_raise(rb_eWinevtQueryError,
563
- "EvtRender failed with %lu\n", status);
556
+ rb_raise(rb_eWinevtQueryError, "EvtRender failed with %lu\n", status);
564
557
  }
565
558
  }
566
559
 
@@ -605,8 +598,11 @@ render_system_event(EVT_HANDLE hEvent)
605
598
  (EvtVarTypeNull == pRenderedValues[EvtSystemOpcode].Type)
606
599
  ? INT2NUM(0)
607
600
  : INT2NUM(pRenderedValues[EvtSystemOpcode].ByteVal));
608
- _snprintf_s(buffer, _countof(buffer), _TRUNCATE,
609
- "0x%llx", pRenderedValues[EvtSystemKeywords].UInt64Val);
601
+ _snprintf_s(buffer,
602
+ _countof(buffer),
603
+ _TRUNCATE,
604
+ "0x%llx",
605
+ pRenderedValues[EvtSystemKeywords].UInt64Val);
610
606
  rb_hash_aset(hash,
611
607
  rb_str_new2("Keywords"),
612
608
  (EvtVarTypeNull == pRenderedValues[EvtSystemKeywords].Type)
@@ -3,6 +3,7 @@ begin
3
3
  rescue LoadError
4
4
  require "winevt/winevt"
5
5
  end
6
+ require "winevt/bookmark"
6
7
  require "winevt/query"
7
8
  require "winevt/subscribe"
8
9
  require "winevt/version"
@@ -0,0 +1,6 @@
1
+ module Winevt
2
+ class EventLog
3
+ class Bookmark
4
+ end
5
+ end
6
+ end
@@ -1,6 +1,15 @@
1
1
  module Winevt
2
2
  class EventLog
3
3
  class Subscribe
4
+ alias_method :subscribe_raw, :subscribe
5
+
6
+ def subscribe(path, query, bookmark = nil)
7
+ if bookmark.is_a?(Winevt::EventLog::Bookmark)
8
+ subscribe_raw(path, query, bookmark.render)
9
+ else
10
+ subscribe_raw(path, query)
11
+ end
12
+ end
4
13
  end
5
14
  end
6
15
  end
@@ -1,3 +1,3 @@
1
1
  module Winevt
2
- VERSION = "0.6.0"
2
+ VERSION = "0.6.1"
3
3
  end
@@ -30,4 +30,5 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "rake-compiler", "~> 1.0"
31
31
  spec.add_development_dependency "rake-compiler-dock", "~> 0.7.2"
32
32
  spec.add_development_dependency "test-unit", "~> 3.2"
33
+ spec.add_development_dependency "yard", "~> 0.9"
33
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.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi Hatake
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-09 00:00:00.000000000 Z
11
+ date: 2019-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,6 +86,20 @@ dependencies:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
88
  version: '3.2'
89
+ - !ruby/object:Gem::Dependency
90
+ name: yard
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.9'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.9'
89
103
  description: Windows Event Log API bindings from winevt.h.
90
104
  email:
91
105
  - cosmo0920.wp@gmail.com
@@ -116,6 +130,7 @@ files:
116
130
  - ext/winevt/winevt_subscribe.c
117
131
  - ext/winevt/winevt_utils.cpp
118
132
  - lib/winevt.rb
133
+ - lib/winevt/bookmark.rb
119
134
  - lib/winevt/query.rb
120
135
  - lib/winevt/subscribe.rb
121
136
  - lib/winevt/version.rb