winevt_c 0.10.1 → 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/.github/workflows/linux.yml +1 -1
- data/appveyor.yml +6 -1
- data/ext/winevt/extconf.rb +3 -0
- data/ext/winevt/winevt.c +2 -0
- data/ext/winevt/winevt_c.h +12 -1
- data/ext/winevt/winevt_query.c +91 -5
- data/ext/winevt/winevt_subscribe.c +67 -2
- 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/.github/workflows/linux.yml
CHANGED
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
CHANGED
@@ -7,6 +7,7 @@ VALUE rb_cSubscribe;
|
|
7
7
|
VALUE rb_eWinevtQueryError;
|
8
8
|
VALUE rb_eChannelNotFoundError;
|
9
9
|
VALUE rb_eRemoteHandlerError;
|
10
|
+
VALUE rb_eSubscribeHandlerError;
|
10
11
|
|
11
12
|
static ID id_call;
|
12
13
|
|
@@ -20,6 +21,7 @@ Init_winevt(void)
|
|
20
21
|
rb_eWinevtQueryError = rb_define_class_under(rb_cQuery, "Error", rb_eStandardError);
|
21
22
|
rb_eChannelNotFoundError = rb_define_class_under(rb_cEventLog, "ChannelNotFoundError", rb_eStandardError);
|
22
23
|
rb_eRemoteHandlerError = rb_define_class_under(rb_cSubscribe, "RemoteHandlerError", rb_eRuntimeError);
|
24
|
+
rb_eSubscribeHandlerError = rb_define_class_under(rb_cSubscribe, "SubscribeHandlerError", rb_eRuntimeError);
|
23
25
|
|
24
26
|
Init_winevt_channel(rb_cEventLog);
|
25
27
|
Init_winevt_bookmark(rb_cEventLog);
|
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
|
@@ -61,6 +69,7 @@ extern VALUE rb_cSubscribe;
|
|
61
69
|
extern VALUE rb_eWinevtQueryError;
|
62
70
|
extern VALUE rb_eChannelNotFoundError;
|
63
71
|
extern VALUE rb_eRemoteHandlerError;
|
72
|
+
extern VALUE rb_eSubscribeHandlerError;
|
64
73
|
extern VALUE rb_cLocale;
|
65
74
|
extern VALUE rb_cSession;
|
66
75
|
|
@@ -100,6 +109,7 @@ struct WinevtQuery
|
|
100
109
|
LONG timeout;
|
101
110
|
BOOL renderAsXML;
|
102
111
|
BOOL preserveQualifiers;
|
112
|
+
BOOL preserveSID;
|
103
113
|
LocaleInfo *localeInfo;
|
104
114
|
EVT_HANDLE remoteHandle;
|
105
115
|
};
|
@@ -121,6 +131,7 @@ struct WinevtSubscribe
|
|
121
131
|
DWORD currentRate;
|
122
132
|
BOOL renderAsXML;
|
123
133
|
BOOL preserveQualifiers;
|
134
|
+
BOOL preserveSID;
|
124
135
|
LocaleInfo* localeInfo;
|
125
136
|
EVT_HANDLE remoteHandle;
|
126
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
|
}
|
@@ -174,7 +175,7 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
|
|
174
175
|
struct WinevtSession* winevtSession;
|
175
176
|
struct WinevtSubscribe* winevtSubscribe;
|
176
177
|
|
177
|
-
hSignalEvent = CreateEvent(NULL,
|
178
|
+
hSignalEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
|
178
179
|
|
179
180
|
TypedData_Get_Struct(
|
180
181
|
self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
@@ -341,6 +342,8 @@ rb_winevt_subscribe_next(VALUE self)
|
|
341
342
|
EVT_HANDLE hEvents[SUBSCRIBE_ARRAY_SIZE];
|
342
343
|
ULONG count = 0;
|
343
344
|
DWORD status = ERROR_SUCCESS;
|
345
|
+
DWORD dwWait = 0;
|
346
|
+
|
344
347
|
struct WinevtSubscribe* winevtSubscribe;
|
345
348
|
|
346
349
|
TypedData_Get_Struct(
|
@@ -355,6 +358,23 @@ rb_winevt_subscribe_next(VALUE self)
|
|
355
358
|
return Qfalse;
|
356
359
|
}
|
357
360
|
|
361
|
+
/* If a signalEvent notifies whether a state of processed event(s)
|
362
|
+
* is existing or not.
|
363
|
+
* For checking for a result of WaitForSingleObject,
|
364
|
+
* we need to raise SubscribeHandlerError exception when
|
365
|
+
* WAIT_FAILED is detected for further investigations.
|
366
|
+
* Note that we don't need to wait explicitly here.
|
367
|
+
* Because this function is inside of each enumerator.
|
368
|
+
* So, WaitForSingleObject should return immediately and should be
|
369
|
+
* processed with the latter each loops if there is no more items.
|
370
|
+
* Just intended to check that there is no errors here. */
|
371
|
+
dwWait = WaitForSingleObject(winevtSubscribe->signalEvent, 0);
|
372
|
+
if (dwWait == WAIT_FAILED) {
|
373
|
+
raise_system_error(rb_eSubscribeHandlerError, GetLastError());
|
374
|
+
} else if (dwWait != WAIT_OBJECT_0) {
|
375
|
+
return Qfalse;
|
376
|
+
}
|
377
|
+
|
358
378
|
if (!EvtNext(winevtSubscribe->subscription,
|
359
379
|
SUBSCRIBE_ARRAY_SIZE,
|
360
380
|
hEvents,
|
@@ -368,6 +388,8 @@ rb_winevt_subscribe_next(VALUE self)
|
|
368
388
|
if (ERROR_NO_MORE_ITEMS != status) {
|
369
389
|
return Qfalse;
|
370
390
|
}
|
391
|
+
|
392
|
+
ResetEvent(winevtSubscribe->signalEvent);
|
371
393
|
}
|
372
394
|
|
373
395
|
if (status == ERROR_SUCCESS) {
|
@@ -396,7 +418,8 @@ rb_winevt_subscribe_render(VALUE self, EVT_HANDLE event)
|
|
396
418
|
if (winevtSubscribe->renderAsXML) {
|
397
419
|
return render_to_rb_str(event, EvtRenderEventXml);
|
398
420
|
} else {
|
399
|
-
return render_system_event(event, winevtSubscribe->preserveQualifiers
|
421
|
+
return render_system_event(event, winevtSubscribe->preserveQualifiers,
|
422
|
+
winevtSubscribe->preserveSID);
|
400
423
|
}
|
401
424
|
}
|
402
425
|
|
@@ -653,6 +676,40 @@ rb_winevt_subscribe_get_locale(VALUE self)
|
|
653
676
|
}
|
654
677
|
}
|
655
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
|
+
|
656
713
|
/*
|
657
714
|
* This method cancels channel subscription.
|
658
715
|
*
|
@@ -750,6 +807,14 @@ Init_winevt_subscribe(VALUE rb_cEventLog)
|
|
750
807
|
*/
|
751
808
|
rb_define_method(
|
752
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);
|
753
818
|
/*
|
754
819
|
* @since 0.9.1
|
755
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:
|
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:
|