winevt_c 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,100 @@
1
+ #include <winevt_c.h>
2
+
3
+ static void bookmark_free(void *ptr);
4
+
5
+ static const rb_data_type_t rb_winevt_bookmark_type = {
6
+ "winevt/bookmark", {
7
+ 0, bookmark_free, 0,
8
+ }, NULL, NULL,
9
+ RUBY_TYPED_FREE_IMMEDIATELY
10
+ };
11
+
12
+ static void
13
+ bookmark_free(void *ptr)
14
+ {
15
+ struct WinevtBookmark *winevtBookmark = (struct WinevtBookmark *)ptr;
16
+ if (winevtBookmark->bookmark)
17
+ EvtClose(winevtBookmark->bookmark);
18
+
19
+ xfree(ptr);
20
+ }
21
+
22
+ static VALUE
23
+ rb_winevt_bookmark_alloc(VALUE klass)
24
+ {
25
+ VALUE obj;
26
+ struct WinevtBookmark *winevtBookmark;
27
+ obj = TypedData_Make_Struct(klass,
28
+ struct WinevtBookmark,
29
+ &rb_winevt_bookmark_type,
30
+ winevtBookmark);
31
+ return obj;
32
+ }
33
+
34
+ static VALUE
35
+ rb_winevt_bookmark_initialize(int argc, VALUE *argv, VALUE self)
36
+ {
37
+ PWSTR bookmarkXml;
38
+ VALUE wbookmarkXmlBuf;
39
+ DWORD len;
40
+ struct WinevtBookmark *winevtBookmark;
41
+
42
+ TypedData_Get_Struct(self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
43
+
44
+ if (argc == 0) {
45
+ winevtBookmark->bookmark = EvtCreateBookmark(NULL);
46
+ } else if (argc == 1) {
47
+ VALUE rb_bookmarkXml;
48
+ rb_scan_args(argc, argv, "10", &rb_bookmarkXml);
49
+ Check_Type(rb_bookmarkXml, T_STRING);
50
+
51
+ // bookmarkXml : To wide char
52
+ len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_bookmarkXml), RSTRING_LEN(rb_bookmarkXml), NULL, 0);
53
+ bookmarkXml = ALLOCV_N(WCHAR, wbookmarkXmlBuf, len+1);
54
+ MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_bookmarkXml), RSTRING_LEN(rb_bookmarkXml), bookmarkXml, len);
55
+ bookmarkXml[len] = L'\0';
56
+ winevtBookmark->bookmark = EvtCreateBookmark(bookmarkXml);
57
+ ALLOCV_END(wbookmarkXmlBuf);
58
+ }
59
+
60
+ return Qnil;
61
+ }
62
+
63
+ static VALUE
64
+ rb_winevt_bookmark_update(VALUE self, VALUE event)
65
+ {
66
+ struct WinevtQuery *winevtQuery;
67
+ struct WinevtBookmark *winevtBookmark;
68
+
69
+ winevtQuery = EventQuery(event);
70
+
71
+ TypedData_Get_Struct(self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
72
+
73
+ if(EvtUpdateBookmark(winevtBookmark->bookmark, winevtQuery->event))
74
+ return Qtrue;
75
+
76
+ return Qfalse;
77
+ }
78
+
79
+ static VALUE
80
+ rb_winevt_bookmark_render(VALUE self)
81
+ {
82
+ char* result;
83
+ struct WinevtBookmark *winevtBookmark;
84
+
85
+ TypedData_Get_Struct(self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
86
+
87
+ result = render_event(winevtBookmark->bookmark, EvtRenderBookmark);
88
+
89
+ return rb_str_new2(result);
90
+ }
91
+
92
+ void Init_winevt_bookmark(VALUE rb_cEventLog)
93
+ {
94
+ rb_cBookmark = rb_define_class_under(rb_cEventLog, "Bookmark", rb_cObject);
95
+
96
+ rb_define_alloc_func(rb_cBookmark, rb_winevt_bookmark_alloc);
97
+ rb_define_method(rb_cBookmark, "initialize", rb_winevt_bookmark_initialize, -1);
98
+ rb_define_method(rb_cBookmark, "update", rb_winevt_bookmark_update, 1);
99
+ rb_define_method(rb_cBookmark, "render", rb_winevt_bookmark_render, 0);
100
+ }
@@ -0,0 +1,65 @@
1
+ #ifndef _WINEVT_C_H_
2
+ #define _WINEVT_C_H_
3
+
4
+ #include <ruby.h>
5
+ #include <ruby/encoding.h>
6
+
7
+ #ifdef __GNUC__
8
+ # include <w32api.h>
9
+ # define MINIMUM_WINDOWS_VERSION WindowsVista
10
+ #else /* __GNUC__ */
11
+ # define MINIMUM_WINDOWS_VERSION 0x0600 /* Vista */
12
+ #endif /* __GNUC__ */
13
+
14
+ #ifdef _WIN32_WINNT
15
+ # undef WIN32_WINNT
16
+ #endif /* WIN32_WINNT */
17
+ #define _WIN32_WINNT MINIMUM_WINDOWS_VERSION
18
+
19
+ #include <winevt.h>
20
+ #define EventQuery(object) ((struct WinevtQuery *)DATA_PTR(object))
21
+ #define EventBookMark(object) ((struct WinevtBookmark *)DATA_PTR(object))
22
+ #define EventChannel(object) ((struct WinevtChannel *)DATA_PTR(object))
23
+
24
+ char* wstr_to_mbstr(UINT cp, const WCHAR *wstr, int clen);
25
+ char* render_event(EVT_HANDLE handle, DWORD flags);
26
+ char* get_description(EVT_HANDLE handle);
27
+
28
+ VALUE rb_cQuery;
29
+ VALUE rb_cChannel;
30
+ VALUE rb_cBookmark;
31
+ VALUE rb_cSubscribe;
32
+ VALUE rb_eWinevtQueryError;
33
+
34
+ struct WinevtChannel {
35
+ EVT_HANDLE channels;
36
+ };
37
+
38
+ struct WinevtBookmark {
39
+ EVT_HANDLE bookmark;
40
+ ULONG count;
41
+ };
42
+
43
+ struct WinevtQuery {
44
+ EVT_HANDLE query;
45
+ EVT_HANDLE event;
46
+ ULONG count;
47
+ LONG offset;
48
+ LONG timeout;
49
+ };
50
+
51
+ struct WinevtSubscribe {
52
+ HANDLE signalEvent;
53
+ EVT_HANDLE subscription;
54
+ EVT_HANDLE bookmark;
55
+ EVT_HANDLE event;
56
+ DWORD flags;
57
+ BOOL tailing;
58
+ };
59
+
60
+ void Init_winevt_query(VALUE rb_cEventLog);
61
+ void Init_winevt_channel(VALUE rb_cEventLog);
62
+ void Init_winevt_bookmark(VALUE rb_cEventLog);
63
+ void Init_winevt_subscribe(VALUE rb_cEventLog);
64
+
65
+ #endif // _WINEVT_C_H
@@ -0,0 +1,103 @@
1
+ #include <winevt_c.h>
2
+
3
+ static void channel_free(void *ptr);
4
+
5
+ static const rb_data_type_t rb_winevt_channel_type = {
6
+ "winevt/channel", {
7
+ 0, channel_free, 0,
8
+ }, NULL, NULL,
9
+ RUBY_TYPED_FREE_IMMEDIATELY
10
+ };
11
+
12
+ static void
13
+ channel_free(void *ptr)
14
+ {
15
+ struct WinevtChannel *winevtChannel = (struct WinevtChannel *)ptr;
16
+ if (winevtChannel->channels)
17
+ EvtClose(winevtChannel->channels);
18
+
19
+ xfree(ptr);
20
+ }
21
+
22
+ static VALUE
23
+ rb_winevt_channel_alloc(VALUE klass)
24
+ {
25
+ VALUE obj;
26
+ struct WinevtChannel *winevtChannel;
27
+ obj = TypedData_Make_Struct(klass,
28
+ struct WinevtChannel,
29
+ &rb_winevt_channel_type,
30
+ winevtChannel);
31
+ return obj;
32
+ }
33
+
34
+ static VALUE
35
+ rb_winevt_channel_initialize(VALUE klass)
36
+ {
37
+ return Qnil;
38
+ }
39
+
40
+ static VALUE
41
+ rb_winevt_channel_each(VALUE self)
42
+ {
43
+ EVT_HANDLE hChannels;
44
+ struct WinevtChannel *winevtChannel;
45
+ char *errBuf;
46
+ char * result;
47
+ LPWSTR buffer = NULL;
48
+ LPWSTR temp = NULL;
49
+ DWORD bufferSize = 0;
50
+ DWORD bufferUsed = 0;
51
+ DWORD status = ERROR_SUCCESS;
52
+
53
+ RETURN_ENUMERATOR(self, 0, 0);
54
+
55
+ TypedData_Get_Struct(self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
56
+
57
+ hChannels = EvtOpenChannelEnum(NULL, 0);
58
+
59
+ if (hChannels) {
60
+ winevtChannel->channels = hChannels;
61
+ } else {
62
+ sprintf(errBuf, "Failed to enumerate channels with %s\n", GetLastError());
63
+ rb_raise(rb_eRuntimeError, errBuf);
64
+ }
65
+
66
+ while (1) {
67
+ if (!EvtNextChannelPath(winevtChannel->channels, bufferSize, buffer, &bufferUsed)) {
68
+ status = GetLastError();
69
+
70
+ if (ERROR_NO_MORE_ITEMS == status) {
71
+ break;
72
+ } else if (ERROR_INSUFFICIENT_BUFFER == status) {
73
+ bufferSize = bufferUsed;
74
+ temp = (LPWSTR)realloc(buffer, bufferSize * sizeof(WCHAR));
75
+ if (temp) {
76
+ buffer = temp;
77
+ temp = NULL;
78
+ EvtNextChannelPath(winevtChannel->channels, bufferSize, buffer, &bufferUsed);
79
+ } else {
80
+ status = ERROR_OUTOFMEMORY;
81
+ rb_raise(rb_eRuntimeError, "realloc failed");
82
+ }
83
+ } else {
84
+ sprintf(errBuf, "EvtNextChannelPath failed with %lu.\n", status);
85
+ rb_raise(rb_eRuntimeError, errBuf);
86
+ }
87
+ }
88
+
89
+ result = wstr_to_mbstr(CP_UTF8, buffer, -1);
90
+
91
+ rb_yield(rb_str_new2(result));
92
+ }
93
+
94
+ return Qnil;
95
+ }
96
+
97
+ void Init_winevt_channel(VALUE rb_cEventLog)
98
+ {
99
+ rb_cChannel = rb_define_class_under(rb_cEventLog, "Channel", rb_cObject);
100
+ rb_define_alloc_func(rb_cChannel, rb_winevt_channel_alloc);
101
+ rb_define_method(rb_cChannel, "initialize", rb_winevt_channel_initialize, 0);
102
+ rb_define_method(rb_cChannel, "each", rb_winevt_channel_each, 0);
103
+ }
@@ -0,0 +1,245 @@
1
+ #include <winevt_c.h>
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
+ };
11
+
12
+ static void
13
+ query_free(void *ptr)
14
+ {
15
+ struct WinevtQuery *winevtQuery = (struct WinevtQuery *)ptr;
16
+ if (winevtQuery->query)
17
+ EvtClose(winevtQuery->query);
18
+
19
+ if (winevtQuery->event)
20
+ EvtClose(winevtQuery->event);
21
+
22
+ xfree(ptr);
23
+ }
24
+
25
+ static VALUE
26
+ rb_winevt_query_alloc(VALUE klass)
27
+ {
28
+ VALUE obj;
29
+ struct WinevtQuery *winevtQuery;
30
+ obj = TypedData_Make_Struct(klass,
31
+ struct WinevtQuery,
32
+ &rb_winevt_query_type,
33
+ winevtQuery);
34
+ return obj;
35
+ }
36
+
37
+ static VALUE
38
+ rb_winevt_query_initialize(VALUE self, VALUE channel, VALUE xpath)
39
+ {
40
+ PWSTR evtChannel, evtXPath;
41
+ struct WinevtQuery *winevtQuery;
42
+ DWORD len;
43
+ VALUE wchannelBuf, wpathBuf;
44
+
45
+ Check_Type(channel, T_STRING);
46
+ Check_Type(xpath, T_STRING);
47
+
48
+ // 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);
52
+ evtChannel[len] = L'\0';
53
+
54
+ // xpath : To wide char
55
+ len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), NULL, 0);
56
+ evtXPath = ALLOCV_N(WCHAR, wpathBuf, len+1);
57
+ MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), evtXPath, len);
58
+ evtXPath[len] = L'\0';
59
+
60
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
61
+
62
+ winevtQuery->query = EvtQuery(NULL, evtChannel, evtXPath,
63
+ EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
64
+ winevtQuery->offset = 0L;
65
+ winevtQuery->timeout = 0L;
66
+
67
+ ALLOCV_END(wchannelBuf);
68
+ ALLOCV_END(wpathBuf);
69
+
70
+ return Qnil;
71
+ }
72
+
73
+ static VALUE
74
+ rb_winevt_query_get_offset(VALUE self, VALUE offset)
75
+ {
76
+ struct WinevtQuery *winevtQuery;
77
+
78
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
79
+
80
+ return LONG2NUM(winevtQuery->offset);
81
+ }
82
+
83
+ static VALUE
84
+ rb_winevt_query_set_offset(VALUE self, VALUE offset)
85
+ {
86
+ struct WinevtQuery *winevtQuery;
87
+
88
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
89
+
90
+ winevtQuery->offset = NUM2LONG(offset);
91
+
92
+ return Qnil;
93
+ }
94
+
95
+ static VALUE
96
+ rb_winevt_query_get_timeout(VALUE self, VALUE timeout)
97
+ {
98
+ struct WinevtQuery *winevtQuery;
99
+
100
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
101
+
102
+ return LONG2NUM(winevtQuery->timeout);
103
+ }
104
+
105
+ static VALUE
106
+ rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
107
+ {
108
+ struct WinevtQuery *winevtQuery;
109
+
110
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
111
+
112
+ winevtQuery->timeout = NUM2LONG(timeout);
113
+
114
+ return Qnil;
115
+ }
116
+
117
+ static VALUE
118
+ rb_winevt_query_next(VALUE self)
119
+ {
120
+ EVT_HANDLE event;
121
+ ULONG count;
122
+ struct WinevtQuery *winevtQuery;
123
+
124
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
125
+
126
+ if (EvtNext(winevtQuery->query, 1, &event, INFINITE, 0, &count) != FALSE) {
127
+ winevtQuery->event = event;
128
+ winevtQuery->count = count;
129
+
130
+ return Qtrue;
131
+ }
132
+
133
+ return Qfalse;
134
+ }
135
+
136
+
137
+ static VALUE
138
+ rb_winevt_query_render(VALUE self)
139
+ {
140
+ char* result;
141
+ struct WinevtQuery *winevtQuery;
142
+
143
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
144
+ result = render_event(winevtQuery->event, EvtRenderEventXml);
145
+ get_description(winevtQuery->event);
146
+
147
+ return rb_str_new2(result);
148
+ }
149
+
150
+ static VALUE
151
+ rb_winevt_query_message(VALUE self)
152
+ {
153
+ char* result;
154
+ struct WinevtQuery *winevtQuery;
155
+
156
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
157
+ result = get_description(winevtQuery->event);
158
+
159
+ return rb_str_new2(result);
160
+ }
161
+
162
+ static DWORD
163
+ get_evt_seek_flag_from_cstr(char* flag_str)
164
+ {
165
+ if (strcmp(flag_str, "first") == 0)
166
+ return EvtSeekRelativeToFirst;
167
+ else if (strcmp(flag_str, "last") == 0)
168
+ return EvtSeekRelativeToLast;
169
+ else if (strcmp(flag_str, "current") == 0)
170
+ return EvtSeekRelativeToCurrent;
171
+ else if (strcmp(flag_str, "bookmark") == 0)
172
+ return EvtSeekRelativeToBookmark;
173
+ else if (strcmp(flag_str, "originmask") == 0)
174
+ return EvtSeekOriginMask;
175
+ else if (strcmp(flag_str, "strict") == 0)
176
+ return EvtSeekStrict;
177
+ }
178
+
179
+ static VALUE
180
+ rb_winevt_query_seek(VALUE self, VALUE bookmark_or_flag)
181
+ {
182
+ struct WinevtQuery *winevtQuery;
183
+ struct WinevtBookmark *winevtBookmark = NULL;
184
+ DWORD status;
185
+ DWORD flag;
186
+
187
+ switch (TYPE(bookmark_or_flag)) {
188
+ case T_SYMBOL:
189
+ flag = get_evt_seek_flag_from_cstr(RSTRING_PTR(rb_sym2str(bookmark_or_flag)));
190
+ break;
191
+ case T_STRING:
192
+ flag = get_evt_seek_flag_from_cstr(StringValueCStr(bookmark_or_flag));
193
+ break;
194
+ default:
195
+ if (!rb_obj_is_kind_of(bookmark_or_flag, rb_cBookmark))
196
+ rb_raise(rb_eArgError, "Expected a String or a Symbol or a Bookmark instance");
197
+
198
+ winevtBookmark = EventBookMark(bookmark_or_flag);
199
+ }
200
+
201
+ if (winevtBookmark) {
202
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
203
+ if (EvtSeek(winevtQuery->query, winevtQuery->offset, winevtBookmark->bookmark, winevtQuery->timeout, EvtSeekRelativeToBookmark))
204
+ return Qtrue;
205
+ } else {
206
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
207
+ if (EvtSeek(winevtQuery->query, winevtQuery->offset, NULL, winevtQuery->timeout, flag))
208
+ return Qtrue;
209
+ }
210
+
211
+ return Qfalse;
212
+ }
213
+
214
+ static VALUE
215
+ rb_winevt_query_each(VALUE self)
216
+ {
217
+ struct WinevtQuery *winevtQuery;
218
+
219
+ RETURN_ENUMERATOR(self, 0, 0);
220
+
221
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
222
+
223
+ while (rb_winevt_query_next(self)) {
224
+ rb_yield_values(2, rb_winevt_query_render(self), rb_winevt_query_message(self));
225
+ }
226
+
227
+ return Qnil;
228
+ }
229
+
230
+ void Init_winevt_query(VALUE rb_cEventLog)
231
+ {
232
+ rb_cQuery = rb_define_class_under(rb_cEventLog, "Query", rb_cObject);
233
+
234
+ rb_define_alloc_func(rb_cQuery, rb_winevt_query_alloc);
235
+ rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, 2);
236
+ rb_define_method(rb_cQuery, "next", rb_winevt_query_next, 0);
237
+ rb_define_method(rb_cQuery, "render", rb_winevt_query_render, 0);
238
+ rb_define_method(rb_cQuery, "message", rb_winevt_query_message, 0);
239
+ rb_define_method(rb_cQuery, "seek", rb_winevt_query_seek, 1);
240
+ rb_define_method(rb_cQuery, "offset", rb_winevt_query_get_offset, 0);
241
+ rb_define_method(rb_cQuery, "offset=", rb_winevt_query_set_offset, 1);
242
+ rb_define_method(rb_cQuery, "timeout", rb_winevt_query_get_timeout, 0);
243
+ rb_define_method(rb_cQuery, "timeout=", rb_winevt_query_set_timeout, 1);
244
+ rb_define_method(rb_cQuery, "each", rb_winevt_query_each, 0);
245
+ }