winevt_c 0.1.1-x86-mingw32 → 0.2.0-x86-mingw32

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.
@@ -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
+ }