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.
- checksums.yaml +4 -4
- data/.clang-format +5 -0
- data/README.md +2 -2
- data/example/rate_limit.rb +14 -0
- data/ext/winevt/extconf.rb +2 -2
- data/ext/winevt/winevt_bookmark.c +44 -39
- data/ext/winevt/winevt_c.h +42 -26
- data/ext/winevt/winevt_channel.c +43 -29
- data/ext/winevt/winevt_query.c +140 -92
- data/ext/winevt/winevt_subscribe.c +214 -89
- data/ext/winevt/winevt_utils.cpp +540 -335
- data/lib/winevt/version.rb +1 -1
- data/winevt_c.gemspec +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12f9385269dcef7feb299a038947855285d7ffb76d8d331941dfa2d30f56fdb4
|
4
|
+
data.tar.gz: f122b6172ae73587a3a518d79d25a7a64daa735a552fb998cfd5f9e2a5fddc07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92d91fafb48fe5a4cc63ad82a9eca050cac7e2db38538347f6a9c247b5218604360a155233d1f37c38ce9967ca6af46f150fedb0d77c261e201fb99a675c0996
|
7
|
+
data.tar.gz: 5fcc3b81d00788d63380692942fe29822fe6a53d058463ce7848409310abb242a187dfb24414c5cdfc17943d6b57f027a9e1ddbeb2ae03c7eee2594215080eb1
|
data/.clang-format
ADDED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# winevt_c
|
2
2
|
|
3
|
-
[![Build status](https://ci.appveyor.com/api/projects/status/
|
3
|
+
[![Build status](https://ci.appveyor.com/api/projects/status/o5771b3cb6x3acq0/branch/master?svg=true)](https://ci.appveyor.com/project/cosmo0920/winevt-c-6145k/branch/master)
|
4
4
|
|
5
5
|
## Prerequisites
|
6
6
|
|
@@ -35,4 +35,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
35
35
|
|
36
36
|
## Contributing
|
37
37
|
|
38
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
38
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/fluent-plugins-nursery/winevt_c.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'winevt'
|
2
|
+
|
3
|
+
@subscribe = Winevt::EventLog::Subscribe.new
|
4
|
+
@subscribe.tail = true
|
5
|
+
@subscribe.rate_limit = 80
|
6
|
+
@subscribe.subscribe(
|
7
|
+
"Application", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]"
|
8
|
+
)
|
9
|
+
while true do
|
10
|
+
@subscribe.each do |eventlog, message, string_inserts|
|
11
|
+
puts ({eventlog: eventlog, data: message})
|
12
|
+
end
|
13
|
+
sleep(0.1)
|
14
|
+
end
|
data/ext/winevt/extconf.rb
CHANGED
@@ -16,8 +16,8 @@ have_library("advapi32")
|
|
16
16
|
have_library("ole32")
|
17
17
|
|
18
18
|
$LDFLAGS << " -lwevtapi -ladvapi32 -lole32"
|
19
|
-
$CFLAGS << " -std=c99 -fPIC -fms-extensions "
|
20
|
-
$CXXFLAGS << " -std=c++11 -fPIC -fms-extensions "
|
19
|
+
$CFLAGS << " -Wall -std=c99 -fPIC -fms-extensions "
|
20
|
+
$CXXFLAGS << " -Wall -std=c++11 -fPIC -fms-extensions "
|
21
21
|
# $CFLAGS << " -g -O0 -ggdb"
|
22
22
|
# $CXXFLAGS << " -g -O0 -ggdb"
|
23
23
|
|
@@ -1,18 +1,21 @@
|
|
1
1
|
#include <winevt_c.h>
|
2
2
|
|
3
|
-
static void bookmark_free(void
|
4
|
-
|
5
|
-
static const rb_data_type_t rb_winevt_bookmark_type = {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
}
|
3
|
+
static void bookmark_free(void* ptr);
|
4
|
+
|
5
|
+
static const rb_data_type_t rb_winevt_bookmark_type = { "winevt/bookmark",
|
6
|
+
{
|
7
|
+
0,
|
8
|
+
bookmark_free,
|
9
|
+
0,
|
10
|
+
},
|
11
|
+
NULL,
|
12
|
+
NULL,
|
13
|
+
RUBY_TYPED_FREE_IMMEDIATELY };
|
11
14
|
|
12
15
|
static void
|
13
|
-
bookmark_free(void
|
16
|
+
bookmark_free(void* ptr)
|
14
17
|
{
|
15
|
-
struct WinevtBookmark
|
18
|
+
struct WinevtBookmark* winevtBookmark = (struct WinevtBookmark*)ptr;
|
16
19
|
if (winevtBookmark->bookmark)
|
17
20
|
EvtClose(winevtBookmark->bookmark);
|
18
21
|
|
@@ -23,23 +26,22 @@ static VALUE
|
|
23
26
|
rb_winevt_bookmark_alloc(VALUE klass)
|
24
27
|
{
|
25
28
|
VALUE obj;
|
26
|
-
struct WinevtBookmark
|
27
|
-
obj = TypedData_Make_Struct(
|
28
|
-
|
29
|
-
&rb_winevt_bookmark_type,
|
30
|
-
winevtBookmark);
|
29
|
+
struct WinevtBookmark* winevtBookmark;
|
30
|
+
obj = TypedData_Make_Struct(
|
31
|
+
klass, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
|
31
32
|
return obj;
|
32
33
|
}
|
33
34
|
|
34
35
|
static VALUE
|
35
|
-
rb_winevt_bookmark_initialize(int argc, VALUE
|
36
|
+
rb_winevt_bookmark_initialize(int argc, VALUE* argv, VALUE self)
|
36
37
|
{
|
37
38
|
PWSTR bookmarkXml;
|
38
39
|
VALUE wbookmarkXmlBuf;
|
39
40
|
DWORD len;
|
40
|
-
struct WinevtBookmark
|
41
|
+
struct WinevtBookmark* winevtBookmark;
|
41
42
|
|
42
|
-
TypedData_Get_Struct(
|
43
|
+
TypedData_Get_Struct(
|
44
|
+
self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
|
43
45
|
|
44
46
|
if (argc == 0) {
|
45
47
|
winevtBookmark->bookmark = EvtCreateBookmark(NULL);
|
@@ -49,9 +51,15 @@ rb_winevt_bookmark_initialize(int argc, VALUE *argv, VALUE self)
|
|
49
51
|
Check_Type(rb_bookmarkXml, T_STRING);
|
50
52
|
|
51
53
|
// bookmarkXml : To wide char
|
52
|
-
len = MultiByteToWideChar(
|
53
|
-
|
54
|
-
|
54
|
+
len = MultiByteToWideChar(
|
55
|
+
CP_UTF8, 0, RSTRING_PTR(rb_bookmarkXml), RSTRING_LEN(rb_bookmarkXml), NULL, 0);
|
56
|
+
bookmarkXml = ALLOCV_N(WCHAR, wbookmarkXmlBuf, len + 1);
|
57
|
+
MultiByteToWideChar(CP_UTF8,
|
58
|
+
0,
|
59
|
+
RSTRING_PTR(rb_bookmarkXml),
|
60
|
+
RSTRING_LEN(rb_bookmarkXml),
|
61
|
+
bookmarkXml,
|
62
|
+
len);
|
55
63
|
bookmarkXml[len] = L'\0';
|
56
64
|
winevtBookmark->bookmark = EvtCreateBookmark(bookmarkXml);
|
57
65
|
ALLOCV_END(wbookmarkXmlBuf);
|
@@ -63,37 +71,34 @@ rb_winevt_bookmark_initialize(int argc, VALUE *argv, VALUE self)
|
|
63
71
|
static VALUE
|
64
72
|
rb_winevt_bookmark_update(VALUE self, VALUE event)
|
65
73
|
{
|
66
|
-
struct WinevtQuery
|
67
|
-
struct WinevtBookmark
|
74
|
+
struct WinevtQuery* winevtQuery;
|
75
|
+
struct WinevtBookmark* winevtBookmark;
|
68
76
|
|
69
77
|
winevtQuery = EventQuery(event);
|
70
78
|
|
71
|
-
TypedData_Get_Struct(
|
72
|
-
|
73
|
-
if(EvtUpdateBookmark(winevtBookmark->bookmark, winevtQuery->event))
|
74
|
-
return Qtrue;
|
79
|
+
TypedData_Get_Struct(
|
80
|
+
self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
|
75
81
|
|
76
|
-
|
82
|
+
for (int i = 0; i < winevtQuery->count; i++) {
|
83
|
+
if (!EvtUpdateBookmark(winevtBookmark->bookmark, winevtQuery->hEvents[i]))
|
84
|
+
return Qfalse;
|
85
|
+
}
|
86
|
+
return Qtrue;
|
77
87
|
}
|
78
88
|
|
79
89
|
static VALUE
|
80
90
|
rb_winevt_bookmark_render(VALUE self)
|
81
91
|
{
|
82
|
-
|
83
|
-
struct WinevtBookmark *winevtBookmark;
|
84
|
-
VALUE utf8str;
|
85
|
-
|
86
|
-
TypedData_Get_Struct(self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
|
87
|
-
wResult = render_event(winevtBookmark->bookmark, EvtRenderBookmark);
|
88
|
-
utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1);
|
92
|
+
struct WinevtBookmark* winevtBookmark;
|
89
93
|
|
90
|
-
|
91
|
-
|
94
|
+
TypedData_Get_Struct(
|
95
|
+
self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
|
92
96
|
|
93
|
-
return
|
97
|
+
return render_to_rb_str(winevtBookmark->bookmark, EvtRenderBookmark);
|
94
98
|
}
|
95
99
|
|
96
|
-
void
|
100
|
+
void
|
101
|
+
Init_winevt_bookmark(VALUE rb_cEventLog)
|
97
102
|
{
|
98
103
|
rb_cBookmark = rb_define_class_under(rb_cEventLog, "Bookmark", rb_cObject);
|
99
104
|
|
data/ext/winevt/winevt_c.h
CHANGED
@@ -5,67 +5,83 @@
|
|
5
5
|
#include <ruby/encoding.h>
|
6
6
|
|
7
7
|
#ifdef __GNUC__
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#else
|
11
|
-
#
|
12
|
-
#endif
|
8
|
+
#include <w32api.h>
|
9
|
+
#define MINIMUM_WINDOWS_VERSION WindowsVista
|
10
|
+
#else /* __GNUC__ */
|
11
|
+
#define MINIMUM_WINDOWS_VERSION 0x0600 /* Vista */
|
12
|
+
#endif /* __GNUC__ */
|
13
13
|
|
14
14
|
#ifdef _WIN32_WINNT
|
15
|
-
#
|
15
|
+
#undef _WIN32_WINNT
|
16
16
|
#endif /* WIN32_WINNT */
|
17
17
|
#define _WIN32_WINNT MINIMUM_WINDOWS_VERSION
|
18
18
|
|
19
|
+
#include <time.h>
|
19
20
|
#include <winevt.h>
|
20
|
-
#define EventQuery(object) ((struct WinevtQuery
|
21
|
-
#define EventBookMark(object) ((struct WinevtBookmark
|
22
|
-
#define EventChannel(object) ((struct WinevtChannel
|
21
|
+
#define EventQuery(object) ((struct WinevtQuery*)DATA_PTR(object))
|
22
|
+
#define EventBookMark(object) ((struct WinevtBookmark*)DATA_PTR(object))
|
23
|
+
#define EventChannel(object) ((struct WinevtChannel*)DATA_PTR(object))
|
23
24
|
|
24
25
|
#ifdef __cplusplus
|
25
26
|
extern "C" {
|
26
27
|
#endif /* __cplusplus */
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
VALUE wstr_to_rb_str(UINT cp, const WCHAR *wstr, int clen);
|
31
|
-
WCHAR* render_event(EVT_HANDLE handle, DWORD flags);
|
29
|
+
VALUE wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen);
|
30
|
+
VALUE render_to_rb_str(EVT_HANDLE handle, DWORD flags);
|
32
31
|
WCHAR* get_description(EVT_HANDLE handle);
|
33
32
|
VALUE get_values(EVT_HANDLE handle);
|
33
|
+
VALUE render_system_event(EVT_HANDLE handle);
|
34
34
|
|
35
35
|
#ifdef __cplusplus
|
36
36
|
}
|
37
37
|
#endif /* __cplusplus */
|
38
38
|
|
39
39
|
VALUE rb_cQuery;
|
40
|
+
VALUE rb_cFlag;
|
40
41
|
VALUE rb_cChannel;
|
41
42
|
VALUE rb_cBookmark;
|
42
43
|
VALUE rb_cSubscribe;
|
43
44
|
VALUE rb_eWinevtQueryError;
|
44
45
|
|
45
|
-
struct WinevtChannel
|
46
|
+
struct WinevtChannel
|
47
|
+
{
|
46
48
|
EVT_HANDLE channels;
|
47
49
|
};
|
48
50
|
|
49
|
-
struct WinevtBookmark
|
51
|
+
struct WinevtBookmark
|
52
|
+
{
|
50
53
|
EVT_HANDLE bookmark;
|
51
|
-
ULONG
|
54
|
+
ULONG count;
|
52
55
|
};
|
53
56
|
|
54
|
-
|
57
|
+
#define QUERY_ARRAY_SIZE 10
|
58
|
+
|
59
|
+
struct WinevtQuery
|
60
|
+
{
|
55
61
|
EVT_HANDLE query;
|
56
|
-
EVT_HANDLE
|
57
|
-
ULONG
|
58
|
-
LONG
|
59
|
-
LONG
|
62
|
+
EVT_HANDLE hEvents[QUERY_ARRAY_SIZE];
|
63
|
+
ULONG count;
|
64
|
+
LONG offset;
|
65
|
+
LONG timeout;
|
66
|
+
BOOL renderAsXML;
|
60
67
|
};
|
61
68
|
|
62
|
-
|
63
|
-
|
69
|
+
#define SUBSCRIBE_ARRAY_SIZE 10
|
70
|
+
#define SUBSCRIBE_RATE_INFINITE -1
|
71
|
+
|
72
|
+
struct WinevtSubscribe
|
73
|
+
{
|
74
|
+
HANDLE signalEvent;
|
64
75
|
EVT_HANDLE subscription;
|
65
76
|
EVT_HANDLE bookmark;
|
66
|
-
EVT_HANDLE
|
67
|
-
DWORD
|
68
|
-
|
77
|
+
EVT_HANDLE hEvents[SUBSCRIBE_ARRAY_SIZE];
|
78
|
+
DWORD count;
|
79
|
+
DWORD flags;
|
80
|
+
BOOL tailing;
|
81
|
+
DWORD rateLimit;
|
82
|
+
time_t lastTime;
|
83
|
+
DWORD currentRate;
|
84
|
+
BOOL renderAsXML;
|
69
85
|
};
|
70
86
|
|
71
87
|
void Init_winevt_query(VALUE rb_cEventLog);
|
data/ext/winevt/winevt_channel.c
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
#include <winevt_c.h>
|
2
2
|
|
3
|
-
static void channel_free(void
|
4
|
-
|
5
|
-
static const rb_data_type_t rb_winevt_channel_type = {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
}
|
3
|
+
static void channel_free(void* ptr);
|
4
|
+
|
5
|
+
static const rb_data_type_t rb_winevt_channel_type = { "winevt/channel",
|
6
|
+
{
|
7
|
+
0,
|
8
|
+
channel_free,
|
9
|
+
0,
|
10
|
+
},
|
11
|
+
NULL,
|
12
|
+
NULL,
|
13
|
+
RUBY_TYPED_FREE_IMMEDIATELY };
|
11
14
|
|
12
15
|
static void
|
13
|
-
channel_free(void
|
16
|
+
channel_free(void* ptr)
|
14
17
|
{
|
15
|
-
struct WinevtChannel
|
18
|
+
struct WinevtChannel* winevtChannel = (struct WinevtChannel*)ptr;
|
16
19
|
if (winevtChannel->channels)
|
17
20
|
EvtClose(winevtChannel->channels);
|
18
21
|
|
@@ -23,11 +26,9 @@ static VALUE
|
|
23
26
|
rb_winevt_channel_alloc(VALUE klass)
|
24
27
|
{
|
25
28
|
VALUE obj;
|
26
|
-
struct WinevtChannel
|
27
|
-
obj = TypedData_Make_Struct(
|
28
|
-
|
29
|
-
&rb_winevt_channel_type,
|
30
|
-
winevtChannel);
|
29
|
+
struct WinevtChannel* winevtChannel;
|
30
|
+
obj = TypedData_Make_Struct(
|
31
|
+
klass, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
|
31
32
|
return obj;
|
32
33
|
}
|
33
34
|
|
@@ -41,10 +42,9 @@ static VALUE
|
|
41
42
|
rb_winevt_channel_each(VALUE self)
|
42
43
|
{
|
43
44
|
EVT_HANDLE hChannels;
|
44
|
-
struct WinevtChannel
|
45
|
+
struct WinevtChannel* winevtChannel;
|
45
46
|
char errBuf[256];
|
46
47
|
LPWSTR buffer = NULL;
|
47
|
-
LPWSTR temp = NULL;
|
48
48
|
DWORD bufferSize = 0;
|
49
49
|
DWORD bufferUsed = 0;
|
50
50
|
DWORD status = ERROR_SUCCESS;
|
@@ -52,14 +52,19 @@ rb_winevt_channel_each(VALUE self)
|
|
52
52
|
|
53
53
|
RETURN_ENUMERATOR(self, 0, 0);
|
54
54
|
|
55
|
-
TypedData_Get_Struct(
|
55
|
+
TypedData_Get_Struct(
|
56
|
+
self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
|
56
57
|
|
57
58
|
hChannels = EvtOpenChannelEnum(NULL, 0);
|
58
59
|
|
59
60
|
if (hChannels) {
|
60
61
|
winevtChannel->channels = hChannels;
|
61
62
|
} else {
|
62
|
-
_snprintf_s(errBuf,
|
63
|
+
_snprintf_s(errBuf,
|
64
|
+
_countof(errBuf),
|
65
|
+
_TRUNCATE,
|
66
|
+
"Failed to enumerate channels with %lu\n",
|
67
|
+
GetLastError());
|
63
68
|
rb_raise(rb_eRuntimeError, errBuf);
|
64
69
|
}
|
65
70
|
|
@@ -71,40 +76,49 @@ rb_winevt_channel_each(VALUE self)
|
|
71
76
|
break;
|
72
77
|
} else if (ERROR_INSUFFICIENT_BUFFER == status) {
|
73
78
|
bufferSize = bufferUsed;
|
74
|
-
|
75
|
-
if (
|
76
|
-
buffer = temp;
|
77
|
-
temp = NULL;
|
79
|
+
buffer = (LPWSTR)malloc(bufferSize * sizeof(WCHAR));
|
80
|
+
if (buffer) {
|
78
81
|
continue;
|
79
82
|
} else {
|
80
83
|
free(buffer);
|
81
84
|
EvtClose(winevtChannel->channels);
|
82
|
-
|
85
|
+
winevtChannel->channels = NULL;
|
83
86
|
rb_raise(rb_eRuntimeError, "realloc failed");
|
84
87
|
}
|
85
88
|
} else {
|
86
89
|
free(buffer);
|
87
90
|
EvtClose(winevtChannel->channels);
|
88
|
-
|
91
|
+
winevtChannel->channels = NULL;
|
92
|
+
_snprintf_s(errBuf,
|
93
|
+
_countof(errBuf),
|
94
|
+
_TRUNCATE,
|
95
|
+
"EvtNextChannelPath failed with %lu.\n",
|
96
|
+
status);
|
89
97
|
rb_raise(rb_eRuntimeError, errBuf);
|
90
98
|
}
|
91
99
|
}
|
92
100
|
|
93
101
|
utf8str = wstr_to_rb_str(CP_UTF8, buffer, -1);
|
94
102
|
|
103
|
+
free(buffer);
|
104
|
+
buffer = NULL;
|
105
|
+
bufferSize = 0;
|
106
|
+
|
95
107
|
rb_yield(utf8str);
|
96
108
|
}
|
97
109
|
|
98
|
-
if (winevtChannel->channels)
|
110
|
+
if (winevtChannel->channels) {
|
99
111
|
EvtClose(winevtChannel->channels);
|
112
|
+
winevtChannel->channels = NULL;
|
113
|
+
}
|
100
114
|
|
101
|
-
|
102
|
-
free(buffer);
|
115
|
+
free(buffer);
|
103
116
|
|
104
117
|
return Qnil;
|
105
118
|
}
|
106
119
|
|
107
|
-
void
|
120
|
+
void
|
121
|
+
Init_winevt_channel(VALUE rb_cEventLog)
|
108
122
|
{
|
109
123
|
rb_cChannel = rb_define_class_under(rb_cEventLog, "Channel", rb_cObject);
|
110
124
|
rb_define_alloc_func(rb_cChannel, rb_winevt_channel_alloc);
|