winevt_c 0.6.0 → 0.6.1

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