winevt_c 0.5.1 → 0.6.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.
@@ -1,24 +1,28 @@
1
1
  #include <winevt_c.h>
2
2
 
3
- static void query_free(void *ptr);
4
-
5
- static const rb_data_type_t rb_winevt_query_type = {
6
- "winevt/query", {
7
- 0, query_free, 0,
8
- }, NULL, NULL,
9
- RUBY_TYPED_FREE_IMMEDIATELY
10
- };
3
+ static void query_free(void* ptr);
4
+
5
+ static const rb_data_type_t rb_winevt_query_type = { "winevt/query",
6
+ {
7
+ 0,
8
+ query_free,
9
+ 0,
10
+ },
11
+ NULL,
12
+ NULL,
13
+ RUBY_TYPED_FREE_IMMEDIATELY };
11
14
 
12
15
  static void
13
- query_free(void *ptr)
16
+ query_free(void* ptr)
14
17
  {
15
- struct WinevtQuery *winevtQuery = (struct WinevtQuery *)ptr;
18
+ struct WinevtQuery* winevtQuery = (struct WinevtQuery*)ptr;
16
19
  if (winevtQuery->query)
17
20
  EvtClose(winevtQuery->query);
18
21
 
19
- if (winevtQuery->event)
20
- EvtClose(winevtQuery->event);
21
-
22
+ for (int i = 0; i < winevtQuery->count; i++) {
23
+ if (winevtQuery->hEvents[i])
24
+ EvtClose(winevtQuery->hEvents[i]);
25
+ }
22
26
  xfree(ptr);
23
27
  }
24
28
 
@@ -26,11 +30,9 @@ static VALUE
26
30
  rb_winevt_query_alloc(VALUE klass)
27
31
  {
28
32
  VALUE obj;
29
- struct WinevtQuery *winevtQuery;
30
- obj = TypedData_Make_Struct(klass,
31
- struct WinevtQuery,
32
- &rb_winevt_query_type,
33
- winevtQuery);
33
+ struct WinevtQuery* winevtQuery;
34
+ obj =
35
+ TypedData_Make_Struct(klass, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
34
36
  return obj;
35
37
  }
36
38
 
@@ -38,7 +40,7 @@ static VALUE
38
40
  rb_winevt_query_initialize(VALUE self, VALUE channel, VALUE xpath)
39
41
  {
40
42
  PWSTR evtChannel, evtXPath;
41
- struct WinevtQuery *winevtQuery;
43
+ struct WinevtQuery* winevtQuery;
42
44
  DWORD len;
43
45
  VALUE wchannelBuf, wpathBuf;
44
46
 
@@ -46,23 +48,26 @@ rb_winevt_query_initialize(VALUE self, VALUE channel, VALUE xpath)
46
48
  Check_Type(xpath, T_STRING);
47
49
 
48
50
  // channel : To wide char
49
- len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
50
- evtChannel = ALLOCV_N(WCHAR, wchannelBuf, len+1);
51
- MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), evtChannel, len);
51
+ len =
52
+ MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
53
+ evtChannel = ALLOCV_N(WCHAR, wchannelBuf, len + 1);
54
+ MultiByteToWideChar(
55
+ CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), evtChannel, len);
52
56
  evtChannel[len] = L'\0';
53
57
 
54
58
  // xpath : To wide char
55
59
  len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), NULL, 0);
56
- evtXPath = ALLOCV_N(WCHAR, wpathBuf, len+1);
60
+ evtXPath = ALLOCV_N(WCHAR, wpathBuf, len + 1);
57
61
  MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), evtXPath, len);
58
62
  evtXPath[len] = L'\0';
59
63
 
60
64
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
61
65
 
62
- winevtQuery->query = EvtQuery(NULL, evtChannel, evtXPath,
63
- EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
66
+ winevtQuery->query = EvtQuery(
67
+ NULL, evtChannel, evtXPath, EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
64
68
  winevtQuery->offset = 0L;
65
69
  winevtQuery->timeout = 0L;
70
+ winevtQuery->renderAsXML = TRUE;
66
71
 
67
72
  ALLOCV_END(wchannelBuf);
68
73
  ALLOCV_END(wpathBuf);
@@ -73,7 +78,7 @@ rb_winevt_query_initialize(VALUE self, VALUE channel, VALUE xpath)
73
78
  static VALUE
74
79
  rb_winevt_query_get_offset(VALUE self, VALUE offset)
75
80
  {
76
- struct WinevtQuery *winevtQuery;
81
+ struct WinevtQuery* winevtQuery;
77
82
 
78
83
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
79
84
 
@@ -83,7 +88,7 @@ rb_winevt_query_get_offset(VALUE self, VALUE offset)
83
88
  static VALUE
84
89
  rb_winevt_query_set_offset(VALUE self, VALUE offset)
85
90
  {
86
- struct WinevtQuery *winevtQuery;
91
+ struct WinevtQuery* winevtQuery;
87
92
 
88
93
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
89
94
 
@@ -95,7 +100,7 @@ rb_winevt_query_set_offset(VALUE self, VALUE offset)
95
100
  static VALUE
96
101
  rb_winevt_query_get_timeout(VALUE self, VALUE timeout)
97
102
  {
98
- struct WinevtQuery *winevtQuery;
103
+ struct WinevtQuery* winevtQuery;
99
104
 
100
105
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
101
106
 
@@ -105,7 +110,7 @@ rb_winevt_query_get_timeout(VALUE self, VALUE timeout)
105
110
  static VALUE
106
111
  rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
107
112
  {
108
- struct WinevtQuery *winevtQuery;
113
+ struct WinevtQuery* winevtQuery;
109
114
 
110
115
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
111
116
 
@@ -117,15 +122,25 @@ rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
117
122
  static VALUE
118
123
  rb_winevt_query_next(VALUE self)
119
124
  {
120
- EVT_HANDLE event;
121
- ULONG count;
122
- struct WinevtQuery *winevtQuery;
125
+ EVT_HANDLE hEvents[QUERY_ARRAY_SIZE];
126
+ ULONG count;
127
+ DWORD status = ERROR_SUCCESS;
128
+ struct WinevtQuery* winevtQuery;
123
129
 
124
130
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
125
131
 
126
- if (EvtNext(winevtQuery->query, 1, &event, INFINITE, 0, &count) != FALSE) {
127
- winevtQuery->event = event;
132
+ if (!EvtNext(winevtQuery->query, QUERY_ARRAY_SIZE, hEvents, INFINITE, 0, &count)) {
133
+ status = GetLastError();
134
+ if (ERROR_NO_MORE_ITEMS != status) {
135
+ return Qfalse;
136
+ }
137
+ }
138
+
139
+ if (status == ERROR_SUCCESS) {
128
140
  winevtQuery->count = count;
141
+ for (int i = 0; i < count; i++){
142
+ winevtQuery->hEvents[i] = hEvents[i];
143
+ }
129
144
 
130
145
  return Qtrue;
131
146
  }
@@ -133,48 +148,37 @@ rb_winevt_query_next(VALUE self)
133
148
  return Qfalse;
134
149
  }
135
150
 
136
-
137
151
  static VALUE
138
- rb_winevt_query_render(VALUE self)
152
+ rb_winevt_query_render(VALUE self, EVT_HANDLE event)
139
153
  {
140
- WCHAR* wResult;
141
- struct WinevtQuery *winevtQuery;
142
- VALUE utf8str;
154
+ struct WinevtQuery* winevtQuery;
143
155
 
144
156
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
145
- wResult = render_event(winevtQuery->event, EvtRenderEventXml);
146
- utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1);
147
157
 
148
- if (wResult != NULL)
149
- free(wResult);
150
-
151
- return utf8str;
158
+ if (winevtQuery->renderAsXML) {
159
+ return render_to_rb_str(event, EvtRenderEventXml);
160
+ } else {
161
+ return render_system_event(event);
162
+ }
152
163
  }
153
164
 
154
165
  static VALUE
155
- rb_winevt_query_message(VALUE self)
166
+ rb_winevt_query_message(EVT_HANDLE event)
156
167
  {
157
168
  WCHAR* wResult;
158
- struct WinevtQuery *winevtQuery;
159
169
  VALUE utf8str;
160
170
 
161
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
162
- wResult = get_description(winevtQuery->event);
171
+ wResult = get_description(event);
163
172
  utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1);
164
-
165
- if (wResult != NULL)
166
- free(wResult);
173
+ free(wResult);
167
174
 
168
175
  return utf8str;
169
176
  }
170
177
 
171
178
  static VALUE
172
- rb_winevt_query_string_inserts(VALUE self)
179
+ rb_winevt_query_string_inserts(EVT_HANDLE event)
173
180
  {
174
- struct WinevtQuery *winevtQuery;
175
-
176
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
177
- return get_values(winevtQuery->event);
181
+ return get_values(event);
178
182
  }
179
183
 
180
184
  static DWORD
@@ -192,37 +196,50 @@ get_evt_seek_flag_from_cstr(char* flag_str)
192
196
  return EvtSeekOriginMask;
193
197
  else if (strcmp(flag_str, "strict") == 0)
194
198
  return EvtSeekStrict;
199
+ else
200
+ rb_raise(rb_eArgError, "Unknown seek flag: %s", flag_str);
201
+
202
+ return 0;
195
203
  }
196
204
 
197
205
  static VALUE
198
206
  rb_winevt_query_seek(VALUE self, VALUE bookmark_or_flag)
199
207
  {
200
- struct WinevtQuery *winevtQuery;
201
- struct WinevtBookmark *winevtBookmark = NULL;
202
- DWORD flag;
208
+ struct WinevtQuery* winevtQuery;
209
+ struct WinevtBookmark* winevtBookmark = NULL;
210
+ DWORD flag = 0;
203
211
 
204
212
  switch (TYPE(bookmark_or_flag)) {
205
- case T_SYMBOL:
206
- flag = get_evt_seek_flag_from_cstr(RSTRING_PTR(rb_sym2str(bookmark_or_flag)));
207
- break;
208
- case T_STRING:
209
- flag = get_evt_seek_flag_from_cstr(StringValueCStr(bookmark_or_flag));
210
- break;
211
- default:
212
- if (!rb_obj_is_kind_of(bookmark_or_flag, rb_cBookmark))
213
- rb_raise(rb_eArgError, "Expected a String or a Symbol or a Bookmark instance");
214
-
215
- winevtBookmark = EventBookMark(bookmark_or_flag);
213
+ case T_SYMBOL:
214
+ flag = get_evt_seek_flag_from_cstr(RSTRING_PTR(rb_sym2str(bookmark_or_flag)));
215
+ break;
216
+ case T_STRING:
217
+ flag = get_evt_seek_flag_from_cstr(StringValueCStr(bookmark_or_flag));
218
+ break;
219
+ case T_FIXNUM:
220
+ flag = NUM2LONG(bookmark_or_flag);
221
+ break;
222
+ default:
223
+ if (!rb_obj_is_kind_of(bookmark_or_flag, rb_cBookmark))
224
+ rb_raise(rb_eArgError, "Expected a String or a Symbol or a Bookmark instance");
225
+
226
+ winevtBookmark = EventBookMark(bookmark_or_flag);
216
227
  }
217
228
 
218
229
  if (winevtBookmark) {
219
230
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
220
- if (EvtSeek(winevtQuery->query, winevtQuery->offset, winevtBookmark->bookmark, winevtQuery->timeout, EvtSeekRelativeToBookmark))
231
+ if (EvtSeek(winevtQuery->query,
232
+ winevtQuery->offset,
233
+ winevtBookmark->bookmark,
234
+ winevtQuery->timeout,
235
+ EvtSeekRelativeToBookmark))
221
236
  return Qtrue;
222
237
  } else {
223
238
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
224
- if (EvtSeek(winevtQuery->query, winevtQuery->offset, NULL, winevtQuery->timeout, flag))
239
+ if (EvtSeek(
240
+ winevtQuery->query, winevtQuery->offset, NULL, winevtQuery->timeout, flag)) {
225
241
  return Qtrue;
242
+ }
226
243
  }
227
244
 
228
245
  return Qfalse;
@@ -231,12 +248,15 @@ rb_winevt_query_seek(VALUE self, VALUE bookmark_or_flag)
231
248
  static VALUE
232
249
  rb_winevt_query_close_handle(VALUE self)
233
250
  {
234
- struct WinevtQuery *winevtQuery;
251
+ struct WinevtQuery* winevtQuery;
235
252
 
236
253
  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
237
254
 
238
- if (winevtQuery->event != NULL) {
239
- EvtClose(winevtQuery->event);
255
+ for (int i = 0; i < winevtQuery->count; i++){
256
+ if (winevtQuery->hEvents[i] != NULL) {
257
+ EvtClose(winevtQuery->hEvents[i]);
258
+ winevtQuery->hEvents[i] = NULL;
259
+ }
240
260
  }
241
261
 
242
262
  return Qnil;
@@ -245,28 +265,26 @@ rb_winevt_query_close_handle(VALUE self)
245
265
  static VALUE
246
266
  rb_winevt_query_each_yield(VALUE self)
247
267
  {
248
- struct WinevtQuery *winevtQuery;
249
-
250
268
  RETURN_ENUMERATOR(self, 0, 0);
251
269
 
252
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
270
+ struct WinevtQuery* winevtQuery;
253
271
 
254
- rb_yield_values(3,
255
- rb_winevt_query_render(self),
256
- rb_winevt_query_message(self),
257
- rb_winevt_query_string_inserts(self));
272
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
258
273
 
274
+ for (int i = 0; i < winevtQuery->count; i++) {
275
+ rb_yield_values(3,
276
+ rb_winevt_query_render(self, winevtQuery->hEvents[i]),
277
+ rb_winevt_query_message(winevtQuery->hEvents[i]),
278
+ rb_winevt_query_string_inserts(winevtQuery->hEvents[i]));
279
+ }
259
280
  return Qnil;
260
281
  }
261
282
 
262
283
  static VALUE
263
284
  rb_winevt_query_each(VALUE self)
264
285
  {
265
- struct WinevtQuery *winevtQuery;
266
-
267
286
  RETURN_ENUMERATOR(self, 0, 0);
268
287
 
269
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
270
288
  while (rb_winevt_query_next(self)) {
271
289
  rb_ensure(rb_winevt_query_each_yield, self, rb_winevt_query_close_handle, self);
272
290
  }
@@ -274,21 +292,51 @@ rb_winevt_query_each(VALUE self)
274
292
  return Qnil;
275
293
  }
276
294
 
277
- void Init_winevt_query(VALUE rb_cEventLog)
295
+ static VALUE
296
+ rb_winevt_query_render_as_xml_p(VALUE self)
278
297
  {
279
- rb_cQuery = rb_define_class_under(rb_cEventLog, "Query", rb_cObject);
298
+ struct WinevtQuery* winevtQuery;
299
+
300
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
301
+
302
+ return winevtQuery->renderAsXML ? Qtrue : Qfalse;
303
+ }
304
+
305
+ static VALUE
306
+ rb_winevt_query_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
307
+ {
308
+ struct WinevtQuery* winevtQuery;
280
309
 
310
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
311
+
312
+ winevtQuery->renderAsXML = RTEST(rb_render_as_xml);
313
+
314
+ return Qnil;
315
+ }
316
+
317
+ void
318
+ Init_winevt_query(VALUE rb_cEventLog)
319
+ {
320
+ rb_cQuery = rb_define_class_under(rb_cEventLog, "Query", rb_cObject);
281
321
  rb_define_alloc_func(rb_cQuery, rb_winevt_query_alloc);
322
+
323
+ rb_cFlag = rb_define_module_under(rb_cQuery, "Flag");
324
+
325
+ rb_define_const(rb_cFlag, "RelativeToFirst", LONG2NUM(EvtSeekRelativeToFirst));
326
+ rb_define_const(rb_cFlag, "RelativeToLast", LONG2NUM(EvtSeekRelativeToLast));
327
+ rb_define_const(rb_cFlag, "RelativeToCurrent", LONG2NUM(EvtSeekRelativeToCurrent));
328
+ rb_define_const(rb_cFlag, "RelativeToBookmark", LONG2NUM(EvtSeekRelativeToBookmark));
329
+ rb_define_const(rb_cFlag, "OriginMask", LONG2NUM(EvtSeekOriginMask));
330
+ rb_define_const(rb_cFlag, "Strict", LONG2NUM(EvtSeekStrict));
331
+
282
332
  rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, 2);
283
333
  rb_define_method(rb_cQuery, "next", rb_winevt_query_next, 0);
284
- rb_define_method(rb_cQuery, "render", rb_winevt_query_render, 0);
285
- rb_define_method(rb_cQuery, "message", rb_winevt_query_message, 0);
286
- rb_define_method(rb_cQuery, "string_inserts", rb_winevt_query_string_inserts, 0);
287
334
  rb_define_method(rb_cQuery, "seek", rb_winevt_query_seek, 1);
288
335
  rb_define_method(rb_cQuery, "offset", rb_winevt_query_get_offset, 0);
289
336
  rb_define_method(rb_cQuery, "offset=", rb_winevt_query_set_offset, 1);
290
337
  rb_define_method(rb_cQuery, "timeout", rb_winevt_query_get_timeout, 0);
291
338
  rb_define_method(rb_cQuery, "timeout=", rb_winevt_query_set_timeout, 1);
292
- rb_define_method(rb_cQuery, "close_handle", rb_winevt_query_close_handle, 0);
293
339
  rb_define_method(rb_cQuery, "each", rb_winevt_query_each, 0);
340
+ rb_define_method(rb_cQuery, "render_as_xml?", rb_winevt_query_render_as_xml_p, 0);
341
+ rb_define_method(rb_cQuery, "render_as_xml=", rb_winevt_query_set_render_as_xml, 1);
294
342
  }