winevt_c 0.10.2 → 0.11.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/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 +121 -18
- 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: 53a1d55d20095680cdb54820e8b0b9293fe40e2a16ae74a897ea3f5b0a1cf05d
|
4
|
+
data.tar.gz: '080132cb71100664e30b9ef7e9c1f2c49542b7f92f5c78b25d3b893fc459bb5b'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbd64322ff92fb89c723a2d963fb1b706a169d40a620985adf8ea9cb4eb5654a5df206d07346834c68334e157224c6d71fc9e38762c010eca73df34f1dd68662
|
7
|
+
data.tar.gz: a514c1c356b1d62c44c19887ce24790cc5efa966a9184470df1fc2317f88d436b24caa61600b62cf5d4d8bddbcf07cccaacd2d2b48fa9b14e0c2adf772db9d11
|
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,23 @@ 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
|
-
|
792
|
-
|
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
|
+
LocalFree(pwsSid);
|
889
|
+
}
|
890
|
+
if (ExpandSIDWString(pRenderedValues[EvtSystemUserID].SidVal,
|
891
|
+
&expandSID) == 0) {
|
892
|
+
rbstr = rb_utf8_str_new_cstr(expandSID);
|
893
|
+
free(expandSID);
|
894
|
+
rb_hash_aset(hash, rb_str_new2("User"), rbstr);
|
895
|
+
}
|
793
896
|
}
|
794
897
|
}
|
795
898
|
|
796
899
|
EvtClose(hContext);
|
797
|
-
|
900
|
+
RB_ALLOCV_END(vRenderedValues);
|
798
901
|
|
799
902
|
return hash;
|
800
903
|
}
|
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.0
|
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-01 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:
|