winevt_c 0.10.2 → 0.11.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80b819f8d9870a7c09c90b34ca7750ddf913df9056369cc8a34b6c8883c13205
4
- data.tar.gz: 49c44fb51e996fa70daae1ee8cfb4e12629624dd0d03f261b9680aa241326abf
3
+ metadata.gz: 236cd5f44b0a13dd198baa83329a340742ae4e9ff618d01671cb48326e4da0c9
4
+ data.tar.gz: 26cfad4e5eede9d60710672dabe47a61db41cc2d21861704fb94f00ea2c6c51f
5
5
  SHA512:
6
- metadata.gz: 40985cde59f0eb8941fa07998a3461d20a02736c85765484778069790517519e273f82b75ee87499fb40f3b1018940de1ed67e31f1fc7e481b2d80f5dbcc617c
7
- data.tar.gz: 862e1aa6620ec9763a82863ac5d74af158f13cb37637ea53434cf66f89e5ca039e16c52b9849a4f91b3326822ec2015cc6c5b298990259c0d8703b31d497e3d9
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.cmd install 1 3
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
@@ -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 "
@@ -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
  };
@@ -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, "21", &channel, &xpath, &session);
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, EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
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
  */
@@ -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 = ALLOCV_N(CHAR, vstr, len);
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
- ALLOCV_END(vstr);
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
- ALLOCV_END(vstr);
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*)ALLOCV(vbuffer, bufferSize);
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
- ALLOCV_END(vbuffer);
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
- ALLOCV_END(vbuffer);
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 = ALLOCV_N(CHAR, vbuffer, size);
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
- ALLOCV_END(vbuffer);
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)ALLOCV(vbuffer, bufferSize);
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
- ALLOCV_END(vbuffer);
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
- ALLOCV_END(vbuffer);
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)ALLOCV(vRenderedValues, dwBufferSize);
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
- ALLOCV_END(vRenderedValues);
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
- rbstr = rb_utf8_str_new_cstr(pwsSid);
791
- rb_hash_aset(hash, rb_str_new2("UserID"), rbstr);
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
- ALLOCV_END(vRenderedValues);
907
+ RB_ALLOCV_END(vRenderedValues);
798
908
 
799
909
  return hash;
800
910
  }
@@ -1,3 +1,3 @@
1
1
  module Winevt
2
- VERSION = "0.10.2"
2
+ VERSION = "0.11.1"
3
3
  end
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.10.2
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-03-06 00:00:00.000000000 Z
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: