winevt_c 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,92 +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
- }
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
+ }
@@ -1,68 +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
- }
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
+ }
@@ -1,650 +1,650 @@
1
- #include <winevt_c.h>
2
-
3
- /* clang-format off */
4
- /*
5
- * Document-class: Winevt::EventLog::Query
6
- *
7
- * Query Windows EventLog channel.
8
- *
9
- * @example
10
- * require 'winevt'
11
- *
12
- * @query = Winevt::EventLog::Query.new("Application", "*[System[(Level <= 3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]")
13
- *
14
- * @query.each do |eventlog, message, string_inserts|
15
- * puts ({eventlog: eventlog, data: message})
16
- * end
17
- */
18
- /* clang-format on */
19
-
20
- VALUE rb_cFlag;
21
-
22
- static void query_free(void* ptr);
23
-
24
- static const rb_data_type_t rb_winevt_query_type = { "winevt/query",
25
- {
26
- 0,
27
- query_free,
28
- 0,
29
- },
30
- NULL,
31
- NULL,
32
- RUBY_TYPED_FREE_IMMEDIATELY };
33
-
34
- static void
35
- close_handles(struct WinevtQuery* winevtQuery)
36
- {
37
- if (winevtQuery->query) {
38
- EvtClose(winevtQuery->query);
39
- winevtQuery->query = NULL;
40
- }
41
-
42
- for (int i = 0; i < winevtQuery->count; i++) {
43
- if (winevtQuery->hEvents[i]) {
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;
52
- }
53
- }
54
-
55
- static void
56
- query_free(void* ptr)
57
- {
58
- struct WinevtQuery* winevtQuery = (struct WinevtQuery*)ptr;
59
- close_handles(winevtQuery);
60
-
61
- xfree(ptr);
62
- }
63
-
64
- static VALUE
65
- rb_winevt_query_alloc(VALUE klass)
66
- {
67
- VALUE obj;
68
- struct WinevtQuery* winevtQuery;
69
- obj =
70
- TypedData_Make_Struct(klass, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
71
- return obj;
72
- }
73
-
74
- /*
75
- * Initalize Query class.
76
- *
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.
81
- * @return [Query]
82
- *
83
- */
84
- static VALUE
85
- rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
86
- {
87
- PWSTR evtChannel, evtXPath;
88
- VALUE channel, xpath, session;
89
- struct WinevtQuery* winevtQuery;
90
- struct WinevtSession* winevtSession;
91
- EVT_HANDLE hRemoteHandle = NULL;
92
- DWORD len;
93
- VALUE wchannelBuf, wpathBuf;
94
- DWORD err;
95
-
96
- rb_scan_args(argc, argv, "21", &channel, &xpath, &session);
97
- Check_Type(channel, T_STRING);
98
- Check_Type(xpath, T_STRING);
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
-
115
- // channel : To wide char
116
- len =
117
- MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
118
- evtChannel = ALLOCV_N(WCHAR, wchannelBuf, len + 1);
119
- MultiByteToWideChar(
120
- CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), evtChannel, len);
121
- evtChannel[len] = L'\0';
122
-
123
- // xpath : To wide char
124
- len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), NULL, 0);
125
- evtXPath = ALLOCV_N(WCHAR, wpathBuf, len + 1);
126
- MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), evtXPath, len);
127
- evtXPath[len] = L'\0';
128
-
129
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
130
-
131
- winevtQuery->query = EvtQuery(
132
- hRemoteHandle, evtChannel, evtXPath, EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
133
- err = GetLastError();
134
- if (err != ERROR_SUCCESS) {
135
- raise_system_error(rb_eRuntimeError, err);
136
- }
137
- winevtQuery->offset = 0L;
138
- winevtQuery->timeout = 0L;
139
- winevtQuery->renderAsXML = TRUE;
140
- winevtQuery->preserveQualifiers = FALSE;
141
- winevtQuery->localeInfo = &default_locale;
142
- winevtQuery->remoteHandle = hRemoteHandle;
143
-
144
- ALLOCV_END(wchannelBuf);
145
- ALLOCV_END(wpathBuf);
146
-
147
- return Qnil;
148
- }
149
-
150
- /*
151
- * This method returns querying event offset.
152
- *
153
- * @return [Integer]
154
- */
155
- static VALUE
156
- rb_winevt_query_get_offset(VALUE self)
157
- {
158
- struct WinevtQuery* winevtQuery;
159
-
160
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
161
-
162
- return LONG2NUM(winevtQuery->offset);
163
- }
164
-
165
- /*
166
- * This method specifies querying event offset.
167
- *
168
- * @param offset [Integer] offset value
169
- */
170
- static VALUE
171
- rb_winevt_query_set_offset(VALUE self, VALUE offset)
172
- {
173
- struct WinevtQuery* winevtQuery;
174
-
175
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
176
-
177
- winevtQuery->offset = NUM2LONG(offset);
178
-
179
- return Qnil;
180
- }
181
-
182
- /*
183
- * This method returns timeout value.
184
- *
185
- * @return [Integer]
186
- */
187
- static VALUE
188
- rb_winevt_query_get_timeout(VALUE self)
189
- {
190
- struct WinevtQuery* winevtQuery;
191
-
192
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
193
-
194
- return LONG2NUM(winevtQuery->timeout);
195
- }
196
-
197
- /*
198
- * This method specifies timeout value.
199
- *
200
- * @param timeout [Integer] timeout value
201
- */
202
- static VALUE
203
- rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
204
- {
205
- struct WinevtQuery* winevtQuery;
206
-
207
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
208
-
209
- winevtQuery->timeout = NUM2LONG(timeout);
210
-
211
- return Qnil;
212
- }
213
-
214
- /*
215
- * Handle the next values. Since v0.6.0, this method is used for
216
- * testing only. Please use #each instead.
217
- *
218
- * @return [Boolean]
219
- *
220
- * @see each
221
- */
222
- static VALUE
223
- rb_winevt_query_next(VALUE self)
224
- {
225
- EVT_HANDLE hEvents[QUERY_ARRAY_SIZE];
226
- ULONG count;
227
- DWORD status = ERROR_SUCCESS;
228
- struct WinevtQuery* winevtQuery;
229
-
230
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
231
-
232
- if (!EvtNext(winevtQuery->query, QUERY_ARRAY_SIZE, hEvents, INFINITE, 0, &count)) {
233
- status = GetLastError();
234
- if (ERROR_CANCELLED == status) {
235
- return Qfalse;
236
- }
237
- if (ERROR_NO_MORE_ITEMS != status) {
238
- return Qfalse;
239
- }
240
- }
241
-
242
- if (status == ERROR_SUCCESS) {
243
- winevtQuery->count = count;
244
- for (int i = 0; i < count; i++) {
245
- winevtQuery->hEvents[i] = hEvents[i];
246
- }
247
-
248
- return Qtrue;
249
- }
250
-
251
- return Qfalse;
252
- }
253
-
254
- static VALUE
255
- rb_winevt_query_render(VALUE self, EVT_HANDLE event)
256
- {
257
- struct WinevtQuery* winevtQuery;
258
-
259
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
260
-
261
- if (winevtQuery->renderAsXML) {
262
- return render_to_rb_str(event, EvtRenderEventXml);
263
- } else {
264
- return render_system_event(event, winevtQuery->preserveQualifiers);
265
- }
266
- }
267
-
268
- static VALUE
269
- rb_winevt_query_message(EVT_HANDLE event, LocaleInfo* localeInfo, EVT_HANDLE hRemote)
270
- {
271
- WCHAR* wResult;
272
- VALUE utf8str;
273
-
274
- wResult = get_description(event, localeInfo->langID, hRemote);
275
- utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1);
276
- free(wResult);
277
-
278
- return utf8str;
279
- }
280
-
281
- static VALUE
282
- rb_winevt_query_string_inserts(EVT_HANDLE event)
283
- {
284
- return get_values(event);
285
- }
286
-
287
- static DWORD
288
- get_evt_seek_flag_from_cstr(char* flag_str)
289
- {
290
- if (strcmp(flag_str, "first") == 0)
291
- return EvtSeekRelativeToFirst;
292
- else if (strcmp(flag_str, "last") == 0)
293
- return EvtSeekRelativeToLast;
294
- else if (strcmp(flag_str, "current") == 0)
295
- return EvtSeekRelativeToCurrent;
296
- else if (strcmp(flag_str, "bookmark") == 0)
297
- return EvtSeekRelativeToBookmark;
298
- else if (strcmp(flag_str, "originmask") == 0)
299
- return EvtSeekOriginMask;
300
- else if (strcmp(flag_str, "strict") == 0)
301
- return EvtSeekStrict;
302
- else
303
- rb_raise(rb_eArgError, "Unknown seek flag: %s", flag_str);
304
-
305
- return 0;
306
- }
307
-
308
- /*
309
- * This method specifies seek strategy.
310
- *
311
- * @param bookmark_or_flag [Bookmark|Query::Flag]
312
- * @return [Boolean]
313
- */
314
- static VALUE
315
- rb_winevt_query_seek(VALUE self, VALUE bookmark_or_flag)
316
- {
317
- struct WinevtQuery* winevtQuery;
318
- struct WinevtBookmark* winevtBookmark = NULL;
319
- DWORD flag = 0;
320
-
321
- switch (TYPE(bookmark_or_flag)) {
322
- case T_SYMBOL:
323
- flag = get_evt_seek_flag_from_cstr(RSTRING_PTR(rb_sym2str(bookmark_or_flag)));
324
- break;
325
- case T_STRING:
326
- flag = get_evt_seek_flag_from_cstr(StringValueCStr(bookmark_or_flag));
327
- break;
328
- case T_FIXNUM:
329
- flag = NUM2LONG(bookmark_or_flag);
330
- break;
331
- default:
332
- if (!rb_obj_is_kind_of(bookmark_or_flag, rb_cBookmark))
333
- rb_raise(rb_eArgError, "Expected a String or a Symbol or a Bookmark instance");
334
-
335
- winevtBookmark = EventBookMark(bookmark_or_flag);
336
- }
337
-
338
- if (winevtBookmark) {
339
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
340
- if (EvtSeek(winevtQuery->query,
341
- winevtQuery->offset,
342
- winevtBookmark->bookmark,
343
- winevtQuery->timeout,
344
- EvtSeekRelativeToBookmark))
345
- return Qtrue;
346
- } else {
347
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
348
- if (EvtSeek(
349
- winevtQuery->query, winevtQuery->offset, NULL, winevtQuery->timeout, flag)) {
350
- return Qtrue;
351
- }
352
- }
353
-
354
- return Qfalse;
355
- }
356
-
357
- static VALUE
358
- rb_winevt_query_close_handle(VALUE self)
359
- {
360
- struct WinevtQuery* winevtQuery;
361
-
362
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
363
-
364
- for (int i = 0; i < winevtQuery->count; i++) {
365
- if (winevtQuery->hEvents[i] != NULL) {
366
- EvtClose(winevtQuery->hEvents[i]);
367
- winevtQuery->hEvents[i] = NULL;
368
- }
369
- }
370
-
371
- return Qnil;
372
- }
373
-
374
- static VALUE
375
- rb_winevt_query_each_yield(VALUE self)
376
- {
377
- RETURN_ENUMERATOR(self, 0, 0);
378
-
379
- struct WinevtQuery* winevtQuery;
380
-
381
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
382
-
383
- for (int i = 0; i < winevtQuery->count; i++) {
384
- rb_yield_values(3,
385
- rb_winevt_query_render(self, winevtQuery->hEvents[i]),
386
- rb_winevt_query_message(winevtQuery->hEvents[i], winevtQuery->localeInfo,
387
- winevtQuery->remoteHandle),
388
- rb_winevt_query_string_inserts(winevtQuery->hEvents[i]));
389
- }
390
- return Qnil;
391
- }
392
-
393
- /*
394
- * Enumerate to obtain Windows EventLog contents.
395
- *
396
- * This method yields the following:
397
- * (Stringified EventLog, Stringified detail message, Stringified
398
- * insert values)
399
- *
400
- * @yield (String,String,String)
401
- *
402
- */
403
- static VALUE
404
- rb_winevt_query_each(VALUE self)
405
- {
406
- RETURN_ENUMERATOR(self, 0, 0);
407
-
408
- while (rb_winevt_query_next(self)) {
409
- rb_ensure(rb_winevt_query_each_yield, self, rb_winevt_query_close_handle, self);
410
- }
411
-
412
- return Qnil;
413
- }
414
-
415
- /*
416
- * This method returns whether render as xml or not.
417
- *
418
- * @return [Boolean]
419
- */
420
- static VALUE
421
- rb_winevt_query_render_as_xml_p(VALUE self)
422
- {
423
- struct WinevtQuery* winevtQuery;
424
-
425
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
426
-
427
- return winevtQuery->renderAsXML ? Qtrue : Qfalse;
428
- }
429
-
430
- /*
431
- * This method specifies whether render as xml or not.
432
- *
433
- * @param rb_render_as_xml [Boolean]
434
- */
435
- static VALUE
436
- rb_winevt_query_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
437
- {
438
- struct WinevtQuery* winevtQuery;
439
-
440
- TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
441
-
442
- winevtQuery->renderAsXML = RTEST(rb_render_as_xml);
443
-
444
- return Qnil;
445
- }
446
-
447
- /*
448
- * This method specifies whether preserving qualifiers key or not.
449
- *
450
- * @since 0.7.3
451
- * @param rb_preserve_qualifiers [Boolean]
452
- */
453
- static VALUE
454
- rb_winevt_query_set_preserve_qualifiers(VALUE self, VALUE rb_preserve_qualifiers)
455
- {
456
- struct WinevtQuery* winevtQuery;
457
-
458
- TypedData_Get_Struct(
459
- self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
460
-
461
- winevtQuery->preserveQualifiers = RTEST(rb_preserve_qualifiers);
462
-
463
- return Qnil;
464
- }
465
-
466
- /*
467
- * This method returns whether preserving qualifiers or not.
468
- *
469
- * @since 0.7.3
470
- * @return [Integer]
471
- */
472
- static VALUE
473
- rb_winevt_query_get_preserve_qualifiers_p(VALUE self)
474
- {
475
- struct WinevtQuery* winevtQuery;
476
-
477
- TypedData_Get_Struct(
478
- self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
479
-
480
- return winevtQuery->preserveQualifiers ? Qtrue : Qfalse;
481
- }
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
-
569
- void
570
- Init_winevt_query(VALUE rb_cEventLog)
571
- {
572
- rb_cQuery = rb_define_class_under(rb_cEventLog, "Query", rb_cObject);
573
- rb_define_alloc_func(rb_cQuery, rb_winevt_query_alloc);
574
-
575
- rb_cFlag = rb_define_module_under(rb_cQuery, "Flag");
576
-
577
- /* clang-format off */
578
- /*
579
- * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToFirst
580
- * @since 0.6.0
581
- * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToFirst
582
- */
583
- rb_define_const(rb_cFlag, "RelativeToFirst", LONG2NUM(EvtSeekRelativeToFirst));
584
- /*
585
- * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToLast
586
- * @since 0.6.0
587
- * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToLast
588
- */
589
- rb_define_const(rb_cFlag, "RelativeToLast", LONG2NUM(EvtSeekRelativeToLast));
590
- /*
591
- * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToCurrent
592
- * @since 0.6.0
593
- * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToCurrent
594
- */
595
- rb_define_const(rb_cFlag, "RelativeToCurrent", LONG2NUM(EvtSeekRelativeToCurrent));
596
- /*
597
- * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToBookmark
598
- * @since 0.6.0
599
- * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToBookmark
600
- */
601
- rb_define_const(rb_cFlag, "RelativeToBookmark", LONG2NUM(EvtSeekRelativeToBookmark));
602
- /*
603
- * EVT_SEEK_FLAGS enumeration: EvtSeekOriginMask
604
- * @since 0.6.0
605
- * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekOriginMask
606
- */
607
- rb_define_const(rb_cFlag, "OriginMask", LONG2NUM(EvtSeekOriginMask));
608
- /*
609
- * EVT_SEEK_FLAGS enumeration: EvtSeekStrict
610
- * @since 0.6.0
611
- * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekStrict
612
- */
613
- rb_define_const(rb_cFlag, "Strict", LONG2NUM(EvtSeekStrict));
614
- /* clang-format on */
615
-
616
- rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, -1);
617
- rb_define_method(rb_cQuery, "next", rb_winevt_query_next, 0);
618
- rb_define_method(rb_cQuery, "seek", rb_winevt_query_seek, 1);
619
- rb_define_method(rb_cQuery, "offset", rb_winevt_query_get_offset, 0);
620
- rb_define_method(rb_cQuery, "offset=", rb_winevt_query_set_offset, 1);
621
- rb_define_method(rb_cQuery, "timeout", rb_winevt_query_get_timeout, 0);
622
- rb_define_method(rb_cQuery, "timeout=", rb_winevt_query_set_timeout, 1);
623
- rb_define_method(rb_cQuery, "each", rb_winevt_query_each, 0);
624
- rb_define_method(rb_cQuery, "render_as_xml?", rb_winevt_query_render_as_xml_p, 0);
625
- rb_define_method(rb_cQuery, "render_as_xml=", rb_winevt_query_set_render_as_xml, 1);
626
- /*
627
- * @since 0.7.3
628
- */
629
- rb_define_method(rb_cQuery, "preserve_qualifiers?", rb_winevt_query_get_preserve_qualifiers_p, 0);
630
- /*
631
- * @since 0.7.3
632
- */
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);
650
- }
1
+ #include <winevt_c.h>
2
+
3
+ /* clang-format off */
4
+ /*
5
+ * Document-class: Winevt::EventLog::Query
6
+ *
7
+ * Query Windows EventLog channel.
8
+ *
9
+ * @example
10
+ * require 'winevt'
11
+ *
12
+ * @query = Winevt::EventLog::Query.new("Application", "*[System[(Level <= 3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]")
13
+ *
14
+ * @query.each do |eventlog, message, string_inserts|
15
+ * puts ({eventlog: eventlog, data: message})
16
+ * end
17
+ */
18
+ /* clang-format on */
19
+
20
+ VALUE rb_cFlag;
21
+
22
+ static void query_free(void* ptr);
23
+
24
+ static const rb_data_type_t rb_winevt_query_type = { "winevt/query",
25
+ {
26
+ 0,
27
+ query_free,
28
+ 0,
29
+ },
30
+ NULL,
31
+ NULL,
32
+ RUBY_TYPED_FREE_IMMEDIATELY };
33
+
34
+ static void
35
+ close_handles(struct WinevtQuery* winevtQuery)
36
+ {
37
+ if (winevtQuery->query) {
38
+ EvtClose(winevtQuery->query);
39
+ winevtQuery->query = NULL;
40
+ }
41
+
42
+ for (int i = 0; i < winevtQuery->count; i++) {
43
+ if (winevtQuery->hEvents[i]) {
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;
52
+ }
53
+ }
54
+
55
+ static void
56
+ query_free(void* ptr)
57
+ {
58
+ struct WinevtQuery* winevtQuery = (struct WinevtQuery*)ptr;
59
+ close_handles(winevtQuery);
60
+
61
+ xfree(ptr);
62
+ }
63
+
64
+ static VALUE
65
+ rb_winevt_query_alloc(VALUE klass)
66
+ {
67
+ VALUE obj;
68
+ struct WinevtQuery* winevtQuery;
69
+ obj =
70
+ TypedData_Make_Struct(klass, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
71
+ return obj;
72
+ }
73
+
74
+ /*
75
+ * Initalize Query class.
76
+ *
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.
81
+ * @return [Query]
82
+ *
83
+ */
84
+ static VALUE
85
+ rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
86
+ {
87
+ PWSTR evtChannel, evtXPath;
88
+ VALUE channel, xpath, session;
89
+ struct WinevtQuery* winevtQuery;
90
+ struct WinevtSession* winevtSession;
91
+ EVT_HANDLE hRemoteHandle = NULL;
92
+ DWORD len;
93
+ VALUE wchannelBuf, wpathBuf;
94
+ DWORD err;
95
+
96
+ rb_scan_args(argc, argv, "21", &channel, &xpath, &session);
97
+ Check_Type(channel, T_STRING);
98
+ Check_Type(xpath, T_STRING);
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
+
115
+ // channel : To wide char
116
+ len =
117
+ MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
118
+ evtChannel = ALLOCV_N(WCHAR, wchannelBuf, len + 1);
119
+ MultiByteToWideChar(
120
+ CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), evtChannel, len);
121
+ evtChannel[len] = L'\0';
122
+
123
+ // xpath : To wide char
124
+ len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), NULL, 0);
125
+ evtXPath = ALLOCV_N(WCHAR, wpathBuf, len + 1);
126
+ MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), evtXPath, len);
127
+ evtXPath[len] = L'\0';
128
+
129
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
130
+
131
+ winevtQuery->query = EvtQuery(
132
+ hRemoteHandle, evtChannel, evtXPath, EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
133
+ err = GetLastError();
134
+ if (err != ERROR_SUCCESS) {
135
+ raise_system_error(rb_eRuntimeError, err);
136
+ }
137
+ winevtQuery->offset = 0L;
138
+ winevtQuery->timeout = 0L;
139
+ winevtQuery->renderAsXML = TRUE;
140
+ winevtQuery->preserveQualifiers = FALSE;
141
+ winevtQuery->localeInfo = &default_locale;
142
+ winevtQuery->remoteHandle = hRemoteHandle;
143
+
144
+ ALLOCV_END(wchannelBuf);
145
+ ALLOCV_END(wpathBuf);
146
+
147
+ return Qnil;
148
+ }
149
+
150
+ /*
151
+ * This method returns querying event offset.
152
+ *
153
+ * @return [Integer]
154
+ */
155
+ static VALUE
156
+ rb_winevt_query_get_offset(VALUE self)
157
+ {
158
+ struct WinevtQuery* winevtQuery;
159
+
160
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
161
+
162
+ return LONG2NUM(winevtQuery->offset);
163
+ }
164
+
165
+ /*
166
+ * This method specifies querying event offset.
167
+ *
168
+ * @param offset [Integer] offset value
169
+ */
170
+ static VALUE
171
+ rb_winevt_query_set_offset(VALUE self, VALUE offset)
172
+ {
173
+ struct WinevtQuery* winevtQuery;
174
+
175
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
176
+
177
+ winevtQuery->offset = NUM2LONG(offset);
178
+
179
+ return Qnil;
180
+ }
181
+
182
+ /*
183
+ * This method returns timeout value.
184
+ *
185
+ * @return [Integer]
186
+ */
187
+ static VALUE
188
+ rb_winevt_query_get_timeout(VALUE self)
189
+ {
190
+ struct WinevtQuery* winevtQuery;
191
+
192
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
193
+
194
+ return LONG2NUM(winevtQuery->timeout);
195
+ }
196
+
197
+ /*
198
+ * This method specifies timeout value.
199
+ *
200
+ * @param timeout [Integer] timeout value
201
+ */
202
+ static VALUE
203
+ rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
204
+ {
205
+ struct WinevtQuery* winevtQuery;
206
+
207
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
208
+
209
+ winevtQuery->timeout = NUM2LONG(timeout);
210
+
211
+ return Qnil;
212
+ }
213
+
214
+ /*
215
+ * Handle the next values. Since v0.6.0, this method is used for
216
+ * testing only. Please use #each instead.
217
+ *
218
+ * @return [Boolean]
219
+ *
220
+ * @see each
221
+ */
222
+ static VALUE
223
+ rb_winevt_query_next(VALUE self)
224
+ {
225
+ EVT_HANDLE hEvents[QUERY_ARRAY_SIZE];
226
+ ULONG count;
227
+ DWORD status = ERROR_SUCCESS;
228
+ struct WinevtQuery* winevtQuery;
229
+
230
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
231
+
232
+ if (!EvtNext(winevtQuery->query, QUERY_ARRAY_SIZE, hEvents, INFINITE, 0, &count)) {
233
+ status = GetLastError();
234
+ if (ERROR_CANCELLED == status) {
235
+ return Qfalse;
236
+ }
237
+ if (ERROR_NO_MORE_ITEMS != status) {
238
+ return Qfalse;
239
+ }
240
+ }
241
+
242
+ if (status == ERROR_SUCCESS) {
243
+ winevtQuery->count = count;
244
+ for (int i = 0; i < count; i++) {
245
+ winevtQuery->hEvents[i] = hEvents[i];
246
+ }
247
+
248
+ return Qtrue;
249
+ }
250
+
251
+ return Qfalse;
252
+ }
253
+
254
+ static VALUE
255
+ rb_winevt_query_render(VALUE self, EVT_HANDLE event)
256
+ {
257
+ struct WinevtQuery* winevtQuery;
258
+
259
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
260
+
261
+ if (winevtQuery->renderAsXML) {
262
+ return render_to_rb_str(event, EvtRenderEventXml);
263
+ } else {
264
+ return render_system_event(event, winevtQuery->preserveQualifiers);
265
+ }
266
+ }
267
+
268
+ static VALUE
269
+ rb_winevt_query_message(EVT_HANDLE event, LocaleInfo* localeInfo, EVT_HANDLE hRemote)
270
+ {
271
+ WCHAR* wResult;
272
+ VALUE utf8str;
273
+
274
+ wResult = get_description(event, localeInfo->langID, hRemote);
275
+ utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1);
276
+ free(wResult);
277
+
278
+ return utf8str;
279
+ }
280
+
281
+ static VALUE
282
+ rb_winevt_query_string_inserts(EVT_HANDLE event)
283
+ {
284
+ return get_values(event);
285
+ }
286
+
287
+ static DWORD
288
+ get_evt_seek_flag_from_cstr(char* flag_str)
289
+ {
290
+ if (strcmp(flag_str, "first") == 0)
291
+ return EvtSeekRelativeToFirst;
292
+ else if (strcmp(flag_str, "last") == 0)
293
+ return EvtSeekRelativeToLast;
294
+ else if (strcmp(flag_str, "current") == 0)
295
+ return EvtSeekRelativeToCurrent;
296
+ else if (strcmp(flag_str, "bookmark") == 0)
297
+ return EvtSeekRelativeToBookmark;
298
+ else if (strcmp(flag_str, "originmask") == 0)
299
+ return EvtSeekOriginMask;
300
+ else if (strcmp(flag_str, "strict") == 0)
301
+ return EvtSeekStrict;
302
+ else
303
+ rb_raise(rb_eArgError, "Unknown seek flag: %s", flag_str);
304
+
305
+ return 0;
306
+ }
307
+
308
+ /*
309
+ * This method specifies seek strategy.
310
+ *
311
+ * @param bookmark_or_flag [Bookmark|Query::Flag]
312
+ * @return [Boolean]
313
+ */
314
+ static VALUE
315
+ rb_winevt_query_seek(VALUE self, VALUE bookmark_or_flag)
316
+ {
317
+ struct WinevtQuery* winevtQuery;
318
+ struct WinevtBookmark* winevtBookmark = NULL;
319
+ DWORD flag = 0;
320
+
321
+ switch (TYPE(bookmark_or_flag)) {
322
+ case T_SYMBOL:
323
+ flag = get_evt_seek_flag_from_cstr(RSTRING_PTR(rb_sym2str(bookmark_or_flag)));
324
+ break;
325
+ case T_STRING:
326
+ flag = get_evt_seek_flag_from_cstr(StringValueCStr(bookmark_or_flag));
327
+ break;
328
+ case T_FIXNUM:
329
+ flag = NUM2LONG(bookmark_or_flag);
330
+ break;
331
+ default:
332
+ if (!rb_obj_is_kind_of(bookmark_or_flag, rb_cBookmark))
333
+ rb_raise(rb_eArgError, "Expected a String or a Symbol or a Bookmark instance");
334
+
335
+ winevtBookmark = EventBookMark(bookmark_or_flag);
336
+ }
337
+
338
+ if (winevtBookmark) {
339
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
340
+ if (EvtSeek(winevtQuery->query,
341
+ winevtQuery->offset,
342
+ winevtBookmark->bookmark,
343
+ winevtQuery->timeout,
344
+ EvtSeekRelativeToBookmark))
345
+ return Qtrue;
346
+ } else {
347
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
348
+ if (EvtSeek(
349
+ winevtQuery->query, winevtQuery->offset, NULL, winevtQuery->timeout, flag)) {
350
+ return Qtrue;
351
+ }
352
+ }
353
+
354
+ return Qfalse;
355
+ }
356
+
357
+ static VALUE
358
+ rb_winevt_query_close_handle(VALUE self)
359
+ {
360
+ struct WinevtQuery* winevtQuery;
361
+
362
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
363
+
364
+ for (int i = 0; i < winevtQuery->count; i++) {
365
+ if (winevtQuery->hEvents[i] != NULL) {
366
+ EvtClose(winevtQuery->hEvents[i]);
367
+ winevtQuery->hEvents[i] = NULL;
368
+ }
369
+ }
370
+
371
+ return Qnil;
372
+ }
373
+
374
+ static VALUE
375
+ rb_winevt_query_each_yield(VALUE self)
376
+ {
377
+ RETURN_ENUMERATOR(self, 0, 0);
378
+
379
+ struct WinevtQuery* winevtQuery;
380
+
381
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
382
+
383
+ for (int i = 0; i < winevtQuery->count; i++) {
384
+ rb_yield_values(3,
385
+ rb_winevt_query_render(self, winevtQuery->hEvents[i]),
386
+ rb_winevt_query_message(winevtQuery->hEvents[i], winevtQuery->localeInfo,
387
+ winevtQuery->remoteHandle),
388
+ rb_winevt_query_string_inserts(winevtQuery->hEvents[i]));
389
+ }
390
+ return Qnil;
391
+ }
392
+
393
+ /*
394
+ * Enumerate to obtain Windows EventLog contents.
395
+ *
396
+ * This method yields the following:
397
+ * (Stringified EventLog, Stringified detail message, Stringified
398
+ * insert values)
399
+ *
400
+ * @yield (String,String,String)
401
+ *
402
+ */
403
+ static VALUE
404
+ rb_winevt_query_each(VALUE self)
405
+ {
406
+ RETURN_ENUMERATOR(self, 0, 0);
407
+
408
+ while (rb_winevt_query_next(self)) {
409
+ rb_ensure(rb_winevt_query_each_yield, self, rb_winevt_query_close_handle, self);
410
+ }
411
+
412
+ return Qnil;
413
+ }
414
+
415
+ /*
416
+ * This method returns whether render as xml or not.
417
+ *
418
+ * @return [Boolean]
419
+ */
420
+ static VALUE
421
+ rb_winevt_query_render_as_xml_p(VALUE self)
422
+ {
423
+ struct WinevtQuery* winevtQuery;
424
+
425
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
426
+
427
+ return winevtQuery->renderAsXML ? Qtrue : Qfalse;
428
+ }
429
+
430
+ /*
431
+ * This method specifies whether render as xml or not.
432
+ *
433
+ * @param rb_render_as_xml [Boolean]
434
+ */
435
+ static VALUE
436
+ rb_winevt_query_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
437
+ {
438
+ struct WinevtQuery* winevtQuery;
439
+
440
+ TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
441
+
442
+ winevtQuery->renderAsXML = RTEST(rb_render_as_xml);
443
+
444
+ return Qnil;
445
+ }
446
+
447
+ /*
448
+ * This method specifies whether preserving qualifiers key or not.
449
+ *
450
+ * @since 0.7.3
451
+ * @param rb_preserve_qualifiers [Boolean]
452
+ */
453
+ static VALUE
454
+ rb_winevt_query_set_preserve_qualifiers(VALUE self, VALUE rb_preserve_qualifiers)
455
+ {
456
+ struct WinevtQuery* winevtQuery;
457
+
458
+ TypedData_Get_Struct(
459
+ self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
460
+
461
+ winevtQuery->preserveQualifiers = RTEST(rb_preserve_qualifiers);
462
+
463
+ return Qnil;
464
+ }
465
+
466
+ /*
467
+ * This method returns whether preserving qualifiers or not.
468
+ *
469
+ * @since 0.7.3
470
+ * @return [Integer]
471
+ */
472
+ static VALUE
473
+ rb_winevt_query_get_preserve_qualifiers_p(VALUE self)
474
+ {
475
+ struct WinevtQuery* winevtQuery;
476
+
477
+ TypedData_Get_Struct(
478
+ self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
479
+
480
+ return winevtQuery->preserveQualifiers ? Qtrue : Qfalse;
481
+ }
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
+
569
+ void
570
+ Init_winevt_query(VALUE rb_cEventLog)
571
+ {
572
+ rb_cQuery = rb_define_class_under(rb_cEventLog, "Query", rb_cObject);
573
+ rb_define_alloc_func(rb_cQuery, rb_winevt_query_alloc);
574
+
575
+ rb_cFlag = rb_define_module_under(rb_cQuery, "Flag");
576
+
577
+ /* clang-format off */
578
+ /*
579
+ * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToFirst
580
+ * @since 0.6.0
581
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToFirst
582
+ */
583
+ rb_define_const(rb_cFlag, "RelativeToFirst", LONG2NUM(EvtSeekRelativeToFirst));
584
+ /*
585
+ * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToLast
586
+ * @since 0.6.0
587
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToLast
588
+ */
589
+ rb_define_const(rb_cFlag, "RelativeToLast", LONG2NUM(EvtSeekRelativeToLast));
590
+ /*
591
+ * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToCurrent
592
+ * @since 0.6.0
593
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToCurrent
594
+ */
595
+ rb_define_const(rb_cFlag, "RelativeToCurrent", LONG2NUM(EvtSeekRelativeToCurrent));
596
+ /*
597
+ * EVT_SEEK_FLAGS enumeration: EvtSeekRelativeToBookmark
598
+ * @since 0.6.0
599
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekRelativeToBookmark
600
+ */
601
+ rb_define_const(rb_cFlag, "RelativeToBookmark", LONG2NUM(EvtSeekRelativeToBookmark));
602
+ /*
603
+ * EVT_SEEK_FLAGS enumeration: EvtSeekOriginMask
604
+ * @since 0.6.0
605
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekOriginMask
606
+ */
607
+ rb_define_const(rb_cFlag, "OriginMask", LONG2NUM(EvtSeekOriginMask));
608
+ /*
609
+ * EVT_SEEK_FLAGS enumeration: EvtSeekStrict
610
+ * @since 0.6.0
611
+ * @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekStrict
612
+ */
613
+ rb_define_const(rb_cFlag, "Strict", LONG2NUM(EvtSeekStrict));
614
+ /* clang-format on */
615
+
616
+ rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, -1);
617
+ rb_define_method(rb_cQuery, "next", rb_winevt_query_next, 0);
618
+ rb_define_method(rb_cQuery, "seek", rb_winevt_query_seek, 1);
619
+ rb_define_method(rb_cQuery, "offset", rb_winevt_query_get_offset, 0);
620
+ rb_define_method(rb_cQuery, "offset=", rb_winevt_query_set_offset, 1);
621
+ rb_define_method(rb_cQuery, "timeout", rb_winevt_query_get_timeout, 0);
622
+ rb_define_method(rb_cQuery, "timeout=", rb_winevt_query_set_timeout, 1);
623
+ rb_define_method(rb_cQuery, "each", rb_winevt_query_each, 0);
624
+ rb_define_method(rb_cQuery, "render_as_xml?", rb_winevt_query_render_as_xml_p, 0);
625
+ rb_define_method(rb_cQuery, "render_as_xml=", rb_winevt_query_set_render_as_xml, 1);
626
+ /*
627
+ * @since 0.7.3
628
+ */
629
+ rb_define_method(rb_cQuery, "preserve_qualifiers?", rb_winevt_query_get_preserve_qualifiers_p, 0);
630
+ /*
631
+ * @since 0.7.3
632
+ */
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);
650
+ }