winevt_c 0.9.1 → 0.9.2

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