winevt_c 0.8.0 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,327 +1,327 @@
1
- #include <winevt_c.h>
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
- * # If users want to retrieve all channel names that
13
- * # including type of Debug and Analytical,
14
- * # it should be set as true.
15
- * @channel.force_enumerate = false
16
- * @channel.each do |channel|
17
- * channels << channel
18
- * end
19
- * print channels
20
- */
21
-
22
- VALUE rb_cChannel;
23
-
24
- DWORD is_subscribable_channel_p(EVT_HANDLE hChannel, BOOL force_enumerate);
25
- DWORD check_subscribable_with_channel_config_type(int Id, PEVT_VARIANT pProperty, BOOL force_enumerate);
26
- static void channel_free(void* ptr);
27
-
28
- static const rb_data_type_t rb_winevt_channel_type = { "winevt/channel",
29
- {
30
- 0,
31
- channel_free,
32
- 0,
33
- },
34
- NULL,
35
- NULL,
36
- RUBY_TYPED_FREE_IMMEDIATELY };
37
-
38
- static void
39
- channel_free(void* ptr)
40
- {
41
- struct WinevtChannel* winevtChannel = (struct WinevtChannel*)ptr;
42
- if (winevtChannel->channels)
43
- EvtClose(winevtChannel->channels);
44
-
45
- xfree(ptr);
46
- }
47
-
48
- static VALUE
49
- rb_winevt_channel_alloc(VALUE klass)
50
- {
51
- VALUE obj;
52
- struct WinevtChannel* winevtChannel;
53
- obj = TypedData_Make_Struct(
54
- klass, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
55
- return obj;
56
- }
57
-
58
- /*
59
- * Initalize Channel class.
60
- *
61
- * @return [Channel]
62
- *
63
- */
64
- static VALUE
65
- rb_winevt_channel_initialize(VALUE self)
66
- {
67
- struct WinevtChannel* winevtChannel;
68
-
69
- TypedData_Get_Struct(
70
- self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
71
-
72
- winevtChannel->force_enumerate = FALSE;
73
-
74
- return Qnil;
75
- }
76
-
77
- /*
78
- * This method specifies whether forcing to enumerate channel which
79
- * type is Debug and Analytical or not.
80
- *
81
- * @param rb_force_enumerate_p [Boolean]
82
- * @since 0.7.1
83
- */
84
- static VALUE
85
- rb_winevt_channel_set_force_enumerate(VALUE self, VALUE rb_force_enumerate_p)
86
- {
87
- struct WinevtChannel* winevtChannel;
88
-
89
- TypedData_Get_Struct(
90
- self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
91
-
92
- winevtChannel->force_enumerate = RTEST(rb_force_enumerate_p);
93
-
94
- return Qnil;
95
- }
96
-
97
- /*
98
- * This method returns whether forcing to enumerate channel which type
99
- * is Debug and Analytical or not.
100
- *
101
- * @return [Boolean]
102
- * @since 0.7.1
103
- */
104
- static VALUE
105
- rb_winevt_channel_get_force_enumerate(VALUE self)
106
- {
107
- struct WinevtChannel* winevtChannel;
108
-
109
- TypedData_Get_Struct(
110
- self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
111
-
112
- return winevtChannel->force_enumerate ? Qtrue : Qfalse;
113
- }
114
-
115
- DWORD is_subscribable_channel_p(EVT_HANDLE hChannel, BOOL force_enumerate)
116
- {
117
- PEVT_VARIANT pProperty = NULL;
118
- PEVT_VARIANT pTemp = NULL;
119
- DWORD dwBufferSize = 0;
120
- DWORD dwBufferUsed = 0;
121
- DWORD status = ERROR_SUCCESS;
122
-
123
- for (int Id = 0; Id < EvtChannelConfigPropertyIdEND; Id++) {
124
- if (!EvtGetChannelConfigProperty(hChannel, (EVT_CHANNEL_CONFIG_PROPERTY_ID)Id, 0, dwBufferSize, pProperty, &dwBufferUsed)) {
125
- status = GetLastError();
126
- if (ERROR_INSUFFICIENT_BUFFER == status) {
127
- dwBufferSize = dwBufferUsed;
128
- pTemp = (PEVT_VARIANT)realloc(pProperty, dwBufferSize);
129
- if (pTemp) {
130
- pProperty = pTemp;
131
- pTemp = NULL;
132
- EvtGetChannelConfigProperty(hChannel, (EVT_CHANNEL_CONFIG_PROPERTY_ID)Id, 0, dwBufferSize, pProperty, &dwBufferUsed);
133
- status = GetLastError();
134
- } else {
135
- free(pProperty);
136
-
137
- status = ERROR_OUTOFMEMORY;
138
-
139
- goto cleanup;
140
- }
141
- }
142
-
143
- if (ERROR_SUCCESS != status) {
144
- free(pProperty);
145
-
146
- goto cleanup;
147
- }
148
- }
149
-
150
- status = check_subscribable_with_channel_config_type(Id, pProperty, force_enumerate);
151
- if (status != ERROR_SUCCESS)
152
- break;
153
- }
154
-
155
- cleanup:
156
-
157
- free(pProperty);
158
-
159
- return status;
160
- }
161
-
162
- #define EVENT_DEBUG_TYPE 2
163
- #define EVENT_ANALYTICAL_TYPE 3
164
-
165
- DWORD check_subscribable_with_channel_config_type(int Id, PEVT_VARIANT pProperty, BOOL force_enumerate)
166
- {
167
- DWORD status = ERROR_SUCCESS;
168
- switch(Id) {
169
- case EvtChannelConfigType:
170
- if (!force_enumerate &&
171
- (pProperty->UInt32Val == EVENT_DEBUG_TYPE ||
172
- pProperty->UInt32Val == EVENT_ANALYTICAL_TYPE)) {
173
- return ERROR_INVALID_DATA;
174
- }
175
- break;
176
- }
177
-
178
- return status;
179
- }
180
-
181
- #undef EVENT_DEBUG_TYPE
182
- #undef EVENT_ANALYTICAL_TYPE
183
-
184
- /*
185
- * Enumerate Windows EventLog channels
186
- *
187
- * @yield (String)
188
- *
189
- */
190
- static VALUE
191
- rb_winevt_channel_each(VALUE self)
192
- {
193
- EVT_HANDLE hChannels;
194
- EVT_HANDLE hChannelConfig = NULL;
195
- struct WinevtChannel* winevtChannel;
196
- char errBuf[256];
197
- LPWSTR buffer = NULL;
198
- DWORD bufferSize = 0;
199
- DWORD bufferUsed = 0;
200
- DWORD status = ERROR_SUCCESS;
201
- VALUE utf8str;
202
-
203
- RETURN_ENUMERATOR(self, 0, 0);
204
-
205
- TypedData_Get_Struct(
206
- self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
207
-
208
- hChannels = EvtOpenChannelEnum(NULL, 0);
209
-
210
- if (hChannels) {
211
- winevtChannel->channels = hChannels;
212
- } else {
213
- _snprintf_s(errBuf,
214
- _countof(errBuf),
215
- _TRUNCATE,
216
- "Failed to enumerate channels with %lu\n",
217
- GetLastError());
218
- rb_raise(rb_eRuntimeError, errBuf);
219
- }
220
-
221
- while (1) {
222
- if (!EvtNextChannelPath(winevtChannel->channels, bufferSize, buffer, &bufferUsed)) {
223
- status = GetLastError();
224
-
225
- if (ERROR_NO_MORE_ITEMS == status) {
226
- break;
227
- } else if (ERROR_INSUFFICIENT_BUFFER == status) {
228
- bufferSize = bufferUsed;
229
- buffer = (LPWSTR)malloc(bufferSize * sizeof(WCHAR));
230
- if (buffer) {
231
- continue;
232
- } else {
233
- free(buffer);
234
- EvtClose(winevtChannel->channels);
235
- winevtChannel->channels = NULL;
236
- rb_raise(rb_eRuntimeError, "realloc failed");
237
- }
238
- } else {
239
- free(buffer);
240
- EvtClose(winevtChannel->channels);
241
- winevtChannel->channels = NULL;
242
- _snprintf_s(errBuf,
243
- _countof(errBuf),
244
- _TRUNCATE,
245
- "EvtNextChannelPath failed with %lu.\n",
246
- status);
247
- rb_raise(rb_eRuntimeError, errBuf);
248
- }
249
- }
250
- hChannelConfig = EvtOpenChannelConfig(NULL, buffer, 0);
251
- if (NULL == hChannelConfig) {
252
- _snprintf_s(errBuf,
253
- _countof(errBuf),
254
- _TRUNCATE,
255
- "EvtOpenChannelConfig failed with %lu.\n",
256
- GetLastError());
257
-
258
- EvtClose(winevtChannel->channels);
259
- winevtChannel->channels = NULL;
260
-
261
- free(buffer);
262
- buffer = NULL;
263
- bufferSize = 0;
264
-
265
- rb_raise(rb_eRuntimeError, errBuf);
266
- }
267
-
268
- status = is_subscribable_channel_p(hChannelConfig, winevtChannel->force_enumerate);
269
- EvtClose(hChannelConfig);
270
-
271
- if (status == ERROR_INVALID_DATA) {
272
- free(buffer);
273
- buffer = NULL;
274
- bufferSize = 0;
275
-
276
- continue;
277
- }
278
-
279
- if (status == ERROR_OUTOFMEMORY) {
280
- EvtClose(winevtChannel->channels);
281
- winevtChannel->channels = NULL;
282
-
283
- free(buffer);
284
- buffer = NULL;
285
- bufferSize = 0;
286
-
287
- rb_raise(rb_eRuntimeError, "realloc failed\n");
288
- } else if (status != ERROR_SUCCESS) {
289
- EvtClose(winevtChannel->channels);
290
- winevtChannel->channels = NULL;
291
-
292
- free(buffer);
293
- buffer = NULL;
294
- bufferSize = 0;
295
-
296
- rb_raise(rb_eRuntimeError, "is_subscribe_channel_p is failed with %ld\n", status);
297
- }
298
-
299
- utf8str = wstr_to_rb_str(CP_UTF8, buffer, -1);
300
-
301
- free(buffer);
302
- buffer = NULL;
303
- bufferSize = 0;
304
-
305
- rb_yield(utf8str);
306
- }
307
-
308
- if (winevtChannel->channels) {
309
- EvtClose(winevtChannel->channels);
310
- winevtChannel->channels = NULL;
311
- }
312
-
313
- free(buffer);
314
-
315
- return Qnil;
316
- }
317
-
318
- void
319
- Init_winevt_channel(VALUE rb_cEventLog)
320
- {
321
- rb_cChannel = rb_define_class_under(rb_cEventLog, "Channel", rb_cObject);
322
- rb_define_alloc_func(rb_cChannel, rb_winevt_channel_alloc);
323
- rb_define_method(rb_cChannel, "initialize", rb_winevt_channel_initialize, 0);
324
- rb_define_method(rb_cChannel, "each", rb_winevt_channel_each, 0);
325
- rb_define_method(rb_cChannel, "force_enumerate", rb_winevt_channel_get_force_enumerate, 0);
326
- rb_define_method(rb_cChannel, "force_enumerate=", rb_winevt_channel_set_force_enumerate, 1);
327
- }
1
+ #include <winevt_c.h>
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
+ * # If users want to retrieve all channel names that
13
+ * # including type of Debug and Analytical,
14
+ * # it should be set as true.
15
+ * @channel.force_enumerate = false
16
+ * @channel.each do |channel|
17
+ * channels << channel
18
+ * end
19
+ * print channels
20
+ */
21
+
22
+ VALUE rb_cChannel;
23
+
24
+ DWORD is_subscribable_channel_p(EVT_HANDLE hChannel, BOOL force_enumerate);
25
+ DWORD check_subscribable_with_channel_config_type(int Id, PEVT_VARIANT pProperty, BOOL force_enumerate);
26
+ static void channel_free(void* ptr);
27
+
28
+ static const rb_data_type_t rb_winevt_channel_type = { "winevt/channel",
29
+ {
30
+ 0,
31
+ channel_free,
32
+ 0,
33
+ },
34
+ NULL,
35
+ NULL,
36
+ RUBY_TYPED_FREE_IMMEDIATELY };
37
+
38
+ static void
39
+ channel_free(void* ptr)
40
+ {
41
+ struct WinevtChannel* winevtChannel = (struct WinevtChannel*)ptr;
42
+ if (winevtChannel->channels)
43
+ EvtClose(winevtChannel->channels);
44
+
45
+ xfree(ptr);
46
+ }
47
+
48
+ static VALUE
49
+ rb_winevt_channel_alloc(VALUE klass)
50
+ {
51
+ VALUE obj;
52
+ struct WinevtChannel* winevtChannel;
53
+ obj = TypedData_Make_Struct(
54
+ klass, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
55
+ return obj;
56
+ }
57
+
58
+ /*
59
+ * Initalize Channel class.
60
+ *
61
+ * @return [Channel]
62
+ *
63
+ */
64
+ static VALUE
65
+ rb_winevt_channel_initialize(VALUE self)
66
+ {
67
+ struct WinevtChannel* winevtChannel;
68
+
69
+ TypedData_Get_Struct(
70
+ self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
71
+
72
+ winevtChannel->force_enumerate = FALSE;
73
+
74
+ return Qnil;
75
+ }
76
+
77
+ /*
78
+ * This method specifies whether forcing to enumerate channel which
79
+ * type is Debug and Analytical or not.
80
+ *
81
+ * @param rb_force_enumerate_p [Boolean]
82
+ * @since 0.7.1
83
+ */
84
+ static VALUE
85
+ rb_winevt_channel_set_force_enumerate(VALUE self, VALUE rb_force_enumerate_p)
86
+ {
87
+ struct WinevtChannel* winevtChannel;
88
+
89
+ TypedData_Get_Struct(
90
+ self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
91
+
92
+ winevtChannel->force_enumerate = RTEST(rb_force_enumerate_p);
93
+
94
+ return Qnil;
95
+ }
96
+
97
+ /*
98
+ * This method returns whether forcing to enumerate channel which type
99
+ * is Debug and Analytical or not.
100
+ *
101
+ * @return [Boolean]
102
+ * @since 0.7.1
103
+ */
104
+ static VALUE
105
+ rb_winevt_channel_get_force_enumerate(VALUE self)
106
+ {
107
+ struct WinevtChannel* winevtChannel;
108
+
109
+ TypedData_Get_Struct(
110
+ self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
111
+
112
+ return winevtChannel->force_enumerate ? Qtrue : Qfalse;
113
+ }
114
+
115
+ DWORD is_subscribable_channel_p(EVT_HANDLE hChannel, BOOL force_enumerate)
116
+ {
117
+ PEVT_VARIANT pProperty = NULL;
118
+ PEVT_VARIANT pTemp = NULL;
119
+ DWORD dwBufferSize = 0;
120
+ DWORD dwBufferUsed = 0;
121
+ DWORD status = ERROR_SUCCESS;
122
+
123
+ for (int Id = 0; Id < EvtChannelConfigPropertyIdEND; Id++) {
124
+ if (!EvtGetChannelConfigProperty(hChannel, (EVT_CHANNEL_CONFIG_PROPERTY_ID)Id, 0, dwBufferSize, pProperty, &dwBufferUsed)) {
125
+ status = GetLastError();
126
+ if (ERROR_INSUFFICIENT_BUFFER == status) {
127
+ dwBufferSize = dwBufferUsed;
128
+ pTemp = (PEVT_VARIANT)realloc(pProperty, dwBufferSize);
129
+ if (pTemp) {
130
+ pProperty = pTemp;
131
+ pTemp = NULL;
132
+ EvtGetChannelConfigProperty(hChannel, (EVT_CHANNEL_CONFIG_PROPERTY_ID)Id, 0, dwBufferSize, pProperty, &dwBufferUsed);
133
+ status = GetLastError();
134
+ } else {
135
+ free(pProperty);
136
+
137
+ status = ERROR_OUTOFMEMORY;
138
+
139
+ goto cleanup;
140
+ }
141
+ }
142
+
143
+ if (ERROR_SUCCESS != status) {
144
+ free(pProperty);
145
+
146
+ goto cleanup;
147
+ }
148
+ }
149
+
150
+ status = check_subscribable_with_channel_config_type(Id, pProperty, force_enumerate);
151
+ if (status != ERROR_SUCCESS)
152
+ break;
153
+ }
154
+
155
+ cleanup:
156
+
157
+ free(pProperty);
158
+
159
+ return status;
160
+ }
161
+
162
+ #define EVENT_DEBUG_TYPE 2
163
+ #define EVENT_ANALYTICAL_TYPE 3
164
+
165
+ DWORD check_subscribable_with_channel_config_type(int Id, PEVT_VARIANT pProperty, BOOL force_enumerate)
166
+ {
167
+ DWORD status = ERROR_SUCCESS;
168
+ switch(Id) {
169
+ case EvtChannelConfigType:
170
+ if (!force_enumerate &&
171
+ (pProperty->UInt32Val == EVENT_DEBUG_TYPE ||
172
+ pProperty->UInt32Val == EVENT_ANALYTICAL_TYPE)) {
173
+ return ERROR_INVALID_DATA;
174
+ }
175
+ break;
176
+ }
177
+
178
+ return status;
179
+ }
180
+
181
+ #undef EVENT_DEBUG_TYPE
182
+ #undef EVENT_ANALYTICAL_TYPE
183
+
184
+ /*
185
+ * Enumerate Windows EventLog channels
186
+ *
187
+ * @yield (String)
188
+ *
189
+ */
190
+ static VALUE
191
+ rb_winevt_channel_each(VALUE self)
192
+ {
193
+ EVT_HANDLE hChannels;
194
+ EVT_HANDLE hChannelConfig = NULL;
195
+ struct WinevtChannel* winevtChannel;
196
+ char errBuf[256];
197
+ LPWSTR buffer = NULL;
198
+ DWORD bufferSize = 0;
199
+ DWORD bufferUsed = 0;
200
+ DWORD status = ERROR_SUCCESS;
201
+ VALUE utf8str;
202
+
203
+ RETURN_ENUMERATOR(self, 0, 0);
204
+
205
+ TypedData_Get_Struct(
206
+ self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
207
+
208
+ hChannels = EvtOpenChannelEnum(NULL, 0);
209
+
210
+ if (hChannels) {
211
+ winevtChannel->channels = hChannels;
212
+ } else {
213
+ _snprintf_s(errBuf,
214
+ _countof(errBuf),
215
+ _TRUNCATE,
216
+ "Failed to enumerate channels with %lu\n",
217
+ GetLastError());
218
+ rb_raise(rb_eRuntimeError, errBuf);
219
+ }
220
+
221
+ while (1) {
222
+ if (!EvtNextChannelPath(winevtChannel->channels, bufferSize, buffer, &bufferUsed)) {
223
+ status = GetLastError();
224
+
225
+ if (ERROR_NO_MORE_ITEMS == status) {
226
+ break;
227
+ } else if (ERROR_INSUFFICIENT_BUFFER == status) {
228
+ bufferSize = bufferUsed;
229
+ buffer = (LPWSTR)malloc(bufferSize * sizeof(WCHAR));
230
+ if (buffer) {
231
+ continue;
232
+ } else {
233
+ free(buffer);
234
+ EvtClose(winevtChannel->channels);
235
+ winevtChannel->channels = NULL;
236
+ rb_raise(rb_eRuntimeError, "realloc failed");
237
+ }
238
+ } else {
239
+ free(buffer);
240
+ EvtClose(winevtChannel->channels);
241
+ winevtChannel->channels = NULL;
242
+ _snprintf_s(errBuf,
243
+ _countof(errBuf),
244
+ _TRUNCATE,
245
+ "EvtNextChannelPath failed with %lu.\n",
246
+ status);
247
+ rb_raise(rb_eRuntimeError, errBuf);
248
+ }
249
+ }
250
+ hChannelConfig = EvtOpenChannelConfig(NULL, buffer, 0);
251
+ if (NULL == hChannelConfig) {
252
+ _snprintf_s(errBuf,
253
+ _countof(errBuf),
254
+ _TRUNCATE,
255
+ "EvtOpenChannelConfig failed with %lu.\n",
256
+ GetLastError());
257
+
258
+ EvtClose(winevtChannel->channels);
259
+ winevtChannel->channels = NULL;
260
+
261
+ free(buffer);
262
+ buffer = NULL;
263
+ bufferSize = 0;
264
+
265
+ rb_raise(rb_eRuntimeError, errBuf);
266
+ }
267
+
268
+ status = is_subscribable_channel_p(hChannelConfig, winevtChannel->force_enumerate);
269
+ EvtClose(hChannelConfig);
270
+
271
+ if (status == ERROR_INVALID_DATA) {
272
+ free(buffer);
273
+ buffer = NULL;
274
+ bufferSize = 0;
275
+
276
+ continue;
277
+ }
278
+
279
+ if (status == ERROR_OUTOFMEMORY) {
280
+ EvtClose(winevtChannel->channels);
281
+ winevtChannel->channels = NULL;
282
+
283
+ free(buffer);
284
+ buffer = NULL;
285
+ bufferSize = 0;
286
+
287
+ rb_raise(rb_eRuntimeError, "realloc failed\n");
288
+ } else if (status != ERROR_SUCCESS) {
289
+ EvtClose(winevtChannel->channels);
290
+ winevtChannel->channels = NULL;
291
+
292
+ free(buffer);
293
+ buffer = NULL;
294
+ bufferSize = 0;
295
+
296
+ rb_raise(rb_eRuntimeError, "is_subscribe_channel_p is failed with %ld\n", status);
297
+ }
298
+
299
+ utf8str = wstr_to_rb_str(CP_UTF8, buffer, -1);
300
+
301
+ free(buffer);
302
+ buffer = NULL;
303
+ bufferSize = 0;
304
+
305
+ rb_yield(utf8str);
306
+ }
307
+
308
+ if (winevtChannel->channels) {
309
+ EvtClose(winevtChannel->channels);
310
+ winevtChannel->channels = NULL;
311
+ }
312
+
313
+ free(buffer);
314
+
315
+ return Qnil;
316
+ }
317
+
318
+ void
319
+ Init_winevt_channel(VALUE rb_cEventLog)
320
+ {
321
+ rb_cChannel = rb_define_class_under(rb_cEventLog, "Channel", rb_cObject);
322
+ rb_define_alloc_func(rb_cChannel, rb_winevt_channel_alloc);
323
+ rb_define_method(rb_cChannel, "initialize", rb_winevt_channel_initialize, 0);
324
+ rb_define_method(rb_cChannel, "each", rb_winevt_channel_each, 0);
325
+ rb_define_method(rb_cChannel, "force_enumerate", rb_winevt_channel_get_force_enumerate, 0);
326
+ rb_define_method(rb_cChannel, "force_enumerate=", rb_winevt_channel_set_force_enumerate, 1);
327
+ }