winevt_c 0.7.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +55 -0
- data/Rakefile +1 -1
- data/example/eventlog.rb +7 -1
- data/example/locale.rb +13 -0
- data/example/rate_limit.rb +1 -1
- data/example/tailing.rb +10 -2
- data/ext/winevt/winevt.c +7 -0
- data/ext/winevt/winevt_bookmark.c +2 -0
- data/ext/winevt/winevt_c.h +46 -8
- data/ext/winevt/winevt_channel.c +2 -0
- data/ext/winevt/winevt_locale.c +92 -0
- data/ext/winevt/winevt_locale_info.c +68 -0
- data/ext/winevt/winevt_query.c +138 -9
- data/ext/winevt/winevt_session.c +425 -0
- data/ext/winevt/winevt_subscribe.c +136 -10
- data/ext/winevt/winevt_utils.cpp +42 -8
- data/lib/winevt.rb +1 -0
- data/lib/winevt/session.rb +15 -0
- data/lib/winevt/subscribe.rb +5 -2
- data/lib/winevt/version.rb +1 -1
- data/winevt_c.gemspec +1 -1
- metadata +9 -4
data/ext/winevt/winevt_query.c
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
*/
|
18
18
|
/* clang-format on */
|
19
19
|
|
20
|
+
VALUE rb_cFlag;
|
20
21
|
|
21
22
|
static void query_free(void* ptr);
|
22
23
|
|
@@ -41,6 +42,10 @@ query_free(void* ptr)
|
|
41
42
|
if (winevtQuery->hEvents[i])
|
42
43
|
EvtClose(winevtQuery->hEvents[i]);
|
43
44
|
}
|
45
|
+
|
46
|
+
if (winevtQuery->remoteHandle)
|
47
|
+
EvtClose(winevtQuery->remoteHandle);
|
48
|
+
|
44
49
|
xfree(ptr);
|
45
50
|
}
|
46
51
|
|
@@ -57,22 +62,44 @@ rb_winevt_query_alloc(VALUE klass)
|
|
57
62
|
/*
|
58
63
|
* Initalize Query class.
|
59
64
|
*
|
60
|
-
* @
|
61
|
-
*
|
65
|
+
* @overload initialize(channel, xpath, session=nil)
|
66
|
+
* @param channel [String] Querying EventLog channel.
|
67
|
+
* @param xpath [String] Querying XPath.
|
68
|
+
* @param session [Session] Session information for remoting access.
|
62
69
|
* @return [Query]
|
63
70
|
*
|
64
71
|
*/
|
65
72
|
static VALUE
|
66
|
-
rb_winevt_query_initialize(VALUE
|
73
|
+
rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
|
67
74
|
{
|
68
75
|
PWSTR evtChannel, evtXPath;
|
76
|
+
VALUE channel, xpath, session;
|
69
77
|
struct WinevtQuery* winevtQuery;
|
78
|
+
struct WinevtSession* winevtSession;
|
79
|
+
EVT_HANDLE hRemoteHandle = NULL;
|
70
80
|
DWORD len;
|
71
81
|
VALUE wchannelBuf, wpathBuf;
|
82
|
+
DWORD err;
|
72
83
|
|
84
|
+
rb_scan_args(argc, argv, "21", &channel, &xpath, &session);
|
73
85
|
Check_Type(channel, T_STRING);
|
74
86
|
Check_Type(xpath, T_STRING);
|
75
87
|
|
88
|
+
if (rb_obj_is_kind_of(session, rb_cSession)) {
|
89
|
+
winevtSession = EventSession(session);
|
90
|
+
|
91
|
+
hRemoteHandle = connect_to_remote(winevtSession->server,
|
92
|
+
winevtSession->domain,
|
93
|
+
winevtSession->username,
|
94
|
+
winevtSession->password,
|
95
|
+
winevtSession->flags);
|
96
|
+
|
97
|
+
err = GetLastError();
|
98
|
+
if (err != ERROR_SUCCESS) {
|
99
|
+
raise_system_error(rb_eRuntimeError, err);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
76
103
|
// channel : To wide char
|
77
104
|
len =
|
78
105
|
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
|
@@ -90,10 +117,17 @@ rb_winevt_query_initialize(VALUE self, VALUE channel, VALUE xpath)
|
|
90
117
|
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
91
118
|
|
92
119
|
winevtQuery->query = EvtQuery(
|
93
|
-
|
120
|
+
hRemoteHandle, evtChannel, evtXPath, EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
|
121
|
+
err = GetLastError();
|
122
|
+
if (err != ERROR_SUCCESS) {
|
123
|
+
raise_system_error(rb_eRuntimeError, err);
|
124
|
+
}
|
94
125
|
winevtQuery->offset = 0L;
|
95
126
|
winevtQuery->timeout = 0L;
|
96
127
|
winevtQuery->renderAsXML = TRUE;
|
128
|
+
winevtQuery->preserveQualifiers = FALSE;
|
129
|
+
winevtQuery->localeInfo = &default_locale;
|
130
|
+
winevtQuery->remoteHandle = hRemoteHandle;
|
97
131
|
|
98
132
|
ALLOCV_END(wchannelBuf);
|
99
133
|
ALLOCV_END(wpathBuf);
|
@@ -212,17 +246,17 @@ rb_winevt_query_render(VALUE self, EVT_HANDLE event)
|
|
212
246
|
if (winevtQuery->renderAsXML) {
|
213
247
|
return render_to_rb_str(event, EvtRenderEventXml);
|
214
248
|
} else {
|
215
|
-
return render_system_event(event);
|
249
|
+
return render_system_event(event, winevtQuery->preserveQualifiers);
|
216
250
|
}
|
217
251
|
}
|
218
252
|
|
219
253
|
static VALUE
|
220
|
-
rb_winevt_query_message(EVT_HANDLE event)
|
254
|
+
rb_winevt_query_message(EVT_HANDLE event, LocaleInfo* localeInfo, EVT_HANDLE hRemote)
|
221
255
|
{
|
222
256
|
WCHAR* wResult;
|
223
257
|
VALUE utf8str;
|
224
258
|
|
225
|
-
wResult = get_description(event);
|
259
|
+
wResult = get_description(event, localeInfo->langID, hRemote);
|
226
260
|
utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1);
|
227
261
|
free(wResult);
|
228
262
|
|
@@ -334,7 +368,8 @@ rb_winevt_query_each_yield(VALUE self)
|
|
334
368
|
for (int i = 0; i < winevtQuery->count; i++) {
|
335
369
|
rb_yield_values(3,
|
336
370
|
rb_winevt_query_render(self, winevtQuery->hEvents[i]),
|
337
|
-
rb_winevt_query_message(winevtQuery->hEvents[i]
|
371
|
+
rb_winevt_query_message(winevtQuery->hEvents[i], winevtQuery->localeInfo,
|
372
|
+
winevtQuery->remoteHandle),
|
338
373
|
rb_winevt_query_string_inserts(winevtQuery->hEvents[i]));
|
339
374
|
}
|
340
375
|
return Qnil;
|
@@ -394,6 +429,84 @@ rb_winevt_query_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
|
|
394
429
|
return Qnil;
|
395
430
|
}
|
396
431
|
|
432
|
+
/*
|
433
|
+
* This method specifies whether preserving qualifiers key or not.
|
434
|
+
*
|
435
|
+
* @since 0.7.3
|
436
|
+
* @param rb_preserve_qualifiers [Boolean]
|
437
|
+
*/
|
438
|
+
static VALUE
|
439
|
+
rb_winevt_query_set_preserve_qualifiers(VALUE self, VALUE rb_preserve_qualifiers)
|
440
|
+
{
|
441
|
+
struct WinevtQuery* winevtQuery;
|
442
|
+
|
443
|
+
TypedData_Get_Struct(
|
444
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
445
|
+
|
446
|
+
winevtQuery->preserveQualifiers = RTEST(rb_preserve_qualifiers);
|
447
|
+
|
448
|
+
return Qnil;
|
449
|
+
}
|
450
|
+
|
451
|
+
/*
|
452
|
+
* This method returns whether preserving qualifiers or not.
|
453
|
+
*
|
454
|
+
* @since 0.7.3
|
455
|
+
* @return [Integer]
|
456
|
+
*/
|
457
|
+
static VALUE
|
458
|
+
rb_winevt_query_get_preserve_qualifiers_p(VALUE self)
|
459
|
+
{
|
460
|
+
struct WinevtQuery* winevtQuery;
|
461
|
+
|
462
|
+
TypedData_Get_Struct(
|
463
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
464
|
+
|
465
|
+
return winevtQuery->preserveQualifiers ? Qtrue : Qfalse;
|
466
|
+
}
|
467
|
+
|
468
|
+
/*
|
469
|
+
* This method specifies locale with [String].
|
470
|
+
*
|
471
|
+
* @since 0.8.0
|
472
|
+
* @param rb_locale_str [String]
|
473
|
+
*/
|
474
|
+
static VALUE
|
475
|
+
rb_winevt_query_set_locale(VALUE self, VALUE rb_locale_str)
|
476
|
+
{
|
477
|
+
struct WinevtQuery* winevtQuery;
|
478
|
+
LocaleInfo* locale_info = &default_locale;
|
479
|
+
|
480
|
+
TypedData_Get_Struct(
|
481
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
482
|
+
|
483
|
+
locale_info = get_locale_info_from_rb_str(rb_locale_str);
|
484
|
+
|
485
|
+
winevtQuery->localeInfo = locale_info;
|
486
|
+
|
487
|
+
return Qnil;
|
488
|
+
}
|
489
|
+
|
490
|
+
/*
|
491
|
+
* This method obtains specified locale with [String].
|
492
|
+
*
|
493
|
+
* @since 0.8.0
|
494
|
+
*/
|
495
|
+
static VALUE
|
496
|
+
rb_winevt_query_get_locale(VALUE self)
|
497
|
+
{
|
498
|
+
struct WinevtQuery* winevtQuery;
|
499
|
+
|
500
|
+
TypedData_Get_Struct(
|
501
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
502
|
+
|
503
|
+
if (winevtQuery->localeInfo->langCode) {
|
504
|
+
return rb_str_new2(winevtQuery->localeInfo->langCode);
|
505
|
+
} else {
|
506
|
+
return rb_str_new2(default_locale.langCode);
|
507
|
+
}
|
508
|
+
}
|
509
|
+
|
397
510
|
void
|
398
511
|
Init_winevt_query(VALUE rb_cEventLog)
|
399
512
|
{
|
@@ -441,7 +554,7 @@ Init_winevt_query(VALUE rb_cEventLog)
|
|
441
554
|
rb_define_const(rb_cFlag, "Strict", LONG2NUM(EvtSeekStrict));
|
442
555
|
/* clang-format on */
|
443
556
|
|
444
|
-
rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize,
|
557
|
+
rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, -1);
|
445
558
|
rb_define_method(rb_cQuery, "next", rb_winevt_query_next, 0);
|
446
559
|
rb_define_method(rb_cQuery, "seek", rb_winevt_query_seek, 1);
|
447
560
|
rb_define_method(rb_cQuery, "offset", rb_winevt_query_get_offset, 0);
|
@@ -451,4 +564,20 @@ Init_winevt_query(VALUE rb_cEventLog)
|
|
451
564
|
rb_define_method(rb_cQuery, "each", rb_winevt_query_each, 0);
|
452
565
|
rb_define_method(rb_cQuery, "render_as_xml?", rb_winevt_query_render_as_xml_p, 0);
|
453
566
|
rb_define_method(rb_cQuery, "render_as_xml=", rb_winevt_query_set_render_as_xml, 1);
|
567
|
+
/*
|
568
|
+
* @since 0.7.3
|
569
|
+
*/
|
570
|
+
rb_define_method(rb_cQuery, "preserve_qualifiers?", rb_winevt_query_get_preserve_qualifiers_p, 0);
|
571
|
+
/*
|
572
|
+
* @since 0.7.3
|
573
|
+
*/
|
574
|
+
rb_define_method(rb_cQuery, "preserve_qualifiers=", rb_winevt_query_set_preserve_qualifiers, 1);
|
575
|
+
/*
|
576
|
+
* @since 0.8.0
|
577
|
+
*/
|
578
|
+
rb_define_method(rb_cQuery, "locale", rb_winevt_query_get_locale, 0);
|
579
|
+
/*
|
580
|
+
* @since 0.8.0
|
581
|
+
*/
|
582
|
+
rb_define_method(rb_cQuery, "locale=", rb_winevt_query_set_locale, 1);
|
454
583
|
}
|
@@ -0,0 +1,425 @@
|
|
1
|
+
#include <winevt_c.h>
|
2
|
+
|
3
|
+
/* clang-format off */
|
4
|
+
/*
|
5
|
+
* Document-class: Winevt::EventLog::Session
|
6
|
+
*
|
7
|
+
* Manage Session information for Windows EventLog.
|
8
|
+
*
|
9
|
+
* @example
|
10
|
+
* require 'winevt'
|
11
|
+
*
|
12
|
+
* @session = Winevt::EventLog::Session.new("127.0.0.1")
|
13
|
+
*
|
14
|
+
* @session.domain = "<EXAMPLEGROUP>"
|
15
|
+
* @session.username = "<username>"
|
16
|
+
* @session.password = "<password>"
|
17
|
+
* # Then pass @session veriable into Winevt::EventLog::Query or
|
18
|
+
* # Winevt::EventLog::Subscribe#subscribe
|
19
|
+
* @query = Winevt::EventLog::Query.new(
|
20
|
+
* "Application",
|
21
|
+
* "*[System[(Level <= 3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]",
|
22
|
+
* @session
|
23
|
+
* )
|
24
|
+
* # some stuff.
|
25
|
+
*
|
26
|
+
* @subscribe = Winevt::EventLog::Subscribe.new
|
27
|
+
* @subscribe.subscribe(
|
28
|
+
* "Application",
|
29
|
+
* "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]",
|
30
|
+
* @session
|
31
|
+
* )
|
32
|
+
* # And some stuff.
|
33
|
+
* @since v0.9.0
|
34
|
+
*/
|
35
|
+
/* clang-format on */
|
36
|
+
|
37
|
+
VALUE rb_cSession;
|
38
|
+
VALUE rb_cRpcLoginFlag;
|
39
|
+
|
40
|
+
static void session_free(void* ptr);
|
41
|
+
|
42
|
+
static const rb_data_type_t rb_winevt_session_type = { "winevt/session",
|
43
|
+
{
|
44
|
+
0,
|
45
|
+
session_free,
|
46
|
+
0,
|
47
|
+
},
|
48
|
+
NULL,
|
49
|
+
NULL,
|
50
|
+
RUBY_TYPED_FREE_IMMEDIATELY };
|
51
|
+
|
52
|
+
static void
|
53
|
+
session_free(void* ptr)
|
54
|
+
{
|
55
|
+
struct WinevtSession* winevtSession = (struct WinevtSession*)ptr;
|
56
|
+
|
57
|
+
if (winevtSession->server)
|
58
|
+
free(winevtSession->server);
|
59
|
+
if (winevtSession->domain)
|
60
|
+
free(winevtSession->domain);
|
61
|
+
if (winevtSession->username)
|
62
|
+
free(winevtSession->username);
|
63
|
+
if (winevtSession->password)
|
64
|
+
free(winevtSession->password);
|
65
|
+
|
66
|
+
xfree(ptr);
|
67
|
+
}
|
68
|
+
|
69
|
+
static VALUE
|
70
|
+
rb_winevt_session_alloc(VALUE klass)
|
71
|
+
{
|
72
|
+
VALUE obj;
|
73
|
+
struct WinevtSession* winevtSession;
|
74
|
+
obj = TypedData_Make_Struct(
|
75
|
+
klass, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
76
|
+
return obj;
|
77
|
+
}
|
78
|
+
|
79
|
+
/*
|
80
|
+
* Initalize Session class.
|
81
|
+
*
|
82
|
+
* @overload initialize(server, domain=nil, username=nil, password=nil, flags=Winevt::EventLog::Session::RpcLoginFlag::AuthDefault)
|
83
|
+
* @param server [String] Server ip address or fqdn.
|
84
|
+
* @param domain [String] Domain name.
|
85
|
+
* @param username [String] username on remote server.
|
86
|
+
* @param password [String] Remote server user password.
|
87
|
+
* @param flags [Integer] Flags for authentication method choices.
|
88
|
+
* @return [Session]
|
89
|
+
*
|
90
|
+
*/
|
91
|
+
|
92
|
+
static VALUE
|
93
|
+
rb_winevt_session_initialize(VALUE self)
|
94
|
+
{
|
95
|
+
struct WinevtSession* winevtSession;
|
96
|
+
|
97
|
+
TypedData_Get_Struct(
|
98
|
+
self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
99
|
+
|
100
|
+
winevtSession->server = NULL;
|
101
|
+
winevtSession->domain = NULL;
|
102
|
+
winevtSession->username = NULL;
|
103
|
+
winevtSession->password = NULL;
|
104
|
+
winevtSession->flags = EvtRpcLoginAuthDefault;
|
105
|
+
|
106
|
+
return Qnil;
|
107
|
+
}
|
108
|
+
|
109
|
+
/*
|
110
|
+
* This method returns server for remoting access.
|
111
|
+
*
|
112
|
+
* @return [String]
|
113
|
+
*/
|
114
|
+
static VALUE
|
115
|
+
rb_winevt_session_get_server(VALUE self)
|
116
|
+
{
|
117
|
+
struct WinevtSession* winevtSession;
|
118
|
+
|
119
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
120
|
+
|
121
|
+
if (winevtSession->server) {
|
122
|
+
return wstr_to_rb_str(CP_UTF8, winevtSession->server, -1);
|
123
|
+
} else {
|
124
|
+
return rb_str_new2("(NULL)");
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
/*
|
129
|
+
* This method specifies server for remoting access.
|
130
|
+
*
|
131
|
+
* @param rb_server [String] server
|
132
|
+
*/
|
133
|
+
static VALUE
|
134
|
+
rb_winevt_session_set_server(VALUE self, VALUE rb_server)
|
135
|
+
{
|
136
|
+
struct WinevtSession* winevtSession;
|
137
|
+
DWORD len;
|
138
|
+
VALUE vserverBuf;
|
139
|
+
PWSTR wServer;
|
140
|
+
|
141
|
+
Check_Type(rb_server, T_STRING);
|
142
|
+
|
143
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
144
|
+
|
145
|
+
len =
|
146
|
+
MultiByteToWideChar(CP_UTF8, 0,
|
147
|
+
RSTRING_PTR(rb_server), RSTRING_LEN(rb_server),
|
148
|
+
NULL, 0);
|
149
|
+
wServer = ALLOCV_N(WCHAR, vserverBuf, len + 1);
|
150
|
+
MultiByteToWideChar(CP_UTF8, 0,
|
151
|
+
RSTRING_PTR(rb_server), RSTRING_LEN(rb_server),
|
152
|
+
wServer, len);
|
153
|
+
winevtSession->server = _wcsdup(wServer);
|
154
|
+
wServer[len] = L'\0';
|
155
|
+
|
156
|
+
ALLOCV_END(vserverBuf);
|
157
|
+
|
158
|
+
return Qnil;
|
159
|
+
}
|
160
|
+
|
161
|
+
/*
|
162
|
+
* This method returns domain for remoting access.
|
163
|
+
*
|
164
|
+
* @return [String]
|
165
|
+
*/
|
166
|
+
static VALUE
|
167
|
+
rb_winevt_session_get_domain(VALUE self)
|
168
|
+
{
|
169
|
+
struct WinevtSession* winevtSession;
|
170
|
+
|
171
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
172
|
+
|
173
|
+
if (winevtSession->domain) {
|
174
|
+
return wstr_to_rb_str(CP_UTF8, winevtSession->domain, -1);
|
175
|
+
} else {
|
176
|
+
return rb_str_new2("(NULL)");
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
/*
|
181
|
+
* This method specifies domain for remoting access.
|
182
|
+
*
|
183
|
+
* @param rb_domain [String] domain
|
184
|
+
*/
|
185
|
+
static VALUE
|
186
|
+
rb_winevt_session_set_domain(VALUE self, VALUE rb_domain)
|
187
|
+
{
|
188
|
+
struct WinevtSession* winevtSession;
|
189
|
+
DWORD len;
|
190
|
+
VALUE vdomainBuf;
|
191
|
+
PWSTR wDomain;
|
192
|
+
|
193
|
+
Check_Type(rb_domain, T_STRING);
|
194
|
+
|
195
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
196
|
+
|
197
|
+
len =
|
198
|
+
MultiByteToWideChar(CP_UTF8, 0,
|
199
|
+
RSTRING_PTR(rb_domain), RSTRING_LEN(rb_domain),
|
200
|
+
NULL, 0);
|
201
|
+
wDomain = ALLOCV_N(WCHAR, vdomainBuf, len + 1);
|
202
|
+
MultiByteToWideChar(CP_UTF8, 0,
|
203
|
+
RSTRING_PTR(rb_domain), RSTRING_LEN(rb_domain),
|
204
|
+
wDomain, len);
|
205
|
+
wDomain[len] = L'\0';
|
206
|
+
|
207
|
+
winevtSession->domain = _wcsdup(wDomain);
|
208
|
+
|
209
|
+
ALLOCV_END(vdomainBuf);
|
210
|
+
|
211
|
+
return Qnil;
|
212
|
+
}
|
213
|
+
|
214
|
+
/*
|
215
|
+
* This method returns username for remoting access.
|
216
|
+
*
|
217
|
+
* @return [String]
|
218
|
+
*/
|
219
|
+
static VALUE
|
220
|
+
rb_winevt_session_get_username(VALUE self)
|
221
|
+
{
|
222
|
+
struct WinevtSession* winevtSession;
|
223
|
+
|
224
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
225
|
+
|
226
|
+
if (winevtSession->username) {
|
227
|
+
return wstr_to_rb_str(CP_UTF8, winevtSession->username, -1);
|
228
|
+
} else {
|
229
|
+
return rb_str_new2("(NULL)");
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
/*
|
234
|
+
* This method specifies username for remoting access.
|
235
|
+
*
|
236
|
+
* @param rb_username [String] username
|
237
|
+
*/
|
238
|
+
static VALUE
|
239
|
+
rb_winevt_session_set_username(VALUE self, VALUE rb_username)
|
240
|
+
{
|
241
|
+
struct WinevtSession* winevtSession;
|
242
|
+
DWORD len;
|
243
|
+
VALUE vusernameBuf;
|
244
|
+
PWSTR wUsername;
|
245
|
+
|
246
|
+
Check_Type(rb_username, T_STRING);
|
247
|
+
|
248
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
249
|
+
|
250
|
+
len =
|
251
|
+
MultiByteToWideChar(CP_UTF8, 0,
|
252
|
+
RSTRING_PTR(rb_username), RSTRING_LEN(rb_username),
|
253
|
+
NULL, 0);
|
254
|
+
wUsername = ALLOCV_N(WCHAR, vusernameBuf, len + 1);
|
255
|
+
MultiByteToWideChar(CP_UTF8, 0,
|
256
|
+
RSTRING_PTR(rb_username), RSTRING_LEN(rb_username),
|
257
|
+
wUsername, len);
|
258
|
+
wUsername[len] = L'\0';
|
259
|
+
|
260
|
+
winevtSession->username = _wcsdup(wUsername);
|
261
|
+
|
262
|
+
ALLOCV_END(vusernameBuf);
|
263
|
+
|
264
|
+
return Qnil;
|
265
|
+
}
|
266
|
+
|
267
|
+
/*
|
268
|
+
* This method returns password for remoting access.
|
269
|
+
*
|
270
|
+
* @return [String]
|
271
|
+
*/
|
272
|
+
static VALUE
|
273
|
+
rb_winevt_session_get_password(VALUE self)
|
274
|
+
{
|
275
|
+
struct WinevtSession* winevtSession;
|
276
|
+
|
277
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
278
|
+
|
279
|
+
if (winevtSession->password) {
|
280
|
+
return wstr_to_rb_str(CP_UTF8, winevtSession->password, -1);
|
281
|
+
} else {
|
282
|
+
return rb_str_new2("(NULL)");
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
/*
|
287
|
+
* This method specifies password for remoting access.
|
288
|
+
*
|
289
|
+
* @param rb_password [String] password
|
290
|
+
*/
|
291
|
+
static VALUE
|
292
|
+
rb_winevt_session_set_password(VALUE self, VALUE rb_password)
|
293
|
+
{
|
294
|
+
struct WinevtSession* winevtSession;
|
295
|
+
DWORD len;
|
296
|
+
VALUE vpasswordBuf;
|
297
|
+
PWSTR wPassword;
|
298
|
+
|
299
|
+
Check_Type(rb_password, T_STRING);
|
300
|
+
|
301
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
302
|
+
|
303
|
+
len =
|
304
|
+
MultiByteToWideChar(CP_UTF8, 0,
|
305
|
+
RSTRING_PTR(rb_password), RSTRING_LEN(rb_password),
|
306
|
+
NULL, 0);
|
307
|
+
wPassword = ALLOCV_N(WCHAR, vpasswordBuf, len + 1);
|
308
|
+
MultiByteToWideChar(CP_UTF8, 0,
|
309
|
+
RSTRING_PTR(rb_password), RSTRING_LEN(rb_password),
|
310
|
+
wPassword, len);
|
311
|
+
wPassword[len] = L'\0';
|
312
|
+
|
313
|
+
winevtSession->password = _wcsdup(wPassword);
|
314
|
+
|
315
|
+
ALLOCV_END(vpasswordBuf);
|
316
|
+
|
317
|
+
return Qnil;
|
318
|
+
}
|
319
|
+
|
320
|
+
/*
|
321
|
+
* This method returns flags for remoting access.
|
322
|
+
*
|
323
|
+
* @return [Integer]
|
324
|
+
*/
|
325
|
+
static VALUE
|
326
|
+
rb_winevt_session_get_flags(VALUE self)
|
327
|
+
{
|
328
|
+
struct WinevtSession* winevtSession;
|
329
|
+
|
330
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
331
|
+
|
332
|
+
return LONG2NUM(winevtSession->flags);
|
333
|
+
}
|
334
|
+
|
335
|
+
static DWORD
|
336
|
+
get_session_rpc_login_flag_from_cstr(char* flag_str)
|
337
|
+
{
|
338
|
+
if (strcmp(flag_str, "default") == 0)
|
339
|
+
return EvtRpcLoginAuthDefault;
|
340
|
+
else if (strcmp(flag_str, "negociate") == 0)
|
341
|
+
return EvtRpcLoginAuthNegotiate;
|
342
|
+
else if (strcmp(flag_str, "kerberos") == 0)
|
343
|
+
return EvtRpcLoginAuthKerberos;
|
344
|
+
else if (strcmp(flag_str, "ntlm") == 0)
|
345
|
+
return EvtRpcLoginAuthNTLM;
|
346
|
+
else
|
347
|
+
rb_raise(rb_eArgError, "Unknown rpc login flag: %s", flag_str);
|
348
|
+
|
349
|
+
return 0;
|
350
|
+
}
|
351
|
+
|
352
|
+
|
353
|
+
/*
|
354
|
+
* This method specifies flags for remoting access.
|
355
|
+
*
|
356
|
+
* @param rb_flags [Integer] flags
|
357
|
+
*/
|
358
|
+
static VALUE
|
359
|
+
rb_winevt_session_set_flags(VALUE self, VALUE rb_flags)
|
360
|
+
{
|
361
|
+
struct WinevtSession* winevtSession;
|
362
|
+
EVT_RPC_LOGIN_FLAGS flags = EvtRpcLoginAuthDefault;
|
363
|
+
|
364
|
+
TypedData_Get_Struct(self, struct WinevtSession, &rb_winevt_session_type, winevtSession);
|
365
|
+
|
366
|
+
switch(TYPE(rb_flags)) {
|
367
|
+
case T_SYMBOL:
|
368
|
+
flags = get_session_rpc_login_flag_from_cstr(RSTRING_PTR(rb_sym2str(rb_flags)));
|
369
|
+
break;
|
370
|
+
case T_STRING:
|
371
|
+
flags = get_session_rpc_login_flag_from_cstr(StringValuePtr(rb_flags));
|
372
|
+
break;
|
373
|
+
case T_FIXNUM:
|
374
|
+
flags = NUM2LONG(rb_flags);
|
375
|
+
break;
|
376
|
+
default:
|
377
|
+
rb_raise(rb_eArgError, "Expected Symbol, String or Fixnum in flags");
|
378
|
+
}
|
379
|
+
winevtSession->flags = flags;
|
380
|
+
|
381
|
+
return Qnil;
|
382
|
+
}
|
383
|
+
|
384
|
+
void
|
385
|
+
Init_winevt_session(VALUE rb_cEventLog)
|
386
|
+
{
|
387
|
+
rb_cSession = rb_define_class_under(rb_cEventLog, "Session", rb_cObject);
|
388
|
+
|
389
|
+
rb_define_alloc_func(rb_cSession, rb_winevt_session_alloc);
|
390
|
+
|
391
|
+
rb_cRpcLoginFlag = rb_define_module_under(rb_cSession, "RpcLoginFlag");
|
392
|
+
|
393
|
+
rb_define_method(rb_cSession, "initialize", rb_winevt_session_initialize, 0);
|
394
|
+
rb_define_method(rb_cSession, "server", rb_winevt_session_get_server, 0);
|
395
|
+
rb_define_method(rb_cSession, "server=", rb_winevt_session_set_server, 1);
|
396
|
+
rb_define_method(rb_cSession, "domain", rb_winevt_session_get_domain, 0);
|
397
|
+
rb_define_method(rb_cSession, "domain=", rb_winevt_session_set_domain, 1);
|
398
|
+
rb_define_method(rb_cSession, "username", rb_winevt_session_get_username, 0);
|
399
|
+
rb_define_method(rb_cSession, "username=", rb_winevt_session_set_username, 1);
|
400
|
+
rb_define_method(rb_cSession, "password", rb_winevt_session_get_password, 0);
|
401
|
+
rb_define_method(rb_cSession, "password=", rb_winevt_session_set_password, 1);
|
402
|
+
rb_define_method(rb_cSession, "flags", rb_winevt_session_get_flags, 0);
|
403
|
+
rb_define_method(rb_cSession, "flags=", rb_winevt_session_set_flags, 1);
|
404
|
+
|
405
|
+
/*
|
406
|
+
* EVT_RPC_LOGIN_FLAGS enumeration: EvtRpcLoginAuthDefault
|
407
|
+
* @see https://docs.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_rpc_login_flags
|
408
|
+
*/
|
409
|
+
rb_define_const(rb_cRpcLoginFlag, "AuthDefault", LONG2NUM(EvtRpcLoginAuthDefault));
|
410
|
+
/*
|
411
|
+
* EVT_RPC_LOGIN_FLAGS enumeration: EvtRpcLoginAuthNegociate
|
412
|
+
* @see https://docs.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_rpc_login_flags
|
413
|
+
*/
|
414
|
+
rb_define_const(rb_cRpcLoginFlag, "AuthNegociate", LONG2NUM(EvtRpcLoginAuthNegotiate));
|
415
|
+
/*
|
416
|
+
* EVT_RPC_LOGIN_FLAGS enumeration: EvtRpcLoginAuthKerberos
|
417
|
+
* @see https://docs.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_rpc_login_flags
|
418
|
+
*/
|
419
|
+
rb_define_const(rb_cRpcLoginFlag, "AuthKerberos", LONG2NUM(EvtRpcLoginAuthKerberos));
|
420
|
+
/*
|
421
|
+
* EVT_RPC_LOGIN_FLAGS enumeration: EvtRpcLoginAuthNTLM
|
422
|
+
* @see https://docs.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_rpc_login_flags
|
423
|
+
*/
|
424
|
+
rb_define_const(rb_cRpcLoginFlag, "AuthNTLM", LONG2NUM(EvtRpcLoginAuthNTLM));
|
425
|
+
}
|