winevt_c 0.7.3 → 0.9.1
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.
- checksums.yaml +4 -4
- data/README.md +55 -0
- data/example/eventlog.rb +5 -1
- data/example/locale.rb +13 -0
- data/example/tailing.rb +7 -1
- data/ext/winevt/winevt.c +7 -0
- data/ext/winevt/winevt_bookmark.c +2 -0
- data/ext/winevt/winevt_c.h +40 -7
- data/ext/winevt/winevt_channel.c +2 -0
- data/ext/winevt/winevt_locale.c +92 -0
- data/ext/winevt/winevt_locale_info.c +68 -0
- data/ext/winevt/winevt_query.c +164 -13
- data/ext/winevt/winevt_session.c +425 -0
- data/ext/winevt/winevt_subscribe.c +173 -15
- data/ext/winevt/winevt_utils.cpp +25 -3
- data/lib/winevt.rb +1 -0
- data/lib/winevt/session.rb +15 -0
- data/lib/winevt/subscribe.rb +5 -2
- data/lib/winevt/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d691ef9954d626041b79d1d63a4258537ded33c0f9c07c9551fd40b6aa211f12
|
4
|
+
data.tar.gz: fbe964ae721b310ca9c9adcf092b0f5ab4f0207e154c41287c17b2a6275932db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90059826d6c9ab0efdce70b7d4c5c4490c69e522fbcaef284e3616aa043b4de63731fe3805c9c4b8837842e44da04f376d8a813b750f926c3ab474c88c332b8c
|
7
|
+
data.tar.gz: 4c75263c161461089b754d512c5d7eaaa9aec9d8e7debeff1d9e0c98c73639f4157f332b5c32ad805b6e3df08e8a330e2e5d76fa85902dc70f133c4e4180ea87
|
data/README.md
CHANGED
@@ -31,6 +31,61 @@ Or install it yourself as:
|
|
31
31
|
## Usage
|
32
32
|
|
33
33
|
Usage examples are found in [example directory](example).
|
34
|
+
|
35
|
+
### Multilingual description
|
36
|
+
|
37
|
+
Currently, the following locales should be supported to output description:
|
38
|
+
|
39
|
+
locale | language
|
40
|
+
---------:|:--------
|
41
|
+
bg\_BG | Bulgarian
|
42
|
+
zh\_CN | Simplified Chinese
|
43
|
+
zh\_TW | Traditional Chinese
|
44
|
+
zh\_HK | Chinese (Hong Kong)
|
45
|
+
zh\_SG | Chinese (Singapore)
|
46
|
+
hr\_HR | Croatian
|
47
|
+
cz\_CZ | Czech
|
48
|
+
da\_DK | Danish
|
49
|
+
nl\_NL | Dutch
|
50
|
+
nl\_BG | Dutch (Belgium)
|
51
|
+
en\_US | English (United States)
|
52
|
+
en\_GB | English (UK)
|
53
|
+
en\_AU | English (Australia)
|
54
|
+
en\_CA | English (Canada)
|
55
|
+
en\_NZ | English (New Zealand)
|
56
|
+
en\_IE | English (Ireland)
|
57
|
+
fi\_FI | Finnish
|
58
|
+
fr\_FR | French
|
59
|
+
fr\_BE | French (Belgium)
|
60
|
+
fr\_CA | French (Canada)
|
61
|
+
fr\_CH | French (Swiss)
|
62
|
+
de\_DE | German
|
63
|
+
de\_CH | German (Swiss)
|
64
|
+
de\_AT | German (Austria)
|
65
|
+
el\_GR | Greek (Ελληνικά)
|
66
|
+
hu\_HU | Hungarian
|
67
|
+
is\_IS | Icelandic
|
68
|
+
it\_IT | Italian (Italy)
|
69
|
+
it\_CH | Italian (Swiss)
|
70
|
+
ja\_JP | Japanese
|
71
|
+
ko\_KO | Korean
|
72
|
+
no\_NO | Norwegian (Bokmål)
|
73
|
+
nb\_NO | Norwegian (Bokmål)
|
74
|
+
nn\_NO | Norwegian (Nynorsk)
|
75
|
+
pl\_PL | Polish (Poland)
|
76
|
+
pt\_PT | Portuguese
|
77
|
+
pt\_BR | Portuguese (Brazil)
|
78
|
+
ro\_RO | Romanian
|
79
|
+
ru\_RU | Russian (русский язык)
|
80
|
+
sk\_SK | Slovak
|
81
|
+
sl\_SI | Slovenian
|
82
|
+
es\_ES | Spanish
|
83
|
+
es\_ES\_T | Spanish (Traditional)
|
84
|
+
es\_MX | Spanish (Mexico)
|
85
|
+
es\_ES\_M | Spanish (Modern)
|
86
|
+
sv\_SE | Swedish
|
87
|
+
tr\_TR | Turkish
|
88
|
+
|
34
89
|
## Development
|
35
90
|
|
36
91
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/example/eventlog.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'winevt'
|
2
2
|
|
3
|
-
@
|
3
|
+
@session = Winevt::EventLog::Session.new("127.0.0.1") # Or remote box ip
|
4
|
+
# @session.domain = "<EXAMPLEGROUP>"
|
5
|
+
# @session.username = "<username>"
|
6
|
+
# @session.password = "<password>"
|
7
|
+
@query = Winevt::EventLog::Query.new("Application", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]", @session)
|
4
8
|
|
5
9
|
@query.render_as_xml = true
|
6
10
|
@query.preserve_qualifiers = true
|
data/example/locale.rb
ADDED
data/example/tailing.rb
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
require 'winevt'
|
2
2
|
|
3
|
+
@session = Winevt::EventLog::Session.new("127.0.0.1") # Or remote box ip
|
4
|
+
# @session.domain = "<EXAMPLEGROUP>"
|
5
|
+
# @session.username = "<username>"
|
6
|
+
# @session.password = "<password>"
|
7
|
+
@bookmark = Winevt::EventLog::Bookmark.new
|
3
8
|
@subscribe = Winevt::EventLog::Subscribe.new
|
4
9
|
@subscribe.read_existing_events = true
|
5
10
|
@subscribe.preserve_qualifiers = true
|
6
11
|
@subscribe.render_as_xml = true
|
7
12
|
@subscribe.subscribe(
|
8
|
-
"Security", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]"
|
13
|
+
"Security", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]",
|
14
|
+
@bookmark, @session
|
9
15
|
)
|
10
16
|
while true do
|
11
17
|
@subscribe.each do |eventlog, message, string_inserts|
|
data/ext/winevt/winevt.c
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
#include <winevt_c.h>
|
2
2
|
|
3
3
|
VALUE rb_mWinevt;
|
4
|
+
VALUE rb_cQuery;
|
4
5
|
VALUE rb_cEventLog;
|
6
|
+
VALUE rb_cSubscribe;
|
7
|
+
VALUE rb_eWinevtQueryError;
|
8
|
+
VALUE rb_eRemoteHandlerError;
|
5
9
|
|
6
10
|
static ID id_call;
|
7
11
|
|
@@ -13,11 +17,14 @@ Init_winevt(void)
|
|
13
17
|
rb_cQuery = rb_define_class_under(rb_cEventLog, "Query", rb_cObject);
|
14
18
|
rb_cSubscribe = rb_define_class_under(rb_cEventLog, "Subscribe", rb_cObject);
|
15
19
|
rb_eWinevtQueryError = rb_define_class_under(rb_cQuery, "Error", rb_eStandardError);
|
20
|
+
rb_eRemoteHandlerError = rb_define_class_under(rb_cSubscribe, "RemoteHandlerError", rb_eRuntimeError);
|
16
21
|
|
17
22
|
Init_winevt_channel(rb_cEventLog);
|
18
23
|
Init_winevt_bookmark(rb_cEventLog);
|
19
24
|
Init_winevt_query(rb_cEventLog);
|
20
25
|
Init_winevt_subscribe(rb_cEventLog);
|
26
|
+
Init_winevt_locale(rb_cEventLog);
|
27
|
+
Init_winevt_session(rb_cEventLog);
|
21
28
|
|
22
29
|
id_call = rb_intern("call");
|
23
30
|
}
|
data/ext/winevt/winevt_c.h
CHANGED
@@ -21,6 +21,13 @@
|
|
21
21
|
#define EventQuery(object) ((struct WinevtQuery*)DATA_PTR(object))
|
22
22
|
#define EventBookMark(object) ((struct WinevtBookmark*)DATA_PTR(object))
|
23
23
|
#define EventChannel(object) ((struct WinevtChannel*)DATA_PTR(object))
|
24
|
+
#define EventSession(object) ((struct WinevtSession*)DATA_PTR(object))
|
25
|
+
|
26
|
+
typedef struct {
|
27
|
+
LANGID langID;
|
28
|
+
CHAR* langCode;
|
29
|
+
CHAR* description;
|
30
|
+
} LocaleInfo;
|
24
31
|
|
25
32
|
#ifdef __cplusplus
|
26
33
|
extern "C" {
|
@@ -32,20 +39,40 @@ VALUE wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen);
|
|
32
39
|
#endif /* __cplusplus */
|
33
40
|
void raise_system_error(VALUE error, DWORD errorCode);
|
34
41
|
VALUE render_to_rb_str(EVT_HANDLE handle, DWORD flags);
|
35
|
-
|
42
|
+
EVT_HANDLE connect_to_remote(LPWSTR computerName, LPWSTR domain,
|
43
|
+
LPWSTR username, LPWSTR password,
|
44
|
+
EVT_RPC_LOGIN_FLAGS flags);
|
45
|
+
WCHAR* get_description(EVT_HANDLE handle, LANGID langID, EVT_HANDLE hRemote);
|
36
46
|
VALUE get_values(EVT_HANDLE handle);
|
37
47
|
VALUE render_system_event(EVT_HANDLE handle, BOOL preserve_qualifiers);
|
48
|
+
LocaleInfo* get_locale_info_from_rb_str(VALUE rb_locale_str);
|
38
49
|
|
39
50
|
#ifdef __cplusplus
|
40
51
|
}
|
41
52
|
#endif /* __cplusplus */
|
42
53
|
|
43
|
-
VALUE rb_cQuery;
|
44
|
-
VALUE rb_cFlag;
|
45
|
-
VALUE rb_cChannel;
|
46
|
-
VALUE rb_cBookmark;
|
47
|
-
VALUE rb_cSubscribe;
|
48
|
-
VALUE rb_eWinevtQueryError;
|
54
|
+
extern VALUE rb_cQuery;
|
55
|
+
extern VALUE rb_cFlag;
|
56
|
+
extern VALUE rb_cChannel;
|
57
|
+
extern VALUE rb_cBookmark;
|
58
|
+
extern VALUE rb_cSubscribe;
|
59
|
+
extern VALUE rb_eWinevtQueryError;
|
60
|
+
extern VALUE rb_eRemoteHandlerError;
|
61
|
+
extern VALUE rb_cLocale;
|
62
|
+
extern VALUE rb_cSession;
|
63
|
+
|
64
|
+
struct WinevtSession {
|
65
|
+
LPWSTR server;
|
66
|
+
LPWSTR domain;
|
67
|
+
LPWSTR username;
|
68
|
+
LPWSTR password;
|
69
|
+
EVT_RPC_LOGIN_FLAGS flags;
|
70
|
+
};
|
71
|
+
|
72
|
+
extern LocaleInfo localeInfoTable[];
|
73
|
+
extern LocaleInfo default_locale;
|
74
|
+
|
75
|
+
struct WinevtLocale {};
|
49
76
|
|
50
77
|
struct WinevtChannel
|
51
78
|
{
|
@@ -70,6 +97,8 @@ struct WinevtQuery
|
|
70
97
|
LONG timeout;
|
71
98
|
BOOL renderAsXML;
|
72
99
|
BOOL preserveQualifiers;
|
100
|
+
LocaleInfo *localeInfo;
|
101
|
+
EVT_HANDLE remoteHandle;
|
73
102
|
};
|
74
103
|
|
75
104
|
#define SUBSCRIBE_ARRAY_SIZE 10
|
@@ -89,11 +118,15 @@ struct WinevtSubscribe
|
|
89
118
|
DWORD currentRate;
|
90
119
|
BOOL renderAsXML;
|
91
120
|
BOOL preserveQualifiers;
|
121
|
+
LocaleInfo* localeInfo;
|
122
|
+
EVT_HANDLE remoteHandle;
|
92
123
|
};
|
93
124
|
|
94
125
|
void Init_winevt_query(VALUE rb_cEventLog);
|
95
126
|
void Init_winevt_channel(VALUE rb_cEventLog);
|
96
127
|
void Init_winevt_bookmark(VALUE rb_cEventLog);
|
97
128
|
void Init_winevt_subscribe(VALUE rb_cEventLog);
|
129
|
+
void Init_winevt_locale(VALUE rb_cEventLog);
|
130
|
+
void Init_winevt_session(VALUE rb_cEventLog);
|
98
131
|
|
99
132
|
#endif // _WINEVT_C_H
|
data/ext/winevt/winevt_channel.c
CHANGED
@@ -19,6 +19,8 @@
|
|
19
19
|
* print channels
|
20
20
|
*/
|
21
21
|
|
22
|
+
VALUE rb_cChannel;
|
23
|
+
|
22
24
|
DWORD is_subscribable_channel_p(EVT_HANDLE hChannel, BOOL force_enumerate);
|
23
25
|
DWORD check_subscribable_with_channel_config_type(int Id, PEVT_VARIANT pProperty, BOOL force_enumerate);
|
24
26
|
static void channel_free(void* ptr);
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#include <winevt_c.h>
|
2
|
+
|
3
|
+
|
4
|
+
/* clang-format off */
|
5
|
+
/*
|
6
|
+
* Document-class: Winevt::EventLog::Locale
|
7
|
+
*
|
8
|
+
* handle locales for Windows EventLog's description.
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* require 'winevt'
|
12
|
+
*
|
13
|
+
* @locale = Winevt::EventLog::Locale.new
|
14
|
+
* @locale.each {|code, desc|
|
15
|
+
* print code, desc
|
16
|
+
* }
|
17
|
+
* @since v0.8.1
|
18
|
+
*/
|
19
|
+
/* clang-format on */
|
20
|
+
|
21
|
+
VALUE rb_cLocale;
|
22
|
+
|
23
|
+
static void locale_free(void* ptr);
|
24
|
+
|
25
|
+
static const rb_data_type_t rb_winevt_locale_type = { "winevt/locale",
|
26
|
+
{
|
27
|
+
0,
|
28
|
+
locale_free,
|
29
|
+
0,
|
30
|
+
},
|
31
|
+
NULL,
|
32
|
+
NULL,
|
33
|
+
RUBY_TYPED_FREE_IMMEDIATELY };
|
34
|
+
|
35
|
+
static void
|
36
|
+
locale_free(void* ptr)
|
37
|
+
{
|
38
|
+
xfree(ptr);
|
39
|
+
}
|
40
|
+
|
41
|
+
static VALUE
|
42
|
+
rb_winevt_locale_alloc(VALUE klass)
|
43
|
+
{
|
44
|
+
VALUE obj;
|
45
|
+
struct WinevtLocale* winevtLocale;
|
46
|
+
obj = TypedData_Make_Struct(
|
47
|
+
klass, struct WinevtLocale, &rb_winevt_locale_type, winevtLocale);
|
48
|
+
return obj;
|
49
|
+
}
|
50
|
+
|
51
|
+
/*
|
52
|
+
* Initalize Locale class.
|
53
|
+
*
|
54
|
+
* @return [Locale]
|
55
|
+
*
|
56
|
+
*/
|
57
|
+
static VALUE
|
58
|
+
rb_winevt_locale_initialize(VALUE self)
|
59
|
+
{
|
60
|
+
return Qnil;
|
61
|
+
}
|
62
|
+
|
63
|
+
/*
|
64
|
+
* Enumerate supported locales and its descriptions
|
65
|
+
*
|
66
|
+
* @yield (String, String)
|
67
|
+
*
|
68
|
+
*/
|
69
|
+
static VALUE
|
70
|
+
rb_winevt_locale_each(VALUE self)
|
71
|
+
{
|
72
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
73
|
+
|
74
|
+
for (int i = 0; localeInfoTable[i].langCode != NULL; i++) {
|
75
|
+
rb_yield_values(2,
|
76
|
+
rb_utf8_str_new_cstr(localeInfoTable[i].langCode),
|
77
|
+
rb_utf8_str_new_cstr(localeInfoTable[i].description));
|
78
|
+
}
|
79
|
+
|
80
|
+
return Qnil;
|
81
|
+
}
|
82
|
+
|
83
|
+
void
|
84
|
+
Init_winevt_locale(VALUE rb_cEventLog)
|
85
|
+
{
|
86
|
+
rb_cLocale = rb_define_class_under(rb_cEventLog, "Locale", rb_cObject);
|
87
|
+
|
88
|
+
rb_define_alloc_func(rb_cLocale, rb_winevt_locale_alloc);
|
89
|
+
|
90
|
+
rb_define_method(rb_cLocale, "initialize", rb_winevt_locale_initialize, 0);
|
91
|
+
rb_define_method(rb_cLocale, "each", rb_winevt_locale_each, 0);
|
92
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#include <winevt_c.h>
|
2
|
+
|
3
|
+
LocaleInfo localeInfoTable [] = {
|
4
|
+
{ MAKELANGID(LANG_BULGARIAN, SUBLANG_DEFAULT), "bg_BG", "Bulgarian"},
|
5
|
+
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), "zh_CN", "Simplified Chinese "},
|
6
|
+
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL), "zh_TW", "Traditional Chinese"},
|
7
|
+
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), "zh_HK", "Chinese (Hong Kong)"},
|
8
|
+
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SINGAPORE), "zh_SG", "Chinese (Singapore)"},
|
9
|
+
{ MAKELANGID(LANG_CROATIAN, SUBLANG_DEFAULT), "hr_HR", "Croatian"},
|
10
|
+
{ MAKELANGID(LANG_CZECH, SUBLANG_DEFAULT), "cs_CZ", "Czech"},
|
11
|
+
{ MAKELANGID(LANG_DANISH, SUBLANG_DEFAULT), "da_DK", "Dannish"},
|
12
|
+
{ MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH), "nl_NL", "Dutch"},
|
13
|
+
{ MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH_BELGIAN), "nl_BE", "Dutch (Belgium)"},
|
14
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), "en_US", "English (United States)"},
|
15
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), "en_GB", "English (UK)"},
|
16
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_AUS), "en_AU", "English (Australia)"},
|
17
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_CAN), "en_CA", "English (Canada)"},
|
18
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_NZ), "en_NZ", "English (New Zealand)"},
|
19
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_EIRE), "en_IE", "English (Ireland)"},
|
20
|
+
{ MAKELANGID(LANG_FINNISH, SUBLANG_DEFAULT), "fi_FI", "Finnish"},
|
21
|
+
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH), "fr_FR", "French"},
|
22
|
+
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH_BELGIAN), "fr_BE", "French (Belgium)"},
|
23
|
+
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH_CANADIAN), "fr_CA", "French (Canada)"},
|
24
|
+
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH_SWISS), "fr_CH", "French (Swiss)"},
|
25
|
+
{ MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), "de_DE", "German"},
|
26
|
+
{ MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN_SWISS), "de_CH", "German (Swiss)"},
|
27
|
+
{ MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN), "de_AT", "German (Austria))"},
|
28
|
+
{ MAKELANGID(LANG_GREEK, SUBLANG_DEFAULT), "el_GR", "Greek (Ελληνικά)"},
|
29
|
+
{ MAKELANGID(LANG_HUNGARIAN, SUBLANG_DEFAULT), "hu_HU", "Hungarian"},
|
30
|
+
{ MAKELANGID(LANG_ICELANDIC, SUBLANG_DEFAULT), "is_IS", "Icelandic"},
|
31
|
+
{ MAKELANGID(LANG_ITALIAN, SUBLANG_ITALIAN), "it_IT", "Italian (Italy)"},
|
32
|
+
{ MAKELANGID(LANG_ITALIAN, SUBLANG_ITALIAN_SWISS), "it_CH", "Italian (Swiss)"},
|
33
|
+
{ MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT), "ja_JP", "Japanases"},
|
34
|
+
{ MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT), "ko_KO", "Korean"},
|
35
|
+
{ MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL), "no_NO", "Norwegian (Bokmål)"},
|
36
|
+
{ MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL), "nb_NO", "Norwegian (Bokmål)"},
|
37
|
+
{ MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_NYNORSK), "nn_NO", "Norwegian (Nynorsk)"},
|
38
|
+
{ MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), "pl_PL", "Polish"},
|
39
|
+
{ MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE), "pt_PT", "Portuguese"},
|
40
|
+
{ MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN), "pt_BR", "Portuguese (Brazil)"},
|
41
|
+
{ MAKELANGID(LANG_ROMANIAN, SUBLANG_DEFAULT), "ro_RO", "Romanian"},
|
42
|
+
{ MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT), "ru_RU", "Russian (русский язык)"},
|
43
|
+
{ MAKELANGID(LANG_SLOVAK, SUBLANG_DEFAULT), "sk_SK", "Slovak"},
|
44
|
+
{ MAKELANGID(LANG_SLOVENIAN, SUBLANG_DEFAULT), "sl_SI", "Slovenian"},
|
45
|
+
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), "es_ES", "Spanish"},
|
46
|
+
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), "es_ES_T", "Spanish (Traditional)"},
|
47
|
+
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MEXICAN), "es_MX", "Spanish (Mexico)"},
|
48
|
+
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), "es_ES_M", "Spanish (Modern)"},
|
49
|
+
{ MAKELANGID(LANG_SWEDISH, SUBLANG_DEFAULT), "sv_SE", "Swedish"},
|
50
|
+
{ MAKELANGID(LANG_TURKISH, SUBLANG_DEFAULT), "tr_TR", "Turkish"},
|
51
|
+
{ 0, NULL, NULL}
|
52
|
+
};
|
53
|
+
|
54
|
+
LocaleInfo default_locale = {MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), "neutral", "Default"};
|
55
|
+
|
56
|
+
LocaleInfo*
|
57
|
+
get_locale_info_from_rb_str(VALUE rb_locale_str)
|
58
|
+
{
|
59
|
+
CHAR* locale_str = StringValuePtr(rb_locale_str);
|
60
|
+
|
61
|
+
for (int i = 0; localeInfoTable[i].langCode != NULL; i++) {
|
62
|
+
if (stricmp(localeInfoTable[i].langCode, locale_str) == 0) {
|
63
|
+
return &localeInfoTable[i];
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
rb_raise(rb_eArgError, "Unknown locale: %s", locale_str);
|
68
|
+
}
|
data/ext/winevt/winevt_query.c
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
*/
|
18
18
|
/* clang-format on */
|
19
19
|
|
20
|
+
VALUE rb_cFlag;
|
20
21
|
|
21
22
|
static void query_free(void* ptr);
|
22
23
|
|
@@ -31,16 +32,32 @@ static const rb_data_type_t rb_winevt_query_type = { "winevt/query",
|
|
31
32
|
RUBY_TYPED_FREE_IMMEDIATELY };
|
32
33
|
|
33
34
|
static void
|
34
|
-
|
35
|
+
close_handles(struct WinevtQuery* winevtQuery)
|
35
36
|
{
|
36
|
-
|
37
|
-
if (winevtQuery->query)
|
37
|
+
if (winevtQuery->query) {
|
38
38
|
EvtClose(winevtQuery->query);
|
39
|
+
winevtQuery->query = NULL;
|
40
|
+
}
|
39
41
|
|
40
42
|
for (int i = 0; i < winevtQuery->count; i++) {
|
41
|
-
if (winevtQuery->hEvents[i])
|
43
|
+
if (winevtQuery->hEvents[i]) {
|
42
44
|
EvtClose(winevtQuery->hEvents[i]);
|
45
|
+
winevtQuery->hEvents[i] = NULL;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
if (winevtQuery->remoteHandle) {
|
50
|
+
EvtClose(winevtQuery->remoteHandle);
|
51
|
+
winevtQuery->remoteHandle = NULL;
|
43
52
|
}
|
53
|
+
}
|
54
|
+
|
55
|
+
static void
|
56
|
+
query_free(void* ptr)
|
57
|
+
{
|
58
|
+
struct WinevtQuery* winevtQuery = (struct WinevtQuery*)ptr;
|
59
|
+
close_handles(winevtQuery);
|
60
|
+
|
44
61
|
xfree(ptr);
|
45
62
|
}
|
46
63
|
|
@@ -57,22 +74,44 @@ rb_winevt_query_alloc(VALUE klass)
|
|
57
74
|
/*
|
58
75
|
* Initalize Query class.
|
59
76
|
*
|
60
|
-
* @
|
61
|
-
*
|
77
|
+
* @overload initialize(channel, xpath, session=nil)
|
78
|
+
* @param channel [String] Querying EventLog channel.
|
79
|
+
* @param xpath [String] Querying XPath.
|
80
|
+
* @param session [Session] Session information for remoting access.
|
62
81
|
* @return [Query]
|
63
82
|
*
|
64
83
|
*/
|
65
84
|
static VALUE
|
66
|
-
rb_winevt_query_initialize(VALUE
|
85
|
+
rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
|
67
86
|
{
|
68
87
|
PWSTR evtChannel, evtXPath;
|
88
|
+
VALUE channel, xpath, session;
|
69
89
|
struct WinevtQuery* winevtQuery;
|
90
|
+
struct WinevtSession* winevtSession;
|
91
|
+
EVT_HANDLE hRemoteHandle = NULL;
|
70
92
|
DWORD len;
|
71
93
|
VALUE wchannelBuf, wpathBuf;
|
94
|
+
DWORD err;
|
72
95
|
|
96
|
+
rb_scan_args(argc, argv, "21", &channel, &xpath, &session);
|
73
97
|
Check_Type(channel, T_STRING);
|
74
98
|
Check_Type(xpath, T_STRING);
|
75
99
|
|
100
|
+
if (rb_obj_is_kind_of(session, rb_cSession)) {
|
101
|
+
winevtSession = EventSession(session);
|
102
|
+
|
103
|
+
hRemoteHandle = connect_to_remote(winevtSession->server,
|
104
|
+
winevtSession->domain,
|
105
|
+
winevtSession->username,
|
106
|
+
winevtSession->password,
|
107
|
+
winevtSession->flags);
|
108
|
+
|
109
|
+
err = GetLastError();
|
110
|
+
if (err != ERROR_SUCCESS) {
|
111
|
+
raise_system_error(rb_eRuntimeError, err);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
76
115
|
// channel : To wide char
|
77
116
|
len =
|
78
117
|
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
|
@@ -90,11 +129,17 @@ rb_winevt_query_initialize(VALUE self, VALUE channel, VALUE xpath)
|
|
90
129
|
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
91
130
|
|
92
131
|
winevtQuery->query = EvtQuery(
|
93
|
-
|
132
|
+
hRemoteHandle, evtChannel, evtXPath, EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
|
133
|
+
err = GetLastError();
|
134
|
+
if (err != ERROR_SUCCESS) {
|
135
|
+
raise_system_error(rb_eRuntimeError, err);
|
136
|
+
}
|
94
137
|
winevtQuery->offset = 0L;
|
95
138
|
winevtQuery->timeout = 0L;
|
96
139
|
winevtQuery->renderAsXML = TRUE;
|
97
140
|
winevtQuery->preserveQualifiers = FALSE;
|
141
|
+
winevtQuery->localeInfo = &default_locale;
|
142
|
+
winevtQuery->remoteHandle = hRemoteHandle;
|
98
143
|
|
99
144
|
ALLOCV_END(wchannelBuf);
|
100
145
|
ALLOCV_END(wpathBuf);
|
@@ -186,6 +231,9 @@ rb_winevt_query_next(VALUE self)
|
|
186
231
|
|
187
232
|
if (!EvtNext(winevtQuery->query, QUERY_ARRAY_SIZE, hEvents, INFINITE, 0, &count)) {
|
188
233
|
status = GetLastError();
|
234
|
+
if (ERROR_CANCELLED == status) {
|
235
|
+
return Qfalse;
|
236
|
+
}
|
189
237
|
if (ERROR_NO_MORE_ITEMS != status) {
|
190
238
|
return Qfalse;
|
191
239
|
}
|
@@ -218,12 +266,12 @@ rb_winevt_query_render(VALUE self, EVT_HANDLE event)
|
|
218
266
|
}
|
219
267
|
|
220
268
|
static VALUE
|
221
|
-
rb_winevt_query_message(EVT_HANDLE event)
|
269
|
+
rb_winevt_query_message(EVT_HANDLE event, LocaleInfo* localeInfo, EVT_HANDLE hRemote)
|
222
270
|
{
|
223
271
|
WCHAR* wResult;
|
224
272
|
VALUE utf8str;
|
225
273
|
|
226
|
-
wResult = get_description(event);
|
274
|
+
wResult = get_description(event, localeInfo->langID, hRemote);
|
227
275
|
utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1);
|
228
276
|
free(wResult);
|
229
277
|
|
@@ -335,7 +383,8 @@ rb_winevt_query_each_yield(VALUE self)
|
|
335
383
|
for (int i = 0; i < winevtQuery->count; i++) {
|
336
384
|
rb_yield_values(3,
|
337
385
|
rb_winevt_query_render(self, winevtQuery->hEvents[i]),
|
338
|
-
rb_winevt_query_message(winevtQuery->hEvents[i]
|
386
|
+
rb_winevt_query_message(winevtQuery->hEvents[i], winevtQuery->localeInfo,
|
387
|
+
winevtQuery->remoteHandle),
|
339
388
|
rb_winevt_query_string_inserts(winevtQuery->hEvents[i]));
|
340
389
|
}
|
341
390
|
return Qnil;
|
@@ -399,7 +448,7 @@ rb_winevt_query_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
|
|
399
448
|
* This method specifies whether preserving qualifiers key or not.
|
400
449
|
*
|
401
450
|
* @since 0.7.3
|
402
|
-
* @param
|
451
|
+
* @param rb_preserve_qualifiers [Boolean]
|
403
452
|
*/
|
404
453
|
static VALUE
|
405
454
|
rb_winevt_query_set_preserve_qualifiers(VALUE self, VALUE rb_preserve_qualifiers)
|
@@ -431,6 +480,92 @@ rb_winevt_query_get_preserve_qualifiers_p(VALUE self)
|
|
431
480
|
return winevtQuery->preserveQualifiers ? Qtrue : Qfalse;
|
432
481
|
}
|
433
482
|
|
483
|
+
/*
|
484
|
+
* This method specifies locale with [String].
|
485
|
+
*
|
486
|
+
* @since 0.8.0
|
487
|
+
* @param rb_locale_str [String]
|
488
|
+
*/
|
489
|
+
static VALUE
|
490
|
+
rb_winevt_query_set_locale(VALUE self, VALUE rb_locale_str)
|
491
|
+
{
|
492
|
+
struct WinevtQuery* winevtQuery;
|
493
|
+
LocaleInfo* locale_info = &default_locale;
|
494
|
+
|
495
|
+
TypedData_Get_Struct(
|
496
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
497
|
+
|
498
|
+
locale_info = get_locale_info_from_rb_str(rb_locale_str);
|
499
|
+
|
500
|
+
winevtQuery->localeInfo = locale_info;
|
501
|
+
|
502
|
+
return Qnil;
|
503
|
+
}
|
504
|
+
|
505
|
+
/*
|
506
|
+
* This method obtains specified locale with [String].
|
507
|
+
*
|
508
|
+
* @since 0.8.0
|
509
|
+
*/
|
510
|
+
static VALUE
|
511
|
+
rb_winevt_query_get_locale(VALUE self)
|
512
|
+
{
|
513
|
+
struct WinevtQuery* winevtQuery;
|
514
|
+
|
515
|
+
TypedData_Get_Struct(
|
516
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
517
|
+
|
518
|
+
if (winevtQuery->localeInfo->langCode) {
|
519
|
+
return rb_str_new2(winevtQuery->localeInfo->langCode);
|
520
|
+
} else {
|
521
|
+
return rb_str_new2(default_locale.langCode);
|
522
|
+
}
|
523
|
+
}
|
524
|
+
|
525
|
+
/*
|
526
|
+
* This method cancels channel query.
|
527
|
+
*
|
528
|
+
* @return [Boolean]
|
529
|
+
* @since 0.9.1
|
530
|
+
*/
|
531
|
+
static VALUE
|
532
|
+
rb_winevt_query_cancel(VALUE self)
|
533
|
+
{
|
534
|
+
struct WinevtQuery* winevtQuery;
|
535
|
+
BOOL result = FALSE;
|
536
|
+
|
537
|
+
TypedData_Get_Struct(
|
538
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
539
|
+
|
540
|
+
if (winevtQuery->query) {
|
541
|
+
result = EvtCancel(winevtQuery->query);
|
542
|
+
}
|
543
|
+
|
544
|
+
if (result) {
|
545
|
+
return Qtrue;
|
546
|
+
} else {
|
547
|
+
return Qfalse;
|
548
|
+
}
|
549
|
+
}
|
550
|
+
|
551
|
+
/*
|
552
|
+
* This method closes channel handles forcibly.
|
553
|
+
*
|
554
|
+
* @since 0.9.1
|
555
|
+
*/
|
556
|
+
static VALUE
|
557
|
+
rb_winevt_query_close(VALUE self)
|
558
|
+
{
|
559
|
+
struct WinevtQuery* winevtQuery;
|
560
|
+
|
561
|
+
TypedData_Get_Struct(
|
562
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
563
|
+
|
564
|
+
close_handles(winevtQuery);
|
565
|
+
|
566
|
+
return Qnil;
|
567
|
+
}
|
568
|
+
|
434
569
|
void
|
435
570
|
Init_winevt_query(VALUE rb_cEventLog)
|
436
571
|
{
|
@@ -478,7 +613,7 @@ Init_winevt_query(VALUE rb_cEventLog)
|
|
478
613
|
rb_define_const(rb_cFlag, "Strict", LONG2NUM(EvtSeekStrict));
|
479
614
|
/* clang-format on */
|
480
615
|
|
481
|
-
rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize,
|
616
|
+
rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, -1);
|
482
617
|
rb_define_method(rb_cQuery, "next", rb_winevt_query_next, 0);
|
483
618
|
rb_define_method(rb_cQuery, "seek", rb_winevt_query_seek, 1);
|
484
619
|
rb_define_method(rb_cQuery, "offset", rb_winevt_query_get_offset, 0);
|
@@ -496,4 +631,20 @@ Init_winevt_query(VALUE rb_cEventLog)
|
|
496
631
|
* @since 0.7.3
|
497
632
|
*/
|
498
633
|
rb_define_method(rb_cQuery, "preserve_qualifiers=", rb_winevt_query_set_preserve_qualifiers, 1);
|
634
|
+
/*
|
635
|
+
* @since 0.8.0
|
636
|
+
*/
|
637
|
+
rb_define_method(rb_cQuery, "locale", rb_winevt_query_get_locale, 0);
|
638
|
+
/*
|
639
|
+
* @since 0.8.0
|
640
|
+
*/
|
641
|
+
rb_define_method(rb_cQuery, "locale=", rb_winevt_query_set_locale, 1);
|
642
|
+
/*
|
643
|
+
* @since 0.9.1
|
644
|
+
*/
|
645
|
+
rb_define_method(rb_cQuery, "cancel", rb_winevt_query_cancel, 0);
|
646
|
+
/*
|
647
|
+
* @since 0.9.1
|
648
|
+
*/
|
649
|
+
rb_define_method(rb_cQuery, "close", rb_winevt_query_close, 0);
|
499
650
|
}
|