winevt_c 0.10.2 → 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/appveyor.yml +6 -1
- data/ext/winevt/extconf.rb +3 -0
- data/ext/winevt/winevt_c.h +11 -1
- data/ext/winevt/winevt_query.c +91 -5
- data/ext/winevt/winevt_subscribe.c +45 -1
- data/ext/winevt/winevt_utils.cpp +127 -17
- data/lib/winevt/version.rb +1 -1
- data/ruby_install.ps1 +92 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 236cd5f44b0a13dd198baa83329a340742ae4e9ff618d01671cb48326e4da0c9
|
4
|
+
data.tar.gz: 26cfad4e5eede9d60710672dabe47a61db41cc2d21861704fb94f00ea2c6c51f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '081e7c41f48447bbb401c5a8483094b3258a521a97a7b301b44ac89d216d888cece8ab1f89406b8fafc694436574c2660f600cec9c053f098cb81e3d05d311d4'
|
7
|
+
data.tar.gz: 4e5eb1006bd0e05d59bdfb361edf02025b1ab86a6f7fc66d9489b27b29cdf530f47a404ae8b8c17f32d167b44cddaa28d5bd89e58cef4a93cec65dfe486c6eb1
|
data/appveyor.yml
CHANGED
@@ -38,11 +38,16 @@ for:
|
|
38
38
|
matrix:
|
39
39
|
only:
|
40
40
|
- ruby_version: "31-x64"
|
41
|
+
- ruby_version: "27-x64"
|
42
|
+
- ruby_version: "27"
|
43
|
+
- ruby_version: "26-x64"
|
44
|
+
- ruby_version: "26"
|
41
45
|
install:
|
46
|
+
- ps: if ($ENV:ruby_version -ne "31-x64") { .\ruby_install.ps1 }
|
42
47
|
- SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
|
43
48
|
- ruby --version
|
44
49
|
- gem --version
|
45
50
|
- bundle --version
|
46
|
-
- ridk.
|
51
|
+
- ps: if ($ENV:ruby_version -eq "31-x64") { ridk.ps1 install 1 3 }
|
47
52
|
- ridk.cmd exec bundle install
|
48
53
|
- ridk.cmd exec bundle exec rake compile
|
data/ext/winevt/extconf.rb
CHANGED
@@ -14,6 +14,9 @@ have_library("wevtapi")
|
|
14
14
|
have_func("EvtQuery", "winevt.h")
|
15
15
|
have_library("advapi32")
|
16
16
|
have_library("ole32")
|
17
|
+
if have_macro("RB_ALLOCV")
|
18
|
+
$CFLAGS << " -DHAVE_RB_ALLOCV=1 "
|
19
|
+
end
|
17
20
|
|
18
21
|
$LDFLAGS << " -lwevtapi -ladvapi32 -lole32"
|
19
22
|
$CFLAGS << " -Wall -std=c99 -fPIC -fms-extensions "
|
data/ext/winevt/winevt_c.h
CHANGED
@@ -16,6 +16,11 @@
|
|
16
16
|
#endif /* WIN32_WINNT */
|
17
17
|
#define _WIN32_WINNT MINIMUM_WINDOWS_VERSION
|
18
18
|
|
19
|
+
#if !defined(HAVE_RB_ALLOCV)
|
20
|
+
#define ALLOCV RB_ALLOCV
|
21
|
+
#define ALLOCV_N RB_ALLOCV_N
|
22
|
+
#endif
|
23
|
+
|
19
24
|
#include <time.h>
|
20
25
|
#include <winevt.h>
|
21
26
|
#define EventQuery(object) ((struct WinevtQuery*)DATA_PTR(object))
|
@@ -33,6 +38,9 @@ typedef struct {
|
|
33
38
|
extern "C" {
|
34
39
|
#endif /* __cplusplus */
|
35
40
|
|
41
|
+
#define WINEVT_UTILS_ERROR_NONE_MAPPED -1
|
42
|
+
#define WINEVT_UTILS_ERROR_OTHERS -2
|
43
|
+
|
36
44
|
VALUE wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen);
|
37
45
|
#if defined(__cplusplus)
|
38
46
|
[[ noreturn ]]
|
@@ -46,7 +54,7 @@ EVT_HANDLE connect_to_remote(LPWSTR computerName, LPWSTR domain,
|
|
46
54
|
DWORD *error_code);
|
47
55
|
WCHAR* get_description(EVT_HANDLE handle, LANGID langID, EVT_HANDLE hRemote);
|
48
56
|
VALUE get_values(EVT_HANDLE handle);
|
49
|
-
VALUE render_system_event(EVT_HANDLE handle, BOOL preserve_qualifiers);
|
57
|
+
VALUE render_system_event(EVT_HANDLE handle, BOOL preserve_qualifiers, BOOL preserveSID);
|
50
58
|
LocaleInfo* get_locale_info_from_rb_str(VALUE rb_locale_str);
|
51
59
|
|
52
60
|
#ifdef __cplusplus
|
@@ -101,6 +109,7 @@ struct WinevtQuery
|
|
101
109
|
LONG timeout;
|
102
110
|
BOOL renderAsXML;
|
103
111
|
BOOL preserveQualifiers;
|
112
|
+
BOOL preserveSID;
|
104
113
|
LocaleInfo *localeInfo;
|
105
114
|
EVT_HANDLE remoteHandle;
|
106
115
|
};
|
@@ -122,6 +131,7 @@ struct WinevtSubscribe
|
|
122
131
|
DWORD currentRate;
|
123
132
|
BOOL renderAsXML;
|
124
133
|
BOOL preserveQualifiers;
|
134
|
+
BOOL preserveSID;
|
125
135
|
LocaleInfo* localeInfo;
|
126
136
|
EVT_HANDLE remoteHandle;
|
127
137
|
};
|
data/ext/winevt/winevt_query.c
CHANGED
@@ -85,15 +85,15 @@ static VALUE
|
|
85
85
|
rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
|
86
86
|
{
|
87
87
|
PWSTR evtChannel, evtXPath;
|
88
|
-
VALUE channel, xpath, session;
|
88
|
+
VALUE channel, xpath, session, rb_flags;
|
89
89
|
struct WinevtQuery* winevtQuery;
|
90
90
|
struct WinevtSession* winevtSession;
|
91
91
|
EVT_HANDLE hRemoteHandle = NULL;
|
92
|
-
DWORD len;
|
92
|
+
DWORD len, flags = 0;
|
93
93
|
VALUE wchannelBuf, wpathBuf;
|
94
94
|
DWORD err = ERROR_SUCCESS;
|
95
95
|
|
96
|
-
rb_scan_args(argc, argv, "
|
96
|
+
rb_scan_args(argc, argv, "22", &channel, &xpath, &session, &rb_flags);
|
97
97
|
Check_Type(channel, T_STRING);
|
98
98
|
Check_Type(xpath, T_STRING);
|
99
99
|
|
@@ -111,6 +111,17 @@ rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
|
|
111
111
|
}
|
112
112
|
}
|
113
113
|
|
114
|
+
switch (TYPE(rb_flags)) {
|
115
|
+
case T_FIXNUM:
|
116
|
+
flags = NUM2LONG(rb_flags);
|
117
|
+
break;
|
118
|
+
case T_NIL:
|
119
|
+
flags = EvtQueryChannelPath | EvtQueryTolerateQueryErrors;
|
120
|
+
break;
|
121
|
+
default:
|
122
|
+
rb_raise(rb_eArgError, "Expected a String, a Symbol, a Fixnum, or a NilClass instance");
|
123
|
+
}
|
124
|
+
|
114
125
|
// channel : To wide char
|
115
126
|
len =
|
116
127
|
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
|
@@ -128,7 +139,7 @@ rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
|
|
128
139
|
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
129
140
|
|
130
141
|
winevtQuery->query = EvtQuery(
|
131
|
-
hRemoteHandle, evtChannel, evtXPath,
|
142
|
+
hRemoteHandle, evtChannel, evtXPath, flags);
|
132
143
|
err = GetLastError();
|
133
144
|
if (err != ERROR_SUCCESS) {
|
134
145
|
if (err == ERROR_EVT_CHANNEL_NOT_FOUND) {
|
@@ -142,6 +153,7 @@ rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
|
|
142
153
|
winevtQuery->preserveQualifiers = FALSE;
|
143
154
|
winevtQuery->localeInfo = &default_locale;
|
144
155
|
winevtQuery->remoteHandle = hRemoteHandle;
|
156
|
+
winevtQuery->preserveSID = TRUE;
|
145
157
|
|
146
158
|
ALLOCV_END(wchannelBuf);
|
147
159
|
ALLOCV_END(wpathBuf);
|
@@ -263,7 +275,8 @@ rb_winevt_query_render(VALUE self, EVT_HANDLE event)
|
|
263
275
|
if (winevtQuery->renderAsXML) {
|
264
276
|
return render_to_rb_str(event, EvtRenderEventXml);
|
265
277
|
} else {
|
266
|
-
return render_system_event(event, winevtQuery->preserveQualifiers
|
278
|
+
return render_system_event(event, winevtQuery->preserveQualifiers,
|
279
|
+
winevtQuery->preserveSID);
|
267
280
|
}
|
268
281
|
}
|
269
282
|
|
@@ -524,6 +537,40 @@ rb_winevt_query_get_locale(VALUE self)
|
|
524
537
|
}
|
525
538
|
}
|
526
539
|
|
540
|
+
/*
|
541
|
+
* This method specifies whether preserving SID or not.
|
542
|
+
*
|
543
|
+
* @param rb_preserve_sid_p [Boolean]
|
544
|
+
*/
|
545
|
+
static VALUE
|
546
|
+
rb_winevt_query_set_preserve_sid(VALUE self, VALUE rb_preserve_sid_p)
|
547
|
+
{
|
548
|
+
struct WinevtQuery* winevtQuery;
|
549
|
+
|
550
|
+
TypedData_Get_Struct(
|
551
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
552
|
+
|
553
|
+
winevtQuery->preserveSID = RTEST(rb_preserve_sid_p);
|
554
|
+
|
555
|
+
return Qnil;
|
556
|
+
}
|
557
|
+
|
558
|
+
/*
|
559
|
+
* This method returns whether preserving SID or not.
|
560
|
+
*
|
561
|
+
* @return [Boolean]
|
562
|
+
*/
|
563
|
+
static VALUE
|
564
|
+
rb_winevt_query_preserve_sid_p(VALUE self)
|
565
|
+
{
|
566
|
+
struct WinevtQuery* winevtQuery;
|
567
|
+
|
568
|
+
TypedData_Get_Struct(
|
569
|
+
self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
570
|
+
|
571
|
+
return winevtQuery->preserveSID ? Qtrue : Qfalse;
|
572
|
+
}
|
573
|
+
|
527
574
|
/*
|
528
575
|
* This method cancels channel query.
|
529
576
|
*
|
@@ -613,6 +660,37 @@ Init_winevt_query(VALUE rb_cEventLog)
|
|
613
660
|
* @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekStrict
|
614
661
|
*/
|
615
662
|
rb_define_const(rb_cFlag, "Strict", LONG2NUM(EvtSeekStrict));
|
663
|
+
|
664
|
+
/*
|
665
|
+
* EVT_QUERY_FLAGS enumeration: EvtQueryChannelPath
|
666
|
+
* @since 0.11.0
|
667
|
+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
|
668
|
+
*/
|
669
|
+
rb_define_const(rb_cFlag, "ChannelPath", LONG2NUM(EvtQueryChannelPath));
|
670
|
+
/*
|
671
|
+
* EVT_QUERY_FLAGS enumeration: EvtQueryFilePath
|
672
|
+
* @since 0.11.0
|
673
|
+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
|
674
|
+
*/
|
675
|
+
rb_define_const(rb_cFlag, "FilePath", LONG2NUM(EvtQueryFilePath));
|
676
|
+
/*
|
677
|
+
* EVT_QUERY_FLAGS enumeration: EvtQueryForwardDirection
|
678
|
+
* @since 0.11.0
|
679
|
+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
|
680
|
+
*/
|
681
|
+
rb_define_const(rb_cFlag, "ForwardDirection", LONG2NUM(EvtQueryForwardDirection));
|
682
|
+
/*
|
683
|
+
* EVT_QUERY_FLAGS enumeration: EvtQueryReverseDirection
|
684
|
+
* @since 0.11.0
|
685
|
+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
|
686
|
+
*/
|
687
|
+
rb_define_const(rb_cFlag, "ReverseDirection", LONG2NUM(EvtQueryReverseDirection));
|
688
|
+
/*
|
689
|
+
* EVT_QUERY_FLAGS enumeration: EvtSeekOriginMask
|
690
|
+
* @since 0.11.0
|
691
|
+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
|
692
|
+
*/
|
693
|
+
rb_define_const(rb_cFlag, "TolerateQueryErrors", LONG2NUM(EvtQueryTolerateQueryErrors));
|
616
694
|
/* clang-format on */
|
617
695
|
|
618
696
|
rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, -1);
|
@@ -641,6 +719,14 @@ Init_winevt_query(VALUE rb_cEventLog)
|
|
641
719
|
* @since 0.8.0
|
642
720
|
*/
|
643
721
|
rb_define_method(rb_cQuery, "locale=", rb_winevt_query_set_locale, 1);
|
722
|
+
/*
|
723
|
+
* @since 0.11.0
|
724
|
+
*/
|
725
|
+
rb_define_method(rb_cQuery, "preserve_sid?", rb_winevt_query_preserve_sid_p, 0);
|
726
|
+
/*
|
727
|
+
* @since 0.11.0
|
728
|
+
*/
|
729
|
+
rb_define_method(rb_cQuery, "preserve_sid=", rb_winevt_query_set_preserve_sid, 1);
|
644
730
|
/*
|
645
731
|
* @since 0.9.1
|
646
732
|
*/
|
@@ -110,6 +110,7 @@ rb_winevt_subscribe_initialize(VALUE self)
|
|
110
110
|
winevtSubscribe->readExistingEvents = TRUE;
|
111
111
|
winevtSubscribe->preserveQualifiers = FALSE;
|
112
112
|
winevtSubscribe->localeInfo = &default_locale;
|
113
|
+
winevtSubscribe->preserveSID = TRUE;
|
113
114
|
|
114
115
|
return Qnil;
|
115
116
|
}
|
@@ -417,7 +418,8 @@ rb_winevt_subscribe_render(VALUE self, EVT_HANDLE event)
|
|
417
418
|
if (winevtSubscribe->renderAsXML) {
|
418
419
|
return render_to_rb_str(event, EvtRenderEventXml);
|
419
420
|
} else {
|
420
|
-
return render_system_event(event, winevtSubscribe->preserveQualifiers
|
421
|
+
return render_system_event(event, winevtSubscribe->preserveQualifiers,
|
422
|
+
winevtSubscribe->preserveSID);
|
421
423
|
}
|
422
424
|
}
|
423
425
|
|
@@ -674,6 +676,40 @@ rb_winevt_subscribe_get_locale(VALUE self)
|
|
674
676
|
}
|
675
677
|
}
|
676
678
|
|
679
|
+
/*
|
680
|
+
* This method specifies whether preserving SID or not.
|
681
|
+
*
|
682
|
+
* @param rb_preserve_sid_p [Boolean]
|
683
|
+
*/
|
684
|
+
static VALUE
|
685
|
+
rb_winevt_subscribe_set_preserve_sid(VALUE self, VALUE rb_preserve_sid_p)
|
686
|
+
{
|
687
|
+
struct WinevtSubscribe* winevtSubscribe;
|
688
|
+
|
689
|
+
TypedData_Get_Struct(
|
690
|
+
self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
691
|
+
|
692
|
+
winevtSubscribe->preserveSID = RTEST(rb_preserve_sid_p);
|
693
|
+
|
694
|
+
return Qnil;
|
695
|
+
}
|
696
|
+
|
697
|
+
/*
|
698
|
+
* This method returns whether preserving SID or not.
|
699
|
+
*
|
700
|
+
* @return [Boolean]
|
701
|
+
*/
|
702
|
+
static VALUE
|
703
|
+
rb_winevt_subscribe_preserve_sid_p(VALUE self)
|
704
|
+
{
|
705
|
+
struct WinevtSubscribe* winevtSubscribe;
|
706
|
+
|
707
|
+
TypedData_Get_Struct(
|
708
|
+
self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
709
|
+
|
710
|
+
return winevtSubscribe->preserveSID ? Qtrue : Qfalse;
|
711
|
+
}
|
712
|
+
|
677
713
|
/*
|
678
714
|
* This method cancels channel subscription.
|
679
715
|
*
|
@@ -771,6 +807,14 @@ Init_winevt_subscribe(VALUE rb_cEventLog)
|
|
771
807
|
*/
|
772
808
|
rb_define_method(
|
773
809
|
rb_cSubscribe, "locale=", rb_winevt_subscribe_set_locale, 1);
|
810
|
+
/*
|
811
|
+
* @since 0.11.0
|
812
|
+
*/
|
813
|
+
rb_define_method(rb_cSubscribe, "preserve_sid?", rb_winevt_subscribe_preserve_sid_p, 0);
|
814
|
+
/*
|
815
|
+
* @since 0.11.0
|
816
|
+
*/
|
817
|
+
rb_define_method(rb_cSubscribe, "preserve_sid=", rb_winevt_subscribe_set_preserve_sid, 1);
|
774
818
|
/*
|
775
819
|
* @since 0.9.1
|
776
820
|
*/
|
data/ext/winevt/winevt_utils.cpp
CHANGED
@@ -17,7 +17,7 @@ wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen)
|
|
17
17
|
}
|
18
18
|
|
19
19
|
int len = WideCharToMultiByte(cp, 0, wstr, clen, nullptr, 0, nullptr, nullptr);
|
20
|
-
ptr =
|
20
|
+
ptr = RB_ALLOCV_N(CHAR, vstr, len);
|
21
21
|
// For memory safety.
|
22
22
|
ZeroMemory(ptr, sizeof(CHAR) * len);
|
23
23
|
ret = WideCharToMultiByte(cp, 0, wstr, clen, ptr, len, nullptr, nullptr);
|
@@ -25,11 +25,11 @@ wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen)
|
|
25
25
|
// ref: https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte#return-value
|
26
26
|
if (ret == 0) {
|
27
27
|
err = GetLastError();
|
28
|
-
|
28
|
+
RB_ALLOCV_END(vstr);
|
29
29
|
raise_system_error(rb_eRuntimeError, err);
|
30
30
|
}
|
31
31
|
VALUE str = rb_utf8_str_new_cstr(ptr);
|
32
|
-
|
32
|
+
RB_ALLOCV_END(vstr);
|
33
33
|
|
34
34
|
return str;
|
35
35
|
}
|
@@ -85,18 +85,18 @@ render_to_rb_str(EVT_HANDLE handle, DWORD flags)
|
|
85
85
|
EvtRender(nullptr, handle, flags, 0, NULL, &bufferSize, &count);
|
86
86
|
|
87
87
|
// bufferSize is in bytes, not characters
|
88
|
-
buffer = (WCHAR*)
|
88
|
+
buffer = (WCHAR*)RB_ALLOCV(vbuffer, bufferSize);
|
89
89
|
|
90
90
|
succeeded =
|
91
91
|
EvtRender(nullptr, handle, flags, bufferSize, buffer, &bufferSizeUsed, &count);
|
92
92
|
if (!succeeded) {
|
93
93
|
DWORD status = GetLastError();
|
94
|
-
|
94
|
+
RB_ALLOCV_END(vbuffer);
|
95
95
|
raise_system_error(rb_eWinevtQueryError, status);
|
96
96
|
}
|
97
97
|
|
98
98
|
result = wstr_to_rb_str(CP_UTF8, buffer, -1);
|
99
|
-
|
99
|
+
RB_ALLOCV_END(vbuffer);
|
100
100
|
|
101
101
|
return result;
|
102
102
|
}
|
@@ -153,7 +153,7 @@ make_displayable_binary_string(PBYTE bin, size_t length)
|
|
153
153
|
return rb_str_new2("(NULL)");
|
154
154
|
}
|
155
155
|
|
156
|
-
buffer =
|
156
|
+
buffer = RB_ALLOCV_N(CHAR, vbuffer, size);
|
157
157
|
|
158
158
|
for (i = 0; i < length; i++) {
|
159
159
|
for (j = 0; j < 2; j++) {
|
@@ -164,7 +164,7 @@ make_displayable_binary_string(PBYTE bin, size_t length)
|
|
164
164
|
buffer[size - 1] = '\0';
|
165
165
|
|
166
166
|
VALUE str = rb_str_new2(buffer);
|
167
|
-
|
167
|
+
RB_ALLOCV_END(vbuffer);
|
168
168
|
|
169
169
|
return str;
|
170
170
|
}
|
@@ -380,7 +380,7 @@ get_values(EVT_HANDLE handle)
|
|
380
380
|
renderContext, handle, EvtRenderEventValues, 0, NULL, &bufferSize, &propCount);
|
381
381
|
|
382
382
|
// bufferSize is in bytes, not array size
|
383
|
-
pRenderedValues = (PEVT_VARIANT)
|
383
|
+
pRenderedValues = (PEVT_VARIANT)RB_ALLOCV(vbuffer, bufferSize);
|
384
384
|
|
385
385
|
succeeded = EvtRender(renderContext,
|
386
386
|
handle,
|
@@ -391,14 +391,14 @@ get_values(EVT_HANDLE handle)
|
|
391
391
|
&propCount);
|
392
392
|
if (!succeeded) {
|
393
393
|
DWORD status = GetLastError();
|
394
|
-
|
394
|
+
RB_ALLOCV_END(vbuffer);
|
395
395
|
EvtClose(renderContext);
|
396
396
|
raise_system_error(rb_eWinevtQueryError, status);
|
397
397
|
}
|
398
398
|
|
399
399
|
userValues = extract_user_evt_variants(pRenderedValues, propCount);
|
400
400
|
|
401
|
-
|
401
|
+
RB_ALLOCV_END(vbuffer);
|
402
402
|
EvtClose(renderContext);
|
403
403
|
|
404
404
|
return userValues;
|
@@ -596,8 +596,102 @@ cleanup:
|
|
596
596
|
return _wcsdup(result.data());
|
597
597
|
}
|
598
598
|
|
599
|
+
static char* convert_wstr(wchar_t *wstr)
|
600
|
+
{
|
601
|
+
VALUE vstr;
|
602
|
+
int len = 0;
|
603
|
+
CHAR *ptr = NULL;
|
604
|
+
DWORD err = ERROR_SUCCESS;
|
605
|
+
|
606
|
+
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
|
607
|
+
if (len == 0) {
|
608
|
+
return NULL;
|
609
|
+
}
|
610
|
+
|
611
|
+
ptr = RB_ALLOCV_N(CHAR, vstr, len);
|
612
|
+
// For memory safety.
|
613
|
+
ZeroMemory(ptr, sizeof(CHAR) * len);
|
614
|
+
|
615
|
+
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, ptr, len, NULL, NULL);
|
616
|
+
// return 0 should be failure.
|
617
|
+
// ref: https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte#return-value
|
618
|
+
if (len == 0) {
|
619
|
+
err = GetLastError();
|
620
|
+
RB_ALLOCV_END(vstr);
|
621
|
+
raise_system_error(rb_eRuntimeError, err);
|
622
|
+
}
|
623
|
+
|
624
|
+
return strdup(ptr);
|
625
|
+
}
|
626
|
+
|
627
|
+
static int ExpandSIDWString(PSID sid, CHAR **out_expanded)
|
628
|
+
{
|
629
|
+
#define MAX_NAME 256
|
630
|
+
DWORD len = MAX_NAME, err = ERROR_SUCCESS;
|
631
|
+
SID_NAME_USE sid_type = SidTypeUnknown;
|
632
|
+
WCHAR wAccount[MAX_NAME];
|
633
|
+
WCHAR wDomain[MAX_NAME];
|
634
|
+
CHAR *account = NULL, *domain = NULL;
|
635
|
+
DWORD result_len = 0;
|
636
|
+
CHAR *formatted = NULL;
|
637
|
+
VALUE vformatted;
|
638
|
+
#undef MAX_NAME
|
639
|
+
|
640
|
+
if (!LookupAccountSidW(NULL, sid,
|
641
|
+
wAccount, &len, wDomain,
|
642
|
+
&len, &sid_type)) {
|
643
|
+
err = GetLastError();
|
644
|
+
if (err == ERROR_NONE_MAPPED) {
|
645
|
+
goto none_mapped_error;
|
646
|
+
}
|
647
|
+
else {
|
648
|
+
return WINEVT_UTILS_ERROR_OTHERS;
|
649
|
+
}
|
650
|
+
|
651
|
+
goto error;
|
652
|
+
}
|
653
|
+
|
654
|
+
domain = convert_wstr(wDomain);
|
655
|
+
if (domain == NULL) {
|
656
|
+
goto error;
|
657
|
+
}
|
658
|
+
account = convert_wstr(wAccount);
|
659
|
+
if (account == NULL) {
|
660
|
+
goto error;
|
661
|
+
}
|
662
|
+
|
663
|
+
result_len = strlen(domain) + 1 + strlen(account) + 1;
|
664
|
+
formatted = (CHAR *)RB_ALLOCV(vformatted, result_len);
|
665
|
+
if (formatted == NULL) {
|
666
|
+
goto error;
|
667
|
+
}
|
668
|
+
|
669
|
+
_snprintf_s(formatted, result_len, _TRUNCATE, "%s\\%s", domain, account);
|
670
|
+
|
671
|
+
*out_expanded = strdup(formatted);
|
672
|
+
|
673
|
+
free(domain);
|
674
|
+
free(account);
|
675
|
+
RB_ALLOCV_END(vformatted);
|
676
|
+
|
677
|
+
|
678
|
+
return 0;
|
679
|
+
|
680
|
+
none_mapped_error:
|
681
|
+
|
682
|
+
return WINEVT_UTILS_ERROR_NONE_MAPPED;
|
683
|
+
|
684
|
+
error:
|
685
|
+
err = GetLastError();
|
686
|
+
|
687
|
+
RB_ALLOCV_END(vformatted);
|
688
|
+
free(domain);
|
689
|
+
free(account);
|
690
|
+
raise_system_error(rb_eRuntimeError, err);
|
691
|
+
}
|
692
|
+
|
599
693
|
VALUE
|
600
|
-
render_system_event(EVT_HANDLE hEvent, BOOL preserve_qualifiers)
|
694
|
+
render_system_event(EVT_HANDLE hEvent, BOOL preserve_qualifiers, BOOL preserveSID_p)
|
601
695
|
{
|
602
696
|
DWORD status = ERROR_SUCCESS;
|
603
697
|
EVT_HANDLE hContext = NULL;
|
@@ -633,7 +727,7 @@ render_system_event(EVT_HANDLE hEvent, BOOL preserve_qualifiers)
|
|
633
727
|
status = GetLastError();
|
634
728
|
if (ERROR_INSUFFICIENT_BUFFER == status) {
|
635
729
|
dwBufferSize = dwBufferUsed;
|
636
|
-
pRenderedValues = (PEVT_VARIANT)
|
730
|
+
pRenderedValues = (PEVT_VARIANT)RB_ALLOCV(vRenderedValues, dwBufferSize);
|
637
731
|
if (pRenderedValues) {
|
638
732
|
EvtRender(hContext,
|
639
733
|
hEvent,
|
@@ -651,7 +745,7 @@ render_system_event(EVT_HANDLE hEvent, BOOL preserve_qualifiers)
|
|
651
745
|
|
652
746
|
if (ERROR_SUCCESS != status) {
|
653
747
|
EvtClose(hContext);
|
654
|
-
|
748
|
+
RB_ALLOCV_END(vRenderedValues);
|
655
749
|
|
656
750
|
rb_raise(rb_eWinevtQueryError, "EvtRender failed with %lu\n", status);
|
657
751
|
}
|
@@ -787,14 +881,30 @@ render_system_event(EVT_HANDLE hEvent, BOOL preserve_qualifiers)
|
|
787
881
|
|
788
882
|
if (EvtVarTypeNull != pRenderedValues[EvtSystemUserID].Type) {
|
789
883
|
if (ConvertSidToStringSid(pRenderedValues[EvtSystemUserID].SidVal, &pwsSid)) {
|
790
|
-
|
791
|
-
|
884
|
+
CHAR *expandSID = NULL;
|
885
|
+
if (preserveSID_p) {
|
886
|
+
rbstr = rb_utf8_str_new_cstr(pwsSid);
|
887
|
+
rb_hash_aset(hash, rb_str_new2("UserID"), rbstr);
|
888
|
+
}
|
889
|
+
/* S-1-15-3- is used for capability SIDs. So, we need to skip
|
890
|
+
* SID translation.
|
891
|
+
* ref: https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers
|
892
|
+
* See also: https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/sids-not-resolve-into-friendly-names
|
893
|
+
*/
|
894
|
+
if (strnicmp(pwsSid, "S-1-15-3-", 9) != 0) {
|
895
|
+
if (ExpandSIDWString(pRenderedValues[EvtSystemUserID].SidVal,
|
896
|
+
&expandSID) == 0) {
|
897
|
+
rbstr = rb_utf8_str_new_cstr(expandSID);
|
898
|
+
free(expandSID);
|
899
|
+
rb_hash_aset(hash, rb_str_new2("User"), rbstr);
|
900
|
+
}
|
901
|
+
}
|
792
902
|
LocalFree(pwsSid);
|
793
903
|
}
|
794
904
|
}
|
795
905
|
|
796
906
|
EvtClose(hContext);
|
797
|
-
|
907
|
+
RB_ALLOCV_END(vRenderedValues);
|
798
908
|
|
799
909
|
return hash;
|
800
910
|
}
|
data/lib/winevt/version.rb
CHANGED
data/ruby_install.ps1
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
$rubies = @(
|
2
|
+
@{
|
3
|
+
"version" = "Ruby 2.6.9-1"
|
4
|
+
"install_path" = "C:\Ruby26"
|
5
|
+
"download_url" = "https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-2.6.9-1/rubyinstaller-2.6.9-1-x86.exe"
|
6
|
+
"devkit_url" = ""
|
7
|
+
"devkit_paths" = @()
|
8
|
+
"bundlerV2" = $true
|
9
|
+
}
|
10
|
+
@{
|
11
|
+
"version" = "Ruby 2.6.9-1 (x64)"
|
12
|
+
"install_path" = "C:\Ruby26-x64"
|
13
|
+
"download_url" = "https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-2.6.9-1/rubyinstaller-2.6.9-1-x64.exe"
|
14
|
+
"devkit_url" = ""
|
15
|
+
"devkit_paths" = @()
|
16
|
+
"bundlerV2" = $true
|
17
|
+
}
|
18
|
+
@{
|
19
|
+
"version" = "Ruby 2.7.8-1"
|
20
|
+
"install_path" = "C:\Ruby27"
|
21
|
+
"download_url" = "https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-2.7.8-1/rubyinstaller-2.7.8-1-x86.exe"
|
22
|
+
"devkit_url" = ""
|
23
|
+
"devkit_paths" = @()
|
24
|
+
"bundlerV2" = $true
|
25
|
+
}
|
26
|
+
@{
|
27
|
+
"version" = "Ruby 2.7.8-1 (x64)"
|
28
|
+
"install_path" = "C:\Ruby27-x64"
|
29
|
+
"download_url" = "https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-2.7.8-1/rubyinstaller-2.7.8-1-x64.exe"
|
30
|
+
"devkit_url" = ""
|
31
|
+
"devkit_paths" = @()
|
32
|
+
"bundlerV2" = $true
|
33
|
+
}
|
34
|
+
)
|
35
|
+
|
36
|
+
function UpdateRubyPath($rubyPath) {
|
37
|
+
$env:path = ($env:path -split ';' | Where-Object { -not $_.contains('\Ruby') }) -join ';'
|
38
|
+
$env:path = "$rubyPath;$env:path"
|
39
|
+
}
|
40
|
+
|
41
|
+
function Install-Ruby($ruby) {
|
42
|
+
Write-Host "Installing $($ruby.version)" -ForegroundColor Cyan
|
43
|
+
|
44
|
+
# uninstall existing
|
45
|
+
$rubyUninstallPath = "$ruby.install_path\unins000.exe"
|
46
|
+
if ([IO.File]::Exists($rubyUninstallPath)) {
|
47
|
+
Write-Host " Uninstalling previous Ruby 2.4..." -ForegroundColor Gray
|
48
|
+
"`"$rubyUninstallPath`" /silent" | out-file "$env:temp\uninstall-ruby.cmd" -Encoding ASCII
|
49
|
+
& "$env:temp\uninstall-ruby.cmd"
|
50
|
+
del "$env:temp\uninstall-ruby.cmd"
|
51
|
+
Start-Sleep -s 5
|
52
|
+
}
|
53
|
+
|
54
|
+
if (Test-Path $ruby.install_path) {
|
55
|
+
Write-Host " Deleting $($ruby.install_path)" -ForegroundColor Gray
|
56
|
+
Remove-Item $ruby.install_path -Force -Recurse
|
57
|
+
}
|
58
|
+
|
59
|
+
$exePath = "$($env:TEMP)\rubyinstaller.exe"
|
60
|
+
|
61
|
+
Write-Host " Downloading $($ruby.version) from $($ruby.download_url)" -ForegroundColor Gray
|
62
|
+
(New-Object Net.WebClient).DownloadFile($ruby.download_url, $exePath)
|
63
|
+
|
64
|
+
Write-Host "Installing..." -ForegroundColor Gray
|
65
|
+
cmd /c start /wait $exePath /verysilent /allusers /dir="$($ruby.install_path.replace('\', '/'))" /tasks="noassocfiles,nomodpath,noridkinstall"
|
66
|
+
del $exePath
|
67
|
+
Write-Host "Installed" -ForegroundColor Green
|
68
|
+
|
69
|
+
# setup Ruby
|
70
|
+
UpdateRubyPath "$($ruby.install_path)\bin"
|
71
|
+
Write-Host "ruby --version" -ForegroundColor Gray
|
72
|
+
cmd /c ruby --version
|
73
|
+
|
74
|
+
Write-Host "gem --version" -ForegroundColor Gray
|
75
|
+
cmd /c gem --version
|
76
|
+
|
77
|
+
# list installed gems
|
78
|
+
Write-Host "gem list --local" -ForegroundColor Gray
|
79
|
+
cmd /c gem list --local
|
80
|
+
|
81
|
+
# delete temp path
|
82
|
+
if ($tempPath) {
|
83
|
+
Write-Host " Cleaning up..." -ForegroundColor Gray
|
84
|
+
Remove-Item $tempPath -Force -Recurse
|
85
|
+
}
|
86
|
+
|
87
|
+
Write-Host " Done!" -ForegroundColor Green
|
88
|
+
}
|
89
|
+
|
90
|
+
for ($i = 0; $i -lt $rubies.Count; $i++) {
|
91
|
+
Install-Ruby $rubies[$i]
|
92
|
+
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: winevt_c
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hiroshi Hatake
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -141,6 +141,7 @@ files:
|
|
141
141
|
- lib/winevt/session.rb
|
142
142
|
- lib/winevt/subscribe.rb
|
143
143
|
- lib/winevt/version.rb
|
144
|
+
- ruby_install.ps1
|
144
145
|
- winevt_c.gemspec
|
145
146
|
homepage: https://github.com/fluent-plugins-nursery/winevt_c
|
146
147
|
licenses:
|