winevt_c 0.5.1 → 0.6.0

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