winevt_c 0.9.1 → 0.9.2
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/.clang-format +4 -4
- data/.github/workflows/linux.yml +26 -0
- data/Gemfile +6 -6
- data/LICENSE.txt +202 -202
- data/README.md +97 -97
- data/Rakefile +37 -37
- data/appveyor.yml +32 -26
- data/example/bookmark.rb +9 -9
- data/example/enumerate_channels.rb +13 -13
- data/example/eventlog.rb +13 -13
- data/example/locale.rb +13 -13
- data/example/rate_limit.rb +14 -14
- data/example/tailing.rb +21 -21
- data/ext/winevt/extconf.rb +24 -24
- data/ext/winevt/winevt.c +30 -30
- data/ext/winevt/winevt_bookmark.c +149 -149
- data/ext/winevt/winevt_c.h +132 -132
- data/ext/winevt/winevt_channel.c +327 -327
- data/ext/winevt/winevt_locale.c +92 -92
- data/ext/winevt/winevt_locale_info.c +68 -68
- data/ext/winevt/winevt_query.c +650 -650
- data/ext/winevt/winevt_session.c +425 -425
- data/ext/winevt/winevt_subscribe.c +757 -757
- data/ext/winevt/winevt_utils.cpp +723 -718
- data/lib/winevt.rb +14 -14
- data/lib/winevt/bookmark.rb +6 -6
- data/lib/winevt/query.rb +6 -6
- data/lib/winevt/session.rb +15 -15
- data/lib/winevt/subscribe.rb +18 -18
- data/lib/winevt/version.rb +3 -3
- data/winevt_c.gemspec +34 -34
- metadata +8 -9
- data/.travis.yml +0 -15
    
        data/ext/winevt/winevt_utils.cpp
    CHANGED
    
    | @@ -1,718 +1,723 @@ | |
| 1 | 
            -
            #include <winevt_c.h>
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            #include <sddl.h>
         | 
| 4 | 
            -
            #include <stdlib.h>
         | 
| 5 | 
            -
            #include <string>
         | 
| 6 | 
            -
            #include <vector>
         | 
| 7 | 
            -
             | 
| 8 | 
            -
            VALUE
         | 
| 9 | 
            -
            wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen)
         | 
| 10 | 
            -
            {
         | 
| 11 | 
            -
              VALUE vstr;
         | 
| 12 | 
            -
              CHAR* ptr;
         | 
| 13 | 
            -
              int len = WideCharToMultiByte(cp, 0, wstr, clen, nullptr, 0, nullptr, nullptr);
         | 
| 14 | 
            -
              ptr = ALLOCV_N(CHAR, vstr, len);
         | 
| 15 | 
            -
              WideCharToMultiByte(cp, 0, wstr, clen, ptr, len, nullptr, nullptr);
         | 
| 16 | 
            -
              VALUE str = rb_utf8_str_new_cstr(ptr);
         | 
| 17 | 
            -
              ALLOCV_END(vstr);
         | 
| 18 | 
            -
             | 
| 19 | 
            -
              return str;
         | 
| 20 | 
            -
            }
         | 
| 21 | 
            -
             | 
| 22 | 
            -
            void
         | 
| 23 | 
            -
            raise_system_error(VALUE error, DWORD errorCode)
         | 
| 24 | 
            -
            {
         | 
| 25 | 
            -
              WCHAR msgBuf[256] = { 0 };
         | 
| 26 | 
            -
              VALUE errorMessage;
         | 
| 27 | 
            -
             | 
| 28 | 
            -
              FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
         | 
| 29 | 
            -
                             NULL,
         | 
| 30 | 
            -
                             errorCode,
         | 
| 31 | 
            -
                             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
         | 
| 32 | 
            -
                             msgBuf,
         | 
| 33 | 
            -
                             _countof(msgBuf),
         | 
| 34 | 
            -
                             NULL);
         | 
| 35 | 
            -
              errorMessage = wstr_to_rb_str(CP_UTF8, msgBuf, -1);
         | 
| 36 | 
            -
             | 
| 37 | 
            -
            #pragma GCC diagnostic push
         | 
| 38 | 
            -
            #pragma GCC diagnostic ignored "-Wformat="
         | 
| 39 | 
            -
            #pragma GCC diagnostic ignored "-Wformat-extra-args"
         | 
| 40 | 
            -
              rb_raise(error, "ErrorCode: %lu\nError: %" PRIsVALUE "\n", errorCode, errorMessage);
         | 
| 41 | 
            -
            #pragma GCC diagnostic pop
         | 
| 42 | 
            -
            }
         | 
| 43 | 
            -
             | 
| 44 | 
            -
            VALUE
         | 
| 45 | 
            -
            render_to_rb_str(EVT_HANDLE handle, DWORD flags)
         | 
| 46 | 
            -
            {
         | 
| 47 | 
            -
              VALUE vbuffer;
         | 
| 48 | 
            -
              WCHAR* buffer;
         | 
| 49 | 
            -
              ULONG bufferSize = 0;
         | 
| 50 | 
            -
              ULONG bufferSizeUsed = 0;
         | 
| 51 | 
            -
              ULONG count;
         | 
| 52 | 
            -
              BOOL succeeded;
         | 
| 53 | 
            -
              VALUE result;
         | 
| 54 | 
            -
             | 
| 55 | 
            -
              if (flags != EvtRenderEventXml && flags != EvtRenderBookmark) {
         | 
| 56 | 
            -
                return Qnil;
         | 
| 57 | 
            -
              }
         | 
| 58 | 
            -
             | 
| 59 | 
            -
              // Get the size of the buffer
         | 
| 60 | 
            -
              EvtRender(nullptr, handle, flags, 0, NULL, &bufferSize, &count);
         | 
| 61 | 
            -
             | 
| 62 | 
            -
              // bufferSize is in bytes, not characters
         | 
| 63 | 
            -
              buffer = (WCHAR*)ALLOCV(vbuffer, bufferSize);
         | 
| 64 | 
            -
             | 
| 65 | 
            -
              succeeded =
         | 
| 66 | 
            -
                EvtRender(nullptr, handle, flags, bufferSize, buffer, &bufferSizeUsed, &count);
         | 
| 67 | 
            -
              if (!succeeded) {
         | 
| 68 | 
            -
                DWORD status = GetLastError();
         | 
| 69 | 
            -
                ALLOCV_END(vbuffer);
         | 
| 70 | 
            -
                raise_system_error(rb_eWinevtQueryError, status);
         | 
| 71 | 
            -
              }
         | 
| 72 | 
            -
             | 
| 73 | 
            -
              result = wstr_to_rb_str(CP_UTF8, buffer, -1);
         | 
| 74 | 
            -
              ALLOCV_END(vbuffer);
         | 
| 75 | 
            -
             | 
| 76 | 
            -
              return result;
         | 
| 77 | 
            -
            }
         | 
| 78 | 
            -
             | 
| 79 | 
            -
            EVT_HANDLE
         | 
| 80 | 
            -
            connect_to_remote(LPWSTR computerName, LPWSTR domain, LPWSTR username, LPWSTR password,
         | 
| 81 | 
            -
                              EVT_RPC_LOGIN_FLAGS flags)
         | 
| 82 | 
            -
            {
         | 
| 83 | 
            -
              EVT_HANDLE hRemote = NULL;
         | 
| 84 | 
            -
              EVT_RPC_LOGIN Credentials;
         | 
| 85 | 
            -
             | 
| 86 | 
            -
              RtlZeroMemory(&Credentials, sizeof(EVT_RPC_LOGIN));
         | 
| 87 | 
            -
             | 
| 88 | 
            -
              Credentials.Server = computerName;
         | 
| 89 | 
            -
              Credentials.Domain = domain;
         | 
| 90 | 
            -
              Credentials.User = username;
         | 
| 91 | 
            -
              Credentials.Password = password;
         | 
| 92 | 
            -
              Credentials.Flags = flags;
         | 
| 93 | 
            -
             | 
| 94 | 
            -
              hRemote = EvtOpenSession(EvtRpcLogin, &Credentials, 0, 0);
         | 
| 95 | 
            -
             | 
| 96 | 
            -
              SecureZeroMemory(&Credentials, sizeof(EVT_RPC_LOGIN));
         | 
| 97 | 
            -
             | 
| 98 | 
            -
              return hRemote;
         | 
| 99 | 
            -
            }
         | 
| 100 | 
            -
             | 
| 101 | 
            -
            static std::wstring
         | 
| 102 | 
            -
            guid_to_wstr(const GUID& guid)
         | 
| 103 | 
            -
            {
         | 
| 104 | 
            -
              LPOLESTR p = nullptr;
         | 
| 105 | 
            -
              if (FAILED(StringFromCLSID(guid, &p))) {
         | 
| 106 | 
            -
                return nullptr;
         | 
| 107 | 
            -
              }
         | 
| 108 | 
            -
              std::wstring s(p);
         | 
| 109 | 
            -
              CoTaskMemFree(p);
         | 
| 110 | 
            -
              return s;
         | 
| 111 | 
            -
            }
         | 
| 112 | 
            -
             | 
| 113 | 
            -
            static VALUE
         | 
| 114 | 
            -
            extract_user_evt_variants(PEVT_VARIANT pRenderedValues, DWORD propCount)
         | 
| 115 | 
            -
            {
         | 
| 116 | 
            -
              VALUE userValues = rb_ary_new();
         | 
| 117 | 
            -
              VALUE rbObj;
         | 
| 118 | 
            -
             | 
| 119 | 
            -
              for (DWORD i = 0; i < propCount; i++) {
         | 
| 120 | 
            -
                switch (pRenderedValues[i].Type) {
         | 
| 121 | 
            -
                  case EvtVarTypeNull:
         | 
| 122 | 
            -
                    rb_ary_push(userValues, Qnil);
         | 
| 123 | 
            -
                    break;
         | 
| 124 | 
            -
                  case EvtVarTypeString:
         | 
| 125 | 
            -
                    if (pRenderedValues[i].StringVal == nullptr) {
         | 
| 126 | 
            -
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("(NULL)"));
         | 
| 127 | 
            -
                    } else {
         | 
| 128 | 
            -
                      std::wstring wStr(pRenderedValues[i].StringVal);
         | 
| 129 | 
            -
                      rbObj = wstr_to_rb_str(CP_UTF8, &wStr[0], -1);
         | 
| 130 | 
            -
                      rb_ary_push(userValues, rbObj);
         | 
| 131 | 
            -
                    }
         | 
| 132 | 
            -
                    break;
         | 
| 133 | 
            -
                  case EvtVarTypeAnsiString:
         | 
| 134 | 
            -
                    if (pRenderedValues[i].AnsiStringVal == nullptr) {
         | 
| 135 | 
            -
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("(NULL)"));
         | 
| 136 | 
            -
                    } else {
         | 
| 137 | 
            -
                      rb_ary_push(
         | 
| 138 | 
            -
                        userValues,
         | 
| 139 | 
            -
                        rb_utf8_str_new_cstr(const_cast<char*>(pRenderedValues[i].AnsiStringVal)));
         | 
| 140 | 
            -
                    }
         | 
| 141 | 
            -
                    break;
         | 
| 142 | 
            -
                  case EvtVarTypeSByte:
         | 
| 143 | 
            -
                    rbObj = INT2NUM(static_cast<UINT32>(pRenderedValues[i].SByteVal));
         | 
| 144 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 145 | 
            -
                    break;
         | 
| 146 | 
            -
                  case EvtVarTypeByte:
         | 
| 147 | 
            -
                    rbObj = INT2NUM(static_cast<UINT32>(pRenderedValues[i].ByteVal));
         | 
| 148 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 149 | 
            -
                    break;
         | 
| 150 | 
            -
                  case EvtVarTypeInt16:
         | 
| 151 | 
            -
                    rbObj = INT2NUM(static_cast<INT32>(pRenderedValues[i].Int16Val));
         | 
| 152 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 153 | 
            -
                    break;
         | 
| 154 | 
            -
                  case EvtVarTypeUInt16:
         | 
| 155 | 
            -
                    rbObj = UINT2NUM(static_cast<UINT32>(pRenderedValues[i].UInt16Val));
         | 
| 156 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 157 | 
            -
                    break;
         | 
| 158 | 
            -
                  case EvtVarTypeInt32:
         | 
| 159 | 
            -
                    rbObj = INT2NUM(pRenderedValues[i].Int32Val);
         | 
| 160 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 161 | 
            -
                    break;
         | 
| 162 | 
            -
                  case EvtVarTypeUInt32:
         | 
| 163 | 
            -
                    rbObj = UINT2NUM(pRenderedValues[i].UInt32Val);
         | 
| 164 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 165 | 
            -
                    break;
         | 
| 166 | 
            -
                  case EvtVarTypeInt64:
         | 
| 167 | 
            -
                    rbObj = LONG2NUM(pRenderedValues[i].Int64Val);
         | 
| 168 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 169 | 
            -
                    break;
         | 
| 170 | 
            -
                  case EvtVarTypeUInt64:
         | 
| 171 | 
            -
                    rbObj = ULONG2NUM(pRenderedValues[i].UInt64Val);
         | 
| 172 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 173 | 
            -
                    break;
         | 
| 174 | 
            -
                  case EvtVarTypeSingle: {
         | 
| 175 | 
            -
                    CHAR sResult[256];
         | 
| 176 | 
            -
                    _snprintf_s(
         | 
| 177 | 
            -
                      sResult, _countof(sResult), _TRUNCATE, "%f", pRenderedValues[i].SingleVal);
         | 
| 178 | 
            -
                    rb_ary_push(userValues, rb_utf8_str_new_cstr(sResult));
         | 
| 179 | 
            -
                    break;
         | 
| 180 | 
            -
                  }
         | 
| 181 | 
            -
                  case EvtVarTypeDouble: {
         | 
| 182 | 
            -
                    CHAR sResult[256];
         | 
| 183 | 
            -
                    _snprintf_s(
         | 
| 184 | 
            -
                      sResult, _countof(sResult), _TRUNCATE, "%lf", pRenderedValues[i].DoubleVal);
         | 
| 185 | 
            -
                    rb_ary_push(userValues, rb_utf8_str_new_cstr(sResult));
         | 
| 186 | 
            -
                    break;
         | 
| 187 | 
            -
                  }
         | 
| 188 | 
            -
                  case EvtVarTypeBoolean:
         | 
| 189 | 
            -
                    rbObj = pRenderedValues[i].BooleanVal ? Qtrue : Qfalse;
         | 
| 190 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 191 | 
            -
                    break;
         | 
| 192 | 
            -
                  case EvtVarTypeGuid:
         | 
| 193 | 
            -
                    if (pRenderedValues[i].GuidVal != nullptr) {
         | 
| 194 | 
            -
                      const GUID guid = *pRenderedValues[i].GuidVal;
         | 
| 195 | 
            -
                      std::wstring wstr = guid_to_wstr(guid);
         | 
| 196 | 
            -
                      rbObj = wstr_to_rb_str(CP_UTF8, wstr.c_str(), -1);
         | 
| 197 | 
            -
                      rb_ary_push(userValues, rbObj);
         | 
| 198 | 
            -
                    } else {
         | 
| 199 | 
            -
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
         | 
| 200 | 
            -
                    }
         | 
| 201 | 
            -
                    break;
         | 
| 202 | 
            -
                  case EvtVarTypeSizeT:
         | 
| 203 | 
            -
                    rbObj = SIZET2NUM(pRenderedValues[i].SizeTVal);
         | 
| 204 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 205 | 
            -
                    break;
         | 
| 206 | 
            -
                  case EvtVarTypeFileTime: {
         | 
| 207 | 
            -
                    LARGE_INTEGER timestamp;
         | 
| 208 | 
            -
                    CHAR strTime[128];
         | 
| 209 | 
            -
                    FILETIME ft;
         | 
| 210 | 
            -
                    SYSTEMTIME st;
         | 
| 211 | 
            -
                    timestamp.QuadPart = pRenderedValues[i].FileTimeVal;
         | 
| 212 | 
            -
                    ft.dwHighDateTime = timestamp.HighPart;
         | 
| 213 | 
            -
                    ft.dwLowDateTime = timestamp.LowPart;
         | 
| 214 | 
            -
                    if (FileTimeToSystemTime(&ft, &st)) {
         | 
| 215 | 
            -
                      _snprintf_s(strTime,
         | 
| 216 | 
            -
                                  _countof(strTime),
         | 
| 217 | 
            -
                                  _TRUNCATE,
         | 
| 218 | 
            -
                                  "%04d-%02d-%02d %02d:%02d:%02d.%dZ",
         | 
| 219 | 
            -
                                  st.wYear,
         | 
| 220 | 
            -
                                  st.wMonth,
         | 
| 221 | 
            -
                                  st.wDay,
         | 
| 222 | 
            -
                                  st.wHour,
         | 
| 223 | 
            -
                                  st.wMinute,
         | 
| 224 | 
            -
                                  st.wSecond,
         | 
| 225 | 
            -
                                  st.wMilliseconds);
         | 
| 226 | 
            -
                      rb_ary_push(userValues, rb_utf8_str_new_cstr(strTime));
         | 
| 227 | 
            -
                    } else {
         | 
| 228 | 
            -
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
         | 
| 229 | 
            -
                    }
         | 
| 230 | 
            -
                    break;
         | 
| 231 | 
            -
                  }
         | 
| 232 | 
            -
                  case EvtVarTypeSysTime: {
         | 
| 233 | 
            -
                    CHAR strTime[128];
         | 
| 234 | 
            -
                    SYSTEMTIME st;
         | 
| 235 | 
            -
                    if (pRenderedValues[i].SysTimeVal != nullptr) {
         | 
| 236 | 
            -
                      st = *pRenderedValues[i].SysTimeVal;
         | 
| 237 | 
            -
                      _snprintf_s(strTime,
         | 
| 238 | 
            -
                                  _countof(strTime),
         | 
| 239 | 
            -
                                  _TRUNCATE,
         | 
| 240 | 
            -
                                  "%04d-%02d-%02d %02d:%02d:%02d.%dZ",
         | 
| 241 | 
            -
                                  st.wYear,
         | 
| 242 | 
            -
                                  st.wMonth,
         | 
| 243 | 
            -
                                  st.wDay,
         | 
| 244 | 
            -
                                  st.wHour,
         | 
| 245 | 
            -
                                  st.wMinute,
         | 
| 246 | 
            -
                                  st.wSecond,
         | 
| 247 | 
            -
                                  st.wMilliseconds);
         | 
| 248 | 
            -
                      rb_ary_push(userValues, rb_utf8_str_new_cstr(strTime));
         | 
| 249 | 
            -
                    } else {
         | 
| 250 | 
            -
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
         | 
| 251 | 
            -
                    }
         | 
| 252 | 
            -
                    break;
         | 
| 253 | 
            -
                  }
         | 
| 254 | 
            -
                  case EvtVarTypeSid: {
         | 
| 255 | 
            -
                    WCHAR* tmpWChar = nullptr;
         | 
| 256 | 
            -
                    if (ConvertSidToStringSidW(pRenderedValues[i].SidVal, &tmpWChar)) {
         | 
| 257 | 
            -
                      rbObj = wstr_to_rb_str(CP_UTF8, tmpWChar, -1);
         | 
| 258 | 
            -
                      rb_ary_push(userValues, rbObj);
         | 
| 259 | 
            -
                      LocalFree(tmpWChar);
         | 
| 260 | 
            -
                    } else {
         | 
| 261 | 
            -
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
         | 
| 262 | 
            -
                    }
         | 
| 263 | 
            -
                    break;
         | 
| 264 | 
            -
                  }
         | 
| 265 | 
            -
                  case EvtVarTypeHexInt32:
         | 
| 266 | 
            -
                    rbObj = rb_sprintf("%#x", pRenderedValues[i].UInt32Val);
         | 
| 267 | 
            -
                    rb_ary_push(userValues, rbObj);
         | 
| 268 | 
            -
                    break;
         | 
| 269 | 
            -
                  case EvtVarTypeHexInt64:
         | 
| 270 | 
            -
                     | 
| 271 | 
            -
                     | 
| 272 | 
            -
             | 
| 273 | 
            -
             | 
| 274 | 
            -
                     | 
| 275 | 
            -
             | 
| 276 | 
            -
                     | 
| 277 | 
            -
             | 
| 278 | 
            -
             | 
| 279 | 
            -
                     | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
             | 
| 284 | 
            -
             | 
| 285 | 
            -
             | 
| 286 | 
            -
             | 
| 287 | 
            -
             | 
| 288 | 
            -
             | 
| 289 | 
            -
             | 
| 290 | 
            -
             | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
             | 
| 296 | 
            -
             | 
| 297 | 
            -
             | 
| 298 | 
            -
               | 
| 299 | 
            -
               | 
| 300 | 
            -
             | 
| 301 | 
            -
               | 
| 302 | 
            -
               | 
| 303 | 
            -
             | 
| 304 | 
            -
               | 
| 305 | 
            -
             | 
| 306 | 
            -
               | 
| 307 | 
            -
               | 
| 308 | 
            -
                 | 
| 309 | 
            -
             | 
| 310 | 
            -
             | 
| 311 | 
            -
               | 
| 312 | 
            -
             | 
| 313 | 
            -
             | 
| 314 | 
            -
             | 
| 315 | 
            -
             | 
| 316 | 
            -
             | 
| 317 | 
            -
             | 
| 318 | 
            -
             | 
| 319 | 
            -
                                     | 
| 320 | 
            -
             | 
| 321 | 
            -
             | 
| 322 | 
            -
             | 
| 323 | 
            -
             | 
| 324 | 
            -
             | 
| 325 | 
            -
               | 
| 326 | 
            -
             | 
| 327 | 
            -
             | 
| 328 | 
            -
             | 
| 329 | 
            -
             | 
| 330 | 
            -
               | 
| 331 | 
            -
             | 
| 332 | 
            -
               | 
| 333 | 
            -
             | 
| 334 | 
            -
             | 
| 335 | 
            -
             | 
| 336 | 
            -
             | 
| 337 | 
            -
             | 
| 338 | 
            -
             | 
| 339 | 
            -
             | 
| 340 | 
            -
             | 
| 341 | 
            -
             | 
| 342 | 
            -
             | 
| 343 | 
            -
             | 
| 344 | 
            -
             | 
| 345 | 
            -
               | 
| 346 | 
            -
             | 
| 347 | 
            -
             | 
| 348 | 
            -
             | 
| 349 | 
            -
             | 
| 350 | 
            -
             | 
| 351 | 
            -
                                     | 
| 352 | 
            -
                                     | 
| 353 | 
            -
                                     | 
| 354 | 
            -
             | 
| 355 | 
            -
             | 
| 356 | 
            -
             | 
| 357 | 
            -
             | 
| 358 | 
            -
             | 
| 359 | 
            -
             | 
| 360 | 
            -
             | 
| 361 | 
            -
             | 
| 362 | 
            -
             | 
| 363 | 
            -
                    case  | 
| 364 | 
            -
             | 
| 365 | 
            -
             | 
| 366 | 
            -
             | 
| 367 | 
            -
             | 
| 368 | 
            -
             | 
| 369 | 
            -
             | 
| 370 | 
            -
             | 
| 371 | 
            -
                                         nullptr | 
| 372 | 
            -
             | 
| 373 | 
            -
                                          | 
| 374 | 
            -
             | 
| 375 | 
            -
             | 
| 376 | 
            -
             | 
| 377 | 
            -
             | 
| 378 | 
            -
             | 
| 379 | 
            -
                                       nullptr | 
| 380 | 
            -
             | 
| 381 | 
            -
             | 
| 382 | 
            -
             | 
| 383 | 
            -
             | 
| 384 | 
            -
             | 
| 385 | 
            -
             | 
| 386 | 
            -
             | 
| 387 | 
            -
             | 
| 388 | 
            -
             | 
| 389 | 
            -
             | 
| 390 | 
            -
             | 
| 391 | 
            -
             | 
| 392 | 
            -
             | 
| 393 | 
            -
             | 
| 394 | 
            -
                   | 
| 395 | 
            -
             | 
| 396 | 
            -
             | 
| 397 | 
            -
             | 
| 398 | 
            -
             | 
| 399 | 
            -
             | 
| 400 | 
            -
             | 
| 401 | 
            -
             | 
| 402 | 
            -
             | 
| 403 | 
            -
                                         | 
| 404 | 
            -
                                         | 
| 405 | 
            -
                                         | 
| 406 | 
            -
             | 
| 407 | 
            -
             | 
| 408 | 
            -
             | 
| 409 | 
            -
             | 
| 410 | 
            -
             | 
| 411 | 
            -
             | 
| 412 | 
            -
             | 
| 413 | 
            -
             | 
| 414 | 
            -
             | 
| 415 | 
            -
                        case  | 
| 416 | 
            -
             | 
| 417 | 
            -
             | 
| 418 | 
            -
             | 
| 419 | 
            -
             | 
| 420 | 
            -
             | 
| 421 | 
            -
             | 
| 422 | 
            -
             | 
| 423 | 
            -
             | 
| 424 | 
            -
                                             nullptr | 
| 425 | 
            -
             | 
| 426 | 
            -
                                              | 
| 427 | 
            -
                                              | 
| 428 | 
            -
             | 
| 429 | 
            -
             | 
| 430 | 
            -
             | 
| 431 | 
            -
             | 
| 432 | 
            -
             | 
| 433 | 
            -
                                           nullptr | 
| 434 | 
            -
             | 
| 435 | 
            -
             | 
| 436 | 
            -
             | 
| 437 | 
            -
             | 
| 438 | 
            -
             | 
| 439 | 
            -
             | 
| 440 | 
            -
             | 
| 441 | 
            -
             | 
| 442 | 
            -
             | 
| 443 | 
            -
             | 
| 444 | 
            -
             | 
| 445 | 
            -
             | 
| 446 | 
            -
             | 
| 447 | 
            -
             | 
| 448 | 
            -
             | 
| 449 | 
            -
             | 
| 450 | 
            -
             | 
| 451 | 
            -
             | 
| 452 | 
            -
             | 
| 453 | 
            -
             | 
| 454 | 
            -
             | 
| 455 | 
            -
             | 
| 456 | 
            -
             | 
| 457 | 
            -
             | 
| 458 | 
            -
             | 
| 459 | 
            -
             | 
| 460 | 
            -
             | 
| 461 | 
            -
             | 
| 462 | 
            -
             | 
| 463 | 
            -
             | 
| 464 | 
            -
             | 
| 465 | 
            -
             | 
| 466 | 
            -
             | 
| 467 | 
            -
               | 
| 468 | 
            -
               | 
| 469 | 
            -
             | 
| 470 | 
            -
               | 
| 471 | 
            -
             | 
| 472 | 
            -
              }
         | 
| 473 | 
            -
             | 
| 474 | 
            -
             | 
| 475 | 
            -
             | 
| 476 | 
            -
             | 
| 477 | 
            -
             | 
| 478 | 
            -
             | 
| 479 | 
            -
             | 
| 480 | 
            -
                             | 
| 481 | 
            -
             | 
| 482 | 
            -
             | 
| 483 | 
            -
             | 
| 484 | 
            -
             | 
| 485 | 
            -
             | 
| 486 | 
            -
             | 
| 487 | 
            -
             | 
| 488 | 
            -
             | 
| 489 | 
            -
             | 
| 490 | 
            -
             | 
| 491 | 
            -
               | 
| 492 | 
            -
             | 
| 493 | 
            -
               | 
| 494 | 
            -
             | 
| 495 | 
            -
             | 
| 496 | 
            -
             | 
| 497 | 
            -
             | 
| 498 | 
            -
             | 
| 499 | 
            -
             | 
| 500 | 
            -
             | 
| 501 | 
            -
                 | 
| 502 | 
            -
                 | 
| 503 | 
            -
                 | 
| 504 | 
            -
             | 
| 505 | 
            -
             | 
| 506 | 
            -
             | 
| 507 | 
            -
             | 
| 508 | 
            -
             | 
| 509 | 
            -
             | 
| 510 | 
            -
             | 
| 511 | 
            -
             | 
| 512 | 
            -
             | 
| 513 | 
            -
             | 
| 514 | 
            -
             | 
| 515 | 
            -
             | 
| 516 | 
            -
             | 
| 517 | 
            -
             | 
| 518 | 
            -
             | 
| 519 | 
            -
             | 
| 520 | 
            -
             | 
| 521 | 
            -
             | 
| 522 | 
            -
             | 
| 523 | 
            -
             | 
| 524 | 
            -
             | 
| 525 | 
            -
             | 
| 526 | 
            -
             | 
| 527 | 
            -
             | 
| 528 | 
            -
             | 
| 529 | 
            -
               | 
| 530 | 
            -
               | 
| 531 | 
            -
               | 
| 532 | 
            -
               | 
| 533 | 
            -
               | 
| 534 | 
            -
               | 
| 535 | 
            -
               | 
| 536 | 
            -
               | 
| 537 | 
            -
               | 
| 538 | 
            -
               | 
| 539 | 
            -
               | 
| 540 | 
            -
               | 
| 541 | 
            -
             | 
| 542 | 
            -
               | 
| 543 | 
            -
               | 
| 544 | 
            -
             | 
| 545 | 
            -
             | 
| 546 | 
            -
             | 
| 547 | 
            -
             | 
| 548 | 
            -
              if ( | 
| 549 | 
            -
             | 
| 550 | 
            -
             | 
| 551 | 
            -
             | 
| 552 | 
            -
             | 
| 553 | 
            -
             | 
| 554 | 
            -
                              | 
| 555 | 
            -
             | 
| 556 | 
            -
             | 
| 557 | 
            -
             | 
| 558 | 
            -
             | 
| 559 | 
            -
             | 
| 560 | 
            -
             | 
| 561 | 
            -
             | 
| 562 | 
            -
             | 
| 563 | 
            -
             | 
| 564 | 
            -
             | 
| 565 | 
            -
             | 
| 566 | 
            -
                               | 
| 567 | 
            -
             | 
| 568 | 
            -
             | 
| 569 | 
            -
             | 
| 570 | 
            -
             | 
| 571 | 
            -
             | 
| 572 | 
            -
             | 
| 573 | 
            -
             | 
| 574 | 
            -
             | 
| 575 | 
            -
                   | 
| 576 | 
            -
             | 
| 577 | 
            -
             | 
| 578 | 
            -
             | 
| 579 | 
            -
                 | 
| 580 | 
            -
             | 
| 581 | 
            -
             | 
| 582 | 
            -
             | 
| 583 | 
            -
             | 
| 584 | 
            -
             | 
| 585 | 
            -
               | 
| 586 | 
            -
             | 
| 587 | 
            -
               | 
| 588 | 
            -
             | 
| 589 | 
            -
             | 
| 590 | 
            -
             | 
| 591 | 
            -
             | 
| 592 | 
            -
               | 
| 593 | 
            -
                 | 
| 594 | 
            -
             | 
| 595 | 
            -
             | 
| 596 | 
            -
             | 
| 597 | 
            -
               | 
| 598 | 
            -
                 | 
| 599 | 
            -
             | 
| 600 | 
            -
             | 
| 601 | 
            -
             | 
| 602 | 
            -
             | 
| 603 | 
            -
                 | 
| 604 | 
            -
             | 
| 605 | 
            -
             | 
| 606 | 
            -
             | 
| 607 | 
            -
             | 
| 608 | 
            -
             | 
| 609 | 
            -
             | 
| 610 | 
            -
                 | 
| 611 | 
            -
             | 
| 612 | 
            -
                 | 
| 613 | 
            -
             | 
| 614 | 
            -
             | 
| 615 | 
            -
             | 
| 616 | 
            -
             | 
| 617 | 
            -
             | 
| 618 | 
            -
             | 
| 619 | 
            -
             | 
| 620 | 
            -
              rb_hash_aset(hash,
         | 
| 621 | 
            -
                           rb_str_new2(" | 
| 622 | 
            -
                           (EvtVarTypeNull == pRenderedValues[ | 
| 623 | 
            -
                             ? INT2NUM(0)
         | 
| 624 | 
            -
                             : INT2NUM(pRenderedValues[ | 
| 625 | 
            -
              rb_hash_aset(hash,
         | 
| 626 | 
            -
                           rb_str_new2(" | 
| 627 | 
            -
                           (EvtVarTypeNull == pRenderedValues[ | 
| 628 | 
            -
                             ? INT2NUM(0)
         | 
| 629 | 
            -
                             : INT2NUM(pRenderedValues[ | 
| 630 | 
            -
              rb_hash_aset(hash,
         | 
| 631 | 
            -
                           rb_str_new2(" | 
| 632 | 
            -
                           (EvtVarTypeNull == pRenderedValues[ | 
| 633 | 
            -
                             ? INT2NUM(0)
         | 
| 634 | 
            -
                             : INT2NUM(pRenderedValues[ | 
| 635 | 
            -
               | 
| 636 | 
            -
             | 
| 637 | 
            -
             | 
| 638 | 
            -
             | 
| 639 | 
            -
             | 
| 640 | 
            -
               | 
| 641 | 
            -
             | 
| 642 | 
            -
             | 
| 643 | 
            -
             | 
| 644 | 
            -
             | 
| 645 | 
            -
             | 
| 646 | 
            -
             | 
| 647 | 
            -
             | 
| 648 | 
            -
             | 
| 649 | 
            -
             | 
| 650 | 
            -
             | 
| 651 | 
            -
               | 
| 652 | 
            -
             | 
| 653 | 
            -
             | 
| 654 | 
            -
             | 
| 655 | 
            -
             | 
| 656 | 
            -
             | 
| 657 | 
            -
             | 
| 658 | 
            -
             | 
| 659 | 
            -
             | 
| 660 | 
            -
                           | 
| 661 | 
            -
                           | 
| 662 | 
            -
                           | 
| 663 | 
            -
                          st. | 
| 664 | 
            -
                           | 
| 665 | 
            -
             | 
| 666 | 
            -
             | 
| 667 | 
            -
             | 
| 668 | 
            -
             | 
| 669 | 
            -
             | 
| 670 | 
            -
               | 
| 671 | 
            -
             | 
| 672 | 
            -
             | 
| 673 | 
            -
             | 
| 674 | 
            -
             | 
| 675 | 
            -
               | 
| 676 | 
            -
             | 
| 677 | 
            -
             | 
| 678 | 
            -
             | 
| 679 | 
            -
             | 
| 680 | 
            -
             | 
| 681 | 
            -
             | 
| 682 | 
            -
             | 
| 683 | 
            -
             | 
| 684 | 
            -
             | 
| 685 | 
            -
             | 
| 686 | 
            -
               | 
| 687 | 
            -
             | 
| 688 | 
            -
             | 
| 689 | 
            -
                 | 
| 690 | 
            -
                 | 
| 691 | 
            -
             | 
| 692 | 
            -
             | 
| 693 | 
            -
               | 
| 694 | 
            -
             | 
| 695 | 
            -
             | 
| 696 | 
            -
             | 
| 697 | 
            -
             | 
| 698 | 
            -
               | 
| 699 | 
            -
             | 
| 700 | 
            -
             | 
| 701 | 
            -
             | 
| 702 | 
            -
             | 
| 703 | 
            -
               | 
| 704 | 
            -
             | 
| 705 | 
            -
             | 
| 706 | 
            -
               | 
| 707 | 
            -
             | 
| 708 | 
            -
             | 
| 709 | 
            -
             | 
| 710 | 
            -
             | 
| 711 | 
            -
             | 
| 712 | 
            -
             | 
| 713 | 
            -
             | 
| 714 | 
            -
             | 
| 715 | 
            -
             | 
| 716 | 
            -
             | 
| 717 | 
            -
               | 
| 718 | 
            -
             | 
| 1 | 
            +
            #include <winevt_c.h>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            #include <sddl.h>
         | 
| 4 | 
            +
            #include <stdlib.h>
         | 
| 5 | 
            +
            #include <string>
         | 
| 6 | 
            +
            #include <vector>
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            VALUE
         | 
| 9 | 
            +
            wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen)
         | 
| 10 | 
            +
            {
         | 
| 11 | 
            +
              VALUE vstr;
         | 
| 12 | 
            +
              CHAR* ptr;
         | 
| 13 | 
            +
              int len = WideCharToMultiByte(cp, 0, wstr, clen, nullptr, 0, nullptr, nullptr);
         | 
| 14 | 
            +
              ptr = ALLOCV_N(CHAR, vstr, len);
         | 
| 15 | 
            +
              WideCharToMultiByte(cp, 0, wstr, clen, ptr, len, nullptr, nullptr);
         | 
| 16 | 
            +
              VALUE str = rb_utf8_str_new_cstr(ptr);
         | 
| 17 | 
            +
              ALLOCV_END(vstr);
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              return str;
         | 
| 20 | 
            +
            }
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            void
         | 
| 23 | 
            +
            raise_system_error(VALUE error, DWORD errorCode)
         | 
| 24 | 
            +
            {
         | 
| 25 | 
            +
              WCHAR msgBuf[256] = { 0 };
         | 
| 26 | 
            +
              VALUE errorMessage;
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
         | 
| 29 | 
            +
                             NULL,
         | 
| 30 | 
            +
                             errorCode,
         | 
| 31 | 
            +
                             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
         | 
| 32 | 
            +
                             msgBuf,
         | 
| 33 | 
            +
                             _countof(msgBuf),
         | 
| 34 | 
            +
                             NULL);
         | 
| 35 | 
            +
              errorMessage = wstr_to_rb_str(CP_UTF8, msgBuf, -1);
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            #pragma GCC diagnostic push
         | 
| 38 | 
            +
            #pragma GCC diagnostic ignored "-Wformat="
         | 
| 39 | 
            +
            #pragma GCC diagnostic ignored "-Wformat-extra-args"
         | 
| 40 | 
            +
              rb_raise(error, "ErrorCode: %lu\nError: %" PRIsVALUE "\n", errorCode, errorMessage);
         | 
| 41 | 
            +
            #pragma GCC diagnostic pop
         | 
| 42 | 
            +
            }
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            VALUE
         | 
| 45 | 
            +
            render_to_rb_str(EVT_HANDLE handle, DWORD flags)
         | 
| 46 | 
            +
            {
         | 
| 47 | 
            +
              VALUE vbuffer;
         | 
| 48 | 
            +
              WCHAR* buffer;
         | 
| 49 | 
            +
              ULONG bufferSize = 0;
         | 
| 50 | 
            +
              ULONG bufferSizeUsed = 0;
         | 
| 51 | 
            +
              ULONG count;
         | 
| 52 | 
            +
              BOOL succeeded;
         | 
| 53 | 
            +
              VALUE result;
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              if (flags != EvtRenderEventXml && flags != EvtRenderBookmark) {
         | 
| 56 | 
            +
                return Qnil;
         | 
| 57 | 
            +
              }
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              // Get the size of the buffer
         | 
| 60 | 
            +
              EvtRender(nullptr, handle, flags, 0, NULL, &bufferSize, &count);
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              // bufferSize is in bytes, not characters
         | 
| 63 | 
            +
              buffer = (WCHAR*)ALLOCV(vbuffer, bufferSize);
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              succeeded =
         | 
| 66 | 
            +
                EvtRender(nullptr, handle, flags, bufferSize, buffer, &bufferSizeUsed, &count);
         | 
| 67 | 
            +
              if (!succeeded) {
         | 
| 68 | 
            +
                DWORD status = GetLastError();
         | 
| 69 | 
            +
                ALLOCV_END(vbuffer);
         | 
| 70 | 
            +
                raise_system_error(rb_eWinevtQueryError, status);
         | 
| 71 | 
            +
              }
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              result = wstr_to_rb_str(CP_UTF8, buffer, -1);
         | 
| 74 | 
            +
              ALLOCV_END(vbuffer);
         | 
| 75 | 
            +
             | 
| 76 | 
            +
              return result;
         | 
| 77 | 
            +
            }
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            EVT_HANDLE
         | 
| 80 | 
            +
            connect_to_remote(LPWSTR computerName, LPWSTR domain, LPWSTR username, LPWSTR password,
         | 
| 81 | 
            +
                              EVT_RPC_LOGIN_FLAGS flags)
         | 
| 82 | 
            +
            {
         | 
| 83 | 
            +
              EVT_HANDLE hRemote = NULL;
         | 
| 84 | 
            +
              EVT_RPC_LOGIN Credentials;
         | 
| 85 | 
            +
             | 
| 86 | 
            +
              RtlZeroMemory(&Credentials, sizeof(EVT_RPC_LOGIN));
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              Credentials.Server = computerName;
         | 
| 89 | 
            +
              Credentials.Domain = domain;
         | 
| 90 | 
            +
              Credentials.User = username;
         | 
| 91 | 
            +
              Credentials.Password = password;
         | 
| 92 | 
            +
              Credentials.Flags = flags;
         | 
| 93 | 
            +
             | 
| 94 | 
            +
              hRemote = EvtOpenSession(EvtRpcLogin, &Credentials, 0, 0);
         | 
| 95 | 
            +
             | 
| 96 | 
            +
              SecureZeroMemory(&Credentials, sizeof(EVT_RPC_LOGIN));
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              return hRemote;
         | 
| 99 | 
            +
            }
         | 
| 100 | 
            +
             | 
| 101 | 
            +
            static std::wstring
         | 
| 102 | 
            +
            guid_to_wstr(const GUID& guid)
         | 
| 103 | 
            +
            {
         | 
| 104 | 
            +
              LPOLESTR p = nullptr;
         | 
| 105 | 
            +
              if (FAILED(StringFromCLSID(guid, &p))) {
         | 
| 106 | 
            +
                return nullptr;
         | 
| 107 | 
            +
              }
         | 
| 108 | 
            +
              std::wstring s(p);
         | 
| 109 | 
            +
              CoTaskMemFree(p);
         | 
| 110 | 
            +
              return s;
         | 
| 111 | 
            +
            }
         | 
| 112 | 
            +
             | 
| 113 | 
            +
            static VALUE
         | 
| 114 | 
            +
            extract_user_evt_variants(PEVT_VARIANT pRenderedValues, DWORD propCount)
         | 
| 115 | 
            +
            {
         | 
| 116 | 
            +
              VALUE userValues = rb_ary_new();
         | 
| 117 | 
            +
              VALUE rbObj;
         | 
| 118 | 
            +
             | 
| 119 | 
            +
              for (DWORD i = 0; i < propCount; i++) {
         | 
| 120 | 
            +
                switch (pRenderedValues[i].Type) {
         | 
| 121 | 
            +
                  case EvtVarTypeNull:
         | 
| 122 | 
            +
                    rb_ary_push(userValues, Qnil);
         | 
| 123 | 
            +
                    break;
         | 
| 124 | 
            +
                  case EvtVarTypeString:
         | 
| 125 | 
            +
                    if (pRenderedValues[i].StringVal == nullptr) {
         | 
| 126 | 
            +
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("(NULL)"));
         | 
| 127 | 
            +
                    } else {
         | 
| 128 | 
            +
                      std::wstring wStr(pRenderedValues[i].StringVal);
         | 
| 129 | 
            +
                      rbObj = wstr_to_rb_str(CP_UTF8, &wStr[0], -1);
         | 
| 130 | 
            +
                      rb_ary_push(userValues, rbObj);
         | 
| 131 | 
            +
                    }
         | 
| 132 | 
            +
                    break;
         | 
| 133 | 
            +
                  case EvtVarTypeAnsiString:
         | 
| 134 | 
            +
                    if (pRenderedValues[i].AnsiStringVal == nullptr) {
         | 
| 135 | 
            +
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("(NULL)"));
         | 
| 136 | 
            +
                    } else {
         | 
| 137 | 
            +
                      rb_ary_push(
         | 
| 138 | 
            +
                        userValues,
         | 
| 139 | 
            +
                        rb_utf8_str_new_cstr(const_cast<char*>(pRenderedValues[i].AnsiStringVal)));
         | 
| 140 | 
            +
                    }
         | 
| 141 | 
            +
                    break;
         | 
| 142 | 
            +
                  case EvtVarTypeSByte:
         | 
| 143 | 
            +
                    rbObj = INT2NUM(static_cast<UINT32>(pRenderedValues[i].SByteVal));
         | 
| 144 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 145 | 
            +
                    break;
         | 
| 146 | 
            +
                  case EvtVarTypeByte:
         | 
| 147 | 
            +
                    rbObj = INT2NUM(static_cast<UINT32>(pRenderedValues[i].ByteVal));
         | 
| 148 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 149 | 
            +
                    break;
         | 
| 150 | 
            +
                  case EvtVarTypeInt16:
         | 
| 151 | 
            +
                    rbObj = INT2NUM(static_cast<INT32>(pRenderedValues[i].Int16Val));
         | 
| 152 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 153 | 
            +
                    break;
         | 
| 154 | 
            +
                  case EvtVarTypeUInt16:
         | 
| 155 | 
            +
                    rbObj = UINT2NUM(static_cast<UINT32>(pRenderedValues[i].UInt16Val));
         | 
| 156 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 157 | 
            +
                    break;
         | 
| 158 | 
            +
                  case EvtVarTypeInt32:
         | 
| 159 | 
            +
                    rbObj = INT2NUM(pRenderedValues[i].Int32Val);
         | 
| 160 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 161 | 
            +
                    break;
         | 
| 162 | 
            +
                  case EvtVarTypeUInt32:
         | 
| 163 | 
            +
                    rbObj = UINT2NUM(pRenderedValues[i].UInt32Val);
         | 
| 164 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 165 | 
            +
                    break;
         | 
| 166 | 
            +
                  case EvtVarTypeInt64:
         | 
| 167 | 
            +
                    rbObj = LONG2NUM(pRenderedValues[i].Int64Val);
         | 
| 168 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 169 | 
            +
                    break;
         | 
| 170 | 
            +
                  case EvtVarTypeUInt64:
         | 
| 171 | 
            +
                    rbObj = ULONG2NUM(pRenderedValues[i].UInt64Val);
         | 
| 172 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 173 | 
            +
                    break;
         | 
| 174 | 
            +
                  case EvtVarTypeSingle: {
         | 
| 175 | 
            +
                    CHAR sResult[256];
         | 
| 176 | 
            +
                    _snprintf_s(
         | 
| 177 | 
            +
                      sResult, _countof(sResult), _TRUNCATE, "%f", pRenderedValues[i].SingleVal);
         | 
| 178 | 
            +
                    rb_ary_push(userValues, rb_utf8_str_new_cstr(sResult));
         | 
| 179 | 
            +
                    break;
         | 
| 180 | 
            +
                  }
         | 
| 181 | 
            +
                  case EvtVarTypeDouble: {
         | 
| 182 | 
            +
                    CHAR sResult[256];
         | 
| 183 | 
            +
                    _snprintf_s(
         | 
| 184 | 
            +
                      sResult, _countof(sResult), _TRUNCATE, "%lf", pRenderedValues[i].DoubleVal);
         | 
| 185 | 
            +
                    rb_ary_push(userValues, rb_utf8_str_new_cstr(sResult));
         | 
| 186 | 
            +
                    break;
         | 
| 187 | 
            +
                  }
         | 
| 188 | 
            +
                  case EvtVarTypeBoolean:
         | 
| 189 | 
            +
                    rbObj = pRenderedValues[i].BooleanVal ? Qtrue : Qfalse;
         | 
| 190 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 191 | 
            +
                    break;
         | 
| 192 | 
            +
                  case EvtVarTypeGuid:
         | 
| 193 | 
            +
                    if (pRenderedValues[i].GuidVal != nullptr) {
         | 
| 194 | 
            +
                      const GUID guid = *pRenderedValues[i].GuidVal;
         | 
| 195 | 
            +
                      std::wstring wstr = guid_to_wstr(guid);
         | 
| 196 | 
            +
                      rbObj = wstr_to_rb_str(CP_UTF8, wstr.c_str(), -1);
         | 
| 197 | 
            +
                      rb_ary_push(userValues, rbObj);
         | 
| 198 | 
            +
                    } else {
         | 
| 199 | 
            +
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
         | 
| 200 | 
            +
                    }
         | 
| 201 | 
            +
                    break;
         | 
| 202 | 
            +
                  case EvtVarTypeSizeT:
         | 
| 203 | 
            +
                    rbObj = SIZET2NUM(pRenderedValues[i].SizeTVal);
         | 
| 204 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 205 | 
            +
                    break;
         | 
| 206 | 
            +
                  case EvtVarTypeFileTime: {
         | 
| 207 | 
            +
                    LARGE_INTEGER timestamp;
         | 
| 208 | 
            +
                    CHAR strTime[128];
         | 
| 209 | 
            +
                    FILETIME ft;
         | 
| 210 | 
            +
                    SYSTEMTIME st;
         | 
| 211 | 
            +
                    timestamp.QuadPart = pRenderedValues[i].FileTimeVal;
         | 
| 212 | 
            +
                    ft.dwHighDateTime = timestamp.HighPart;
         | 
| 213 | 
            +
                    ft.dwLowDateTime = timestamp.LowPart;
         | 
| 214 | 
            +
                    if (FileTimeToSystemTime(&ft, &st)) {
         | 
| 215 | 
            +
                      _snprintf_s(strTime,
         | 
| 216 | 
            +
                                  _countof(strTime),
         | 
| 217 | 
            +
                                  _TRUNCATE,
         | 
| 218 | 
            +
                                  "%04d-%02d-%02d %02d:%02d:%02d.%dZ",
         | 
| 219 | 
            +
                                  st.wYear,
         | 
| 220 | 
            +
                                  st.wMonth,
         | 
| 221 | 
            +
                                  st.wDay,
         | 
| 222 | 
            +
                                  st.wHour,
         | 
| 223 | 
            +
                                  st.wMinute,
         | 
| 224 | 
            +
                                  st.wSecond,
         | 
| 225 | 
            +
                                  st.wMilliseconds);
         | 
| 226 | 
            +
                      rb_ary_push(userValues, rb_utf8_str_new_cstr(strTime));
         | 
| 227 | 
            +
                    } else {
         | 
| 228 | 
            +
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
         | 
| 229 | 
            +
                    }
         | 
| 230 | 
            +
                    break;
         | 
| 231 | 
            +
                  }
         | 
| 232 | 
            +
                  case EvtVarTypeSysTime: {
         | 
| 233 | 
            +
                    CHAR strTime[128];
         | 
| 234 | 
            +
                    SYSTEMTIME st;
         | 
| 235 | 
            +
                    if (pRenderedValues[i].SysTimeVal != nullptr) {
         | 
| 236 | 
            +
                      st = *pRenderedValues[i].SysTimeVal;
         | 
| 237 | 
            +
                      _snprintf_s(strTime,
         | 
| 238 | 
            +
                                  _countof(strTime),
         | 
| 239 | 
            +
                                  _TRUNCATE,
         | 
| 240 | 
            +
                                  "%04d-%02d-%02d %02d:%02d:%02d.%dZ",
         | 
| 241 | 
            +
                                  st.wYear,
         | 
| 242 | 
            +
                                  st.wMonth,
         | 
| 243 | 
            +
                                  st.wDay,
         | 
| 244 | 
            +
                                  st.wHour,
         | 
| 245 | 
            +
                                  st.wMinute,
         | 
| 246 | 
            +
                                  st.wSecond,
         | 
| 247 | 
            +
                                  st.wMilliseconds);
         | 
| 248 | 
            +
                      rb_ary_push(userValues, rb_utf8_str_new_cstr(strTime));
         | 
| 249 | 
            +
                    } else {
         | 
| 250 | 
            +
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
         | 
| 251 | 
            +
                    }
         | 
| 252 | 
            +
                    break;
         | 
| 253 | 
            +
                  }
         | 
| 254 | 
            +
                  case EvtVarTypeSid: {
         | 
| 255 | 
            +
                    WCHAR* tmpWChar = nullptr;
         | 
| 256 | 
            +
                    if (ConvertSidToStringSidW(pRenderedValues[i].SidVal, &tmpWChar)) {
         | 
| 257 | 
            +
                      rbObj = wstr_to_rb_str(CP_UTF8, tmpWChar, -1);
         | 
| 258 | 
            +
                      rb_ary_push(userValues, rbObj);
         | 
| 259 | 
            +
                      LocalFree(tmpWChar);
         | 
| 260 | 
            +
                    } else {
         | 
| 261 | 
            +
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
         | 
| 262 | 
            +
                    }
         | 
| 263 | 
            +
                    break;
         | 
| 264 | 
            +
                  }
         | 
| 265 | 
            +
                  case EvtVarTypeHexInt32:
         | 
| 266 | 
            +
                    rbObj = rb_sprintf("%#x", pRenderedValues[i].UInt32Val);
         | 
| 267 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 268 | 
            +
                    break;
         | 
| 269 | 
            +
                  case EvtVarTypeHexInt64:
         | 
| 270 | 
            +
                    uint32_t  high;
         | 
| 271 | 
            +
                    uint32_t  low;
         | 
| 272 | 
            +
             | 
| 273 | 
            +
                    high = pRenderedValues[i].UInt64Val >> 32;
         | 
| 274 | 
            +
                    low = pRenderedValues[i].UInt64Val & 0x00000000FFFFFFFF;
         | 
| 275 | 
            +
                    rbObj = rb_sprintf("0x%08x%08x", high, low);
         | 
| 276 | 
            +
                    rb_ary_push(userValues, rbObj);
         | 
| 277 | 
            +
                    break;
         | 
| 278 | 
            +
                  case EvtVarTypeEvtXml:
         | 
| 279 | 
            +
                    if (pRenderedValues[i].XmlVal == nullptr) {
         | 
| 280 | 
            +
                      rb_ary_push(userValues, rb_utf8_str_new_cstr("(NULL)"));
         | 
| 281 | 
            +
                    } else {
         | 
| 282 | 
            +
                      rbObj = wstr_to_rb_str(CP_UTF8, pRenderedValues[i].XmlVal, -1);
         | 
| 283 | 
            +
                      rb_ary_push(userValues, rbObj);
         | 
| 284 | 
            +
                    }
         | 
| 285 | 
            +
                    break;
         | 
| 286 | 
            +
                  default:
         | 
| 287 | 
            +
                    rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
         | 
| 288 | 
            +
                    break;
         | 
| 289 | 
            +
                }
         | 
| 290 | 
            +
              }
         | 
| 291 | 
            +
             | 
| 292 | 
            +
              return userValues;
         | 
| 293 | 
            +
            }
         | 
| 294 | 
            +
             | 
| 295 | 
            +
            VALUE
         | 
| 296 | 
            +
            get_values(EVT_HANDLE handle)
         | 
| 297 | 
            +
            {
         | 
| 298 | 
            +
              VALUE vbuffer;
         | 
| 299 | 
            +
              PEVT_VARIANT pRenderedValues;
         | 
| 300 | 
            +
              ULONG bufferSize = 0;
         | 
| 301 | 
            +
              ULONG bufferSizeUsed = 0;
         | 
| 302 | 
            +
              DWORD propCount = 0;
         | 
| 303 | 
            +
              BOOL succeeded;
         | 
| 304 | 
            +
              VALUE userValues = Qnil;
         | 
| 305 | 
            +
             | 
| 306 | 
            +
              EVT_HANDLE renderContext = EvtCreateRenderContext(0, nullptr, EvtRenderContextUser);
         | 
| 307 | 
            +
              if (renderContext == nullptr) {
         | 
| 308 | 
            +
                rb_raise(rb_eWinevtQueryError, "Failed to create renderContext");
         | 
| 309 | 
            +
              }
         | 
| 310 | 
            +
             | 
| 311 | 
            +
              // Get the size of the buffer
         | 
| 312 | 
            +
              EvtRender(
         | 
| 313 | 
            +
                renderContext, handle, EvtRenderEventValues, 0, NULL, &bufferSize, &propCount);
         | 
| 314 | 
            +
             | 
| 315 | 
            +
              // bufferSize is in bytes, not array size
         | 
| 316 | 
            +
              pRenderedValues = (PEVT_VARIANT)ALLOCV(vbuffer, bufferSize);
         | 
| 317 | 
            +
             | 
| 318 | 
            +
              succeeded = EvtRender(renderContext,
         | 
| 319 | 
            +
                                    handle,
         | 
| 320 | 
            +
                                    EvtRenderEventValues,
         | 
| 321 | 
            +
                                    bufferSize,
         | 
| 322 | 
            +
                                    pRenderedValues,
         | 
| 323 | 
            +
                                    &bufferSizeUsed,
         | 
| 324 | 
            +
                                    &propCount);
         | 
| 325 | 
            +
              if (!succeeded) {
         | 
| 326 | 
            +
                DWORD status = GetLastError();
         | 
| 327 | 
            +
                ALLOCV_END(vbuffer);
         | 
| 328 | 
            +
                EvtClose(renderContext);
         | 
| 329 | 
            +
                raise_system_error(rb_eWinevtQueryError, status);
         | 
| 330 | 
            +
              }
         | 
| 331 | 
            +
             | 
| 332 | 
            +
              userValues = extract_user_evt_variants(pRenderedValues, propCount);
         | 
| 333 | 
            +
             | 
| 334 | 
            +
              ALLOCV_END(vbuffer);
         | 
| 335 | 
            +
              EvtClose(renderContext);
         | 
| 336 | 
            +
             | 
| 337 | 
            +
              return userValues;
         | 
| 338 | 
            +
            }
         | 
| 339 | 
            +
             | 
| 340 | 
            +
            static std::vector<WCHAR>
         | 
| 341 | 
            +
            get_message(EVT_HANDLE hMetadata, EVT_HANDLE handle)
         | 
| 342 | 
            +
            {
         | 
| 343 | 
            +
            #define BUFSIZE 4096
         | 
| 344 | 
            +
              std::vector<WCHAR> result;
         | 
| 345 | 
            +
              ULONG status;
         | 
| 346 | 
            +
              ULONG bufferSizeNeeded = 0;
         | 
| 347 | 
            +
              LPVOID lpMsgBuf;
         | 
| 348 | 
            +
              std::vector<WCHAR> message(BUFSIZE);
         | 
| 349 | 
            +
             | 
| 350 | 
            +
              if (!EvtFormatMessage(hMetadata,
         | 
| 351 | 
            +
                                    handle,
         | 
| 352 | 
            +
                                    0xffffffff,
         | 
| 353 | 
            +
                                    0,
         | 
| 354 | 
            +
                                    nullptr,
         | 
| 355 | 
            +
                                    EvtFormatMessageEvent,
         | 
| 356 | 
            +
                                    message.size(),
         | 
| 357 | 
            +
                                    &message[0],
         | 
| 358 | 
            +
                                    &bufferSizeNeeded)) {
         | 
| 359 | 
            +
                status = GetLastError();
         | 
| 360 | 
            +
             | 
| 361 | 
            +
                if (status != ERROR_EVT_UNRESOLVED_VALUE_INSERT) {
         | 
| 362 | 
            +
                  switch (status) {
         | 
| 363 | 
            +
                    case ERROR_EVT_MESSAGE_NOT_FOUND:
         | 
| 364 | 
            +
                    case ERROR_EVT_MESSAGE_ID_NOT_FOUND:
         | 
| 365 | 
            +
                    case ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
         | 
| 366 | 
            +
                    case ERROR_RESOURCE_LANG_NOT_FOUND:
         | 
| 367 | 
            +
                    case ERROR_MUI_FILE_NOT_FOUND:
         | 
| 368 | 
            +
                    case ERROR_EVT_UNRESOLVED_PARAMETER_INSERT: {
         | 
| 369 | 
            +
                      if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
         | 
| 370 | 
            +
                                           FORMAT_MESSAGE_IGNORE_INSERTS,
         | 
| 371 | 
            +
                                         nullptr,
         | 
| 372 | 
            +
                                         status,
         | 
| 373 | 
            +
                                         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
         | 
| 374 | 
            +
                                         reinterpret_cast<WCHAR*>(&lpMsgBuf),
         | 
| 375 | 
            +
                                         0,
         | 
| 376 | 
            +
                                         nullptr) == 0)
         | 
| 377 | 
            +
                        FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
         | 
| 378 | 
            +
                                         FORMAT_MESSAGE_IGNORE_INSERTS,
         | 
| 379 | 
            +
                                       nullptr,
         | 
| 380 | 
            +
                                       status,
         | 
| 381 | 
            +
                                       MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
         | 
| 382 | 
            +
                                       reinterpret_cast<WCHAR*>(&lpMsgBuf),
         | 
| 383 | 
            +
                                       0,
         | 
| 384 | 
            +
                                       nullptr);
         | 
| 385 | 
            +
             | 
| 386 | 
            +
                      std::wstring ret(reinterpret_cast<WCHAR*>(lpMsgBuf));
         | 
| 387 | 
            +
                      std::copy(ret.begin(), ret.end(), std::back_inserter(result));
         | 
| 388 | 
            +
                      LocalFree(lpMsgBuf);
         | 
| 389 | 
            +
             | 
| 390 | 
            +
                      goto cleanup;
         | 
| 391 | 
            +
                    }
         | 
| 392 | 
            +
                  }
         | 
| 393 | 
            +
             | 
| 394 | 
            +
                  if (status != ERROR_INSUFFICIENT_BUFFER)
         | 
| 395 | 
            +
                    rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu", status);
         | 
| 396 | 
            +
                }
         | 
| 397 | 
            +
             | 
| 398 | 
            +
                if (status == ERROR_INSUFFICIENT_BUFFER) {
         | 
| 399 | 
            +
                  message.resize(bufferSizeNeeded);
         | 
| 400 | 
            +
                  message.shrink_to_fit();
         | 
| 401 | 
            +
             | 
| 402 | 
            +
                  if (!EvtFormatMessage(hMetadata,
         | 
| 403 | 
            +
                                        handle,
         | 
| 404 | 
            +
                                        0xffffffff,
         | 
| 405 | 
            +
                                        0,
         | 
| 406 | 
            +
                                        nullptr,
         | 
| 407 | 
            +
                                        EvtFormatMessageEvent,
         | 
| 408 | 
            +
                                        message.size(),
         | 
| 409 | 
            +
                                        &message.front(),
         | 
| 410 | 
            +
                                        &bufferSizeNeeded)) {
         | 
| 411 | 
            +
                    status = GetLastError();
         | 
| 412 | 
            +
             | 
| 413 | 
            +
                    if (status != ERROR_EVT_UNRESOLVED_VALUE_INSERT) {
         | 
| 414 | 
            +
                      switch (status) {
         | 
| 415 | 
            +
                        case ERROR_EVT_MESSAGE_NOT_FOUND:
         | 
| 416 | 
            +
                        case ERROR_EVT_MESSAGE_ID_NOT_FOUND:
         | 
| 417 | 
            +
                        case ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
         | 
| 418 | 
            +
                        case ERROR_RESOURCE_LANG_NOT_FOUND:
         | 
| 419 | 
            +
                        case ERROR_MUI_FILE_NOT_FOUND:
         | 
| 420 | 
            +
                        case ERROR_EVT_UNRESOLVED_PARAMETER_INSERT:
         | 
| 421 | 
            +
                          if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
         | 
| 422 | 
            +
                                               FORMAT_MESSAGE_FROM_SYSTEM |
         | 
| 423 | 
            +
                                               FORMAT_MESSAGE_IGNORE_INSERTS,
         | 
| 424 | 
            +
                                             nullptr,
         | 
| 425 | 
            +
                                             status,
         | 
| 426 | 
            +
                                             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
         | 
| 427 | 
            +
                                             reinterpret_cast<WCHAR*>(&lpMsgBuf),
         | 
| 428 | 
            +
                                             0,
         | 
| 429 | 
            +
                                             nullptr) == 0)
         | 
| 430 | 
            +
                            FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
         | 
| 431 | 
            +
                                             FORMAT_MESSAGE_FROM_SYSTEM |
         | 
| 432 | 
            +
                                             FORMAT_MESSAGE_IGNORE_INSERTS,
         | 
| 433 | 
            +
                                           nullptr,
         | 
| 434 | 
            +
                                           status,
         | 
| 435 | 
            +
                                           MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
         | 
| 436 | 
            +
                                           reinterpret_cast<WCHAR*>(&lpMsgBuf),
         | 
| 437 | 
            +
                                           0,
         | 
| 438 | 
            +
                                           nullptr);
         | 
| 439 | 
            +
             | 
| 440 | 
            +
                          std::wstring ret(reinterpret_cast<WCHAR*>(lpMsgBuf));
         | 
| 441 | 
            +
                          std::copy(ret.begin(), ret.end(), std::back_inserter(result));
         | 
| 442 | 
            +
                          LocalFree(lpMsgBuf);
         | 
| 443 | 
            +
             | 
| 444 | 
            +
                          goto cleanup;
         | 
| 445 | 
            +
                      }
         | 
| 446 | 
            +
             | 
| 447 | 
            +
                      rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu", status);
         | 
| 448 | 
            +
                    }
         | 
| 449 | 
            +
                  }
         | 
| 450 | 
            +
                }
         | 
| 451 | 
            +
              }
         | 
| 452 | 
            +
             | 
| 453 | 
            +
              result = message;
         | 
| 454 | 
            +
             | 
| 455 | 
            +
            cleanup:
         | 
| 456 | 
            +
             | 
| 457 | 
            +
              return result;
         | 
| 458 | 
            +
             | 
| 459 | 
            +
            #undef BUFSIZE
         | 
| 460 | 
            +
            }
         | 
| 461 | 
            +
             | 
| 462 | 
            +
            WCHAR*
         | 
| 463 | 
            +
            get_description(EVT_HANDLE handle, LANGID langID, EVT_HANDLE hRemote)
         | 
| 464 | 
            +
            {
         | 
| 465 | 
            +
            #define BUFSIZE 4096
         | 
| 466 | 
            +
              std::vector<WCHAR> buffer(BUFSIZE);
         | 
| 467 | 
            +
              ULONG bufferSizeNeeded = 0;
         | 
| 468 | 
            +
              ULONG status, count;
         | 
| 469 | 
            +
              std::vector<WCHAR> result;
         | 
| 470 | 
            +
              EVT_HANDLE hMetadata = nullptr;
         | 
| 471 | 
            +
             | 
| 472 | 
            +
              static PCWSTR eventProperties[] = { L"Event/System/Provider/@Name" };
         | 
| 473 | 
            +
              EVT_HANDLE renderContext =
         | 
| 474 | 
            +
                EvtCreateRenderContext(1, eventProperties, EvtRenderContextValues);
         | 
| 475 | 
            +
              if (renderContext == nullptr) {
         | 
| 476 | 
            +
                rb_raise(rb_eWinevtQueryError, "Failed to create renderContext");
         | 
| 477 | 
            +
              }
         | 
| 478 | 
            +
             | 
| 479 | 
            +
              if (EvtRender(renderContext,
         | 
| 480 | 
            +
                            handle,
         | 
| 481 | 
            +
                            EvtRenderEventValues,
         | 
| 482 | 
            +
                            buffer.size(),
         | 
| 483 | 
            +
                            &buffer.front(),
         | 
| 484 | 
            +
                            &bufferSizeNeeded,
         | 
| 485 | 
            +
                            &count) != FALSE) {
         | 
| 486 | 
            +
                status = ERROR_SUCCESS;
         | 
| 487 | 
            +
              } else {
         | 
| 488 | 
            +
                status = GetLastError();
         | 
| 489 | 
            +
              }
         | 
| 490 | 
            +
             | 
| 491 | 
            +
              if (status != ERROR_SUCCESS) {
         | 
| 492 | 
            +
                raise_system_error(rb_eWinevtQueryError, status);
         | 
| 493 | 
            +
              }
         | 
| 494 | 
            +
             | 
| 495 | 
            +
              // Obtain buffer as EVT_VARIANT pointer. To avoid ErrorCide 87 in EvtRender.
         | 
| 496 | 
            +
              const PEVT_VARIANT values = reinterpret_cast<PEVT_VARIANT>(&buffer.front());
         | 
| 497 | 
            +
             | 
| 498 | 
            +
              // Open publisher metadata
         | 
| 499 | 
            +
              hMetadata = EvtOpenPublisherMetadata(
         | 
| 500 | 
            +
                hRemote,
         | 
| 501 | 
            +
                values[0].StringVal,
         | 
| 502 | 
            +
                nullptr,
         | 
| 503 | 
            +
                MAKELCID(langID, SORT_DEFAULT),
         | 
| 504 | 
            +
                0);
         | 
| 505 | 
            +
              if (hMetadata == nullptr) {
         | 
| 506 | 
            +
                // When winevt_c cannot open metadata, then give up to obtain
         | 
| 507 | 
            +
                // message file and clean up immediately.
         | 
| 508 | 
            +
                goto cleanup;
         | 
| 509 | 
            +
              }
         | 
| 510 | 
            +
             | 
| 511 | 
            +
              result = get_message(hMetadata, handle);
         | 
| 512 | 
            +
             | 
| 513 | 
            +
            #undef BUFSIZE
         | 
| 514 | 
            +
             | 
| 515 | 
            +
            cleanup:
         | 
| 516 | 
            +
             | 
| 517 | 
            +
              if (renderContext)
         | 
| 518 | 
            +
                EvtClose(renderContext);
         | 
| 519 | 
            +
             | 
| 520 | 
            +
              if (hMetadata)
         | 
| 521 | 
            +
                EvtClose(hMetadata);
         | 
| 522 | 
            +
             | 
| 523 | 
            +
              return _wcsdup(result.data());
         | 
| 524 | 
            +
            }
         | 
| 525 | 
            +
             | 
| 526 | 
            +
            VALUE
         | 
| 527 | 
            +
            render_system_event(EVT_HANDLE hEvent, BOOL preserve_qualifiers)
         | 
| 528 | 
            +
            {
         | 
| 529 | 
            +
              DWORD status = ERROR_SUCCESS;
         | 
| 530 | 
            +
              EVT_HANDLE hContext = NULL;
         | 
| 531 | 
            +
              DWORD dwBufferSize = 0;
         | 
| 532 | 
            +
              DWORD dwBufferUsed = 0;
         | 
| 533 | 
            +
              DWORD dwPropertyCount = 0;
         | 
| 534 | 
            +
              VALUE vRenderedValues;
         | 
| 535 | 
            +
              PEVT_VARIANT pRenderedValues = NULL;
         | 
| 536 | 
            +
              WCHAR wsGuid[50];
         | 
| 537 | 
            +
              LPSTR pwsSid = NULL;
         | 
| 538 | 
            +
              ULONGLONG ullTimeStamp = 0;
         | 
| 539 | 
            +
              ULONGLONG ullNanoseconds = 0;
         | 
| 540 | 
            +
              SYSTEMTIME st;
         | 
| 541 | 
            +
              FILETIME ft;
         | 
| 542 | 
            +
              CHAR buffer[32];
         | 
| 543 | 
            +
              VALUE rbstr;
         | 
| 544 | 
            +
              DWORD EventID;
         | 
| 545 | 
            +
              VALUE hash = rb_hash_new();
         | 
| 546 | 
            +
             | 
| 547 | 
            +
              hContext = EvtCreateRenderContext(0, NULL, EvtRenderContextSystem);
         | 
| 548 | 
            +
              if (NULL == hContext) {
         | 
| 549 | 
            +
                rb_raise(
         | 
| 550 | 
            +
                  rb_eWinevtQueryError, "Failed to create renderContext with %lu\n", GetLastError());
         | 
| 551 | 
            +
              }
         | 
| 552 | 
            +
             | 
| 553 | 
            +
              if (!EvtRender(hContext,
         | 
| 554 | 
            +
                             hEvent,
         | 
| 555 | 
            +
                             EvtRenderEventValues,
         | 
| 556 | 
            +
                             dwBufferSize,
         | 
| 557 | 
            +
                             pRenderedValues,
         | 
| 558 | 
            +
                             &dwBufferUsed,
         | 
| 559 | 
            +
                             &dwPropertyCount)) {
         | 
| 560 | 
            +
                status = GetLastError();
         | 
| 561 | 
            +
                if (ERROR_INSUFFICIENT_BUFFER == status) {
         | 
| 562 | 
            +
                  dwBufferSize = dwBufferUsed;
         | 
| 563 | 
            +
                  pRenderedValues = (PEVT_VARIANT)ALLOCV(vRenderedValues, dwBufferSize);
         | 
| 564 | 
            +
                  if (pRenderedValues) {
         | 
| 565 | 
            +
                    EvtRender(hContext,
         | 
| 566 | 
            +
                              hEvent,
         | 
| 567 | 
            +
                              EvtRenderEventValues,
         | 
| 568 | 
            +
                              dwBufferSize,
         | 
| 569 | 
            +
                              pRenderedValues,
         | 
| 570 | 
            +
                              &dwBufferUsed,
         | 
| 571 | 
            +
                              &dwPropertyCount);
         | 
| 572 | 
            +
                  } else {
         | 
| 573 | 
            +
                    EvtClose(hContext);
         | 
| 574 | 
            +
                    rb_raise(rb_eRuntimeError, "Failed to malloc memory with %lu\n", status);
         | 
| 575 | 
            +
                  }
         | 
| 576 | 
            +
                }
         | 
| 577 | 
            +
             | 
| 578 | 
            +
                status = GetLastError();
         | 
| 579 | 
            +
                if (ERROR_SUCCESS != status) {
         | 
| 580 | 
            +
                  EvtClose(hContext);
         | 
| 581 | 
            +
                  ALLOCV_END(vRenderedValues);
         | 
| 582 | 
            +
             | 
| 583 | 
            +
                  rb_raise(rb_eWinevtQueryError, "EvtRender failed with %lu\n", status);
         | 
| 584 | 
            +
                }
         | 
| 585 | 
            +
              }
         | 
| 586 | 
            +
             | 
| 587 | 
            +
              // EVT_VARIANT value with EvtRenderContextSystem will be decomposed
         | 
| 588 | 
            +
              // as the following enum definition:
         | 
| 589 | 
            +
              // https://docs.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_system_property_id
         | 
| 590 | 
            +
              rbstr = wstr_to_rb_str(CP_UTF8, pRenderedValues[EvtSystemProviderName].StringVal, -1);
         | 
| 591 | 
            +
              rb_hash_aset(hash, rb_str_new2("ProviderName"), rbstr);
         | 
| 592 | 
            +
              if (NULL != pRenderedValues[EvtSystemProviderGuid].GuidVal) {
         | 
| 593 | 
            +
                const GUID* Guid = pRenderedValues[EvtSystemProviderGuid].GuidVal;
         | 
| 594 | 
            +
                StringFromGUID2(*Guid, wsGuid, _countof(wsGuid));
         | 
| 595 | 
            +
                rbstr = wstr_to_rb_str(CP_UTF8, wsGuid, -1);
         | 
| 596 | 
            +
                rb_hash_aset(hash, rb_str_new2("ProviderGuid"), rbstr);
         | 
| 597 | 
            +
              } else {
         | 
| 598 | 
            +
                rb_hash_aset(hash, rb_str_new2("ProviderGuid"), Qnil);
         | 
| 599 | 
            +
              }
         | 
| 600 | 
            +
             | 
| 601 | 
            +
              EventID = pRenderedValues[EvtSystemEventID].UInt16Val;
         | 
| 602 | 
            +
              if (preserve_qualifiers) {
         | 
| 603 | 
            +
                if (EvtVarTypeNull != pRenderedValues[EvtSystemQualifiers].Type) {
         | 
| 604 | 
            +
                  rb_hash_aset(hash, rb_str_new2("Qualifiers"),
         | 
| 605 | 
            +
                               INT2NUM(pRenderedValues[EvtSystemQualifiers].UInt16Val));
         | 
| 606 | 
            +
                } else {
         | 
| 607 | 
            +
                  rb_hash_aset(hash, rb_str_new2("Qualifiers"), rb_str_new2(""));
         | 
| 608 | 
            +
                }
         | 
| 609 | 
            +
             | 
| 610 | 
            +
                rb_hash_aset(hash, rb_str_new2("EventID"), INT2NUM(EventID));
         | 
| 611 | 
            +
              } else {
         | 
| 612 | 
            +
                if (EvtVarTypeNull != pRenderedValues[EvtSystemQualifiers].Type) {
         | 
| 613 | 
            +
                  EventID = MAKELONG(pRenderedValues[EvtSystemEventID].UInt16Val,
         | 
| 614 | 
            +
                                     pRenderedValues[EvtSystemQualifiers].UInt16Val);
         | 
| 615 | 
            +
                }
         | 
| 616 | 
            +
             | 
| 617 | 
            +
                rb_hash_aset(hash, rb_str_new2("EventID"), ULONG2NUM(EventID));
         | 
| 618 | 
            +
              }
         | 
| 619 | 
            +
             | 
| 620 | 
            +
              rb_hash_aset(hash,
         | 
| 621 | 
            +
                           rb_str_new2("Version"),
         | 
| 622 | 
            +
                           (EvtVarTypeNull == pRenderedValues[EvtSystemVersion].Type)
         | 
| 623 | 
            +
                             ? INT2NUM(0)
         | 
| 624 | 
            +
                             : INT2NUM(pRenderedValues[EvtSystemVersion].ByteVal));
         | 
| 625 | 
            +
              rb_hash_aset(hash,
         | 
| 626 | 
            +
                           rb_str_new2("Level"),
         | 
| 627 | 
            +
                           (EvtVarTypeNull == pRenderedValues[EvtSystemLevel].Type)
         | 
| 628 | 
            +
                             ? INT2NUM(0)
         | 
| 629 | 
            +
                             : INT2NUM(pRenderedValues[EvtSystemLevel].ByteVal));
         | 
| 630 | 
            +
              rb_hash_aset(hash,
         | 
| 631 | 
            +
                           rb_str_new2("Task"),
         | 
| 632 | 
            +
                           (EvtVarTypeNull == pRenderedValues[EvtSystemTask].Type)
         | 
| 633 | 
            +
                             ? INT2NUM(0)
         | 
| 634 | 
            +
                             : INT2NUM(pRenderedValues[EvtSystemTask].UInt16Val));
         | 
| 635 | 
            +
              rb_hash_aset(hash,
         | 
| 636 | 
            +
                           rb_str_new2("Opcode"),
         | 
| 637 | 
            +
                           (EvtVarTypeNull == pRenderedValues[EvtSystemOpcode].Type)
         | 
| 638 | 
            +
                             ? INT2NUM(0)
         | 
| 639 | 
            +
                             : INT2NUM(pRenderedValues[EvtSystemOpcode].ByteVal));
         | 
| 640 | 
            +
              _snprintf_s(buffer,
         | 
| 641 | 
            +
                          _countof(buffer),
         | 
| 642 | 
            +
                          _TRUNCATE,
         | 
| 643 | 
            +
                          "0x%llx",
         | 
| 644 | 
            +
                          pRenderedValues[EvtSystemKeywords].UInt64Val);
         | 
| 645 | 
            +
              rb_hash_aset(hash,
         | 
| 646 | 
            +
                           rb_str_new2("Keywords"),
         | 
| 647 | 
            +
                           (EvtVarTypeNull == pRenderedValues[EvtSystemKeywords].Type)
         | 
| 648 | 
            +
                             ? Qnil
         | 
| 649 | 
            +
                             : rb_str_new2(buffer));
         | 
| 650 | 
            +
             | 
| 651 | 
            +
              ullTimeStamp = pRenderedValues[EvtSystemTimeCreated].FileTimeVal;
         | 
| 652 | 
            +
              ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
         | 
| 653 | 
            +
              ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);
         | 
| 654 | 
            +
             | 
| 655 | 
            +
              FileTimeToSystemTime(&ft, &st);
         | 
| 656 | 
            +
              ullNanoseconds =
         | 
| 657 | 
            +
                (ullTimeStamp % 10000000) *
         | 
| 658 | 
            +
                100; // Display nanoseconds instead of milliseconds for higher resolution
         | 
| 659 | 
            +
              _snprintf_s(buffer,
         | 
| 660 | 
            +
                          _countof(buffer),
         | 
| 661 | 
            +
                          _TRUNCATE,
         | 
| 662 | 
            +
                          "%02d/%02d/%02d %02d:%02d:%02d.%llu",
         | 
| 663 | 
            +
                          st.wYear,
         | 
| 664 | 
            +
                          st.wMonth,
         | 
| 665 | 
            +
                          st.wDay,
         | 
| 666 | 
            +
                          st.wHour,
         | 
| 667 | 
            +
                          st.wMinute,
         | 
| 668 | 
            +
                          st.wSecond,
         | 
| 669 | 
            +
                          ullNanoseconds);
         | 
| 670 | 
            +
              rb_hash_aset(hash,
         | 
| 671 | 
            +
                           rb_str_new2("TimeCreated"),
         | 
| 672 | 
            +
                           (EvtVarTypeNull == pRenderedValues[EvtSystemKeywords].Type)
         | 
| 673 | 
            +
                             ? Qnil
         | 
| 674 | 
            +
                             : rb_str_new2(buffer));
         | 
| 675 | 
            +
              _snprintf_s(buffer,
         | 
| 676 | 
            +
                          _countof(buffer),
         | 
| 677 | 
            +
                          _TRUNCATE,
         | 
| 678 | 
            +
                          "%llu",
         | 
| 679 | 
            +
                          pRenderedValues[EvtSystemEventRecordId].UInt64Val);
         | 
| 680 | 
            +
              rb_hash_aset(hash,
         | 
| 681 | 
            +
                           rb_str_new2("EventRecordID"),
         | 
| 682 | 
            +
                           (EvtVarTypeNull == pRenderedValues[EvtSystemEventRecordId].UInt64Val)
         | 
| 683 | 
            +
                             ? Qnil
         | 
| 684 | 
            +
                             : rb_str_new2(buffer));
         | 
| 685 | 
            +
             | 
| 686 | 
            +
              if (EvtVarTypeNull != pRenderedValues[EvtSystemActivityID].Type) {
         | 
| 687 | 
            +
                const GUID* Guid = pRenderedValues[EvtSystemActivityID].GuidVal;
         | 
| 688 | 
            +
                StringFromGUID2(*Guid, wsGuid, _countof(wsGuid));
         | 
| 689 | 
            +
                rbstr = wstr_to_rb_str(CP_UTF8, wsGuid, -1);
         | 
| 690 | 
            +
                rb_hash_aset(hash, rb_str_new2("ActivityID"), rbstr);
         | 
| 691 | 
            +
              }
         | 
| 692 | 
            +
             | 
| 693 | 
            +
              if (EvtVarTypeNull != pRenderedValues[EvtSystemRelatedActivityID].Type) {
         | 
| 694 | 
            +
                const GUID* Guid = pRenderedValues[EvtSystemRelatedActivityID].GuidVal;
         | 
| 695 | 
            +
                StringFromGUID2(*Guid, wsGuid, _countof(wsGuid));
         | 
| 696 | 
            +
                rbstr = wstr_to_rb_str(CP_UTF8, wsGuid, -1);
         | 
| 697 | 
            +
                rb_hash_aset(hash, rb_str_new2("RelatedActivityID"), rbstr);
         | 
| 698 | 
            +
              }
         | 
| 699 | 
            +
             | 
| 700 | 
            +
              rb_hash_aset(hash,
         | 
| 701 | 
            +
                           rb_str_new2("ProcessID"),
         | 
| 702 | 
            +
                           UINT2NUM(pRenderedValues[EvtSystemProcessID].UInt32Val));
         | 
| 703 | 
            +
              rb_hash_aset(hash,
         | 
| 704 | 
            +
                           rb_str_new2("ThreadID"),
         | 
| 705 | 
            +
                           UINT2NUM(pRenderedValues[EvtSystemThreadID].UInt32Val));
         | 
| 706 | 
            +
              rbstr = wstr_to_rb_str(CP_UTF8, pRenderedValues[EvtSystemChannel].StringVal, -1);
         | 
| 707 | 
            +
              rb_hash_aset(hash, rb_str_new2("Channel"), rbstr);
         | 
| 708 | 
            +
              rbstr = wstr_to_rb_str(CP_UTF8, pRenderedValues[EvtSystemComputer].StringVal, -1);
         | 
| 709 | 
            +
              rb_hash_aset(hash, rb_str_new2("Computer"), rbstr);
         | 
| 710 | 
            +
             | 
| 711 | 
            +
              if (EvtVarTypeNull != pRenderedValues[EvtSystemUserID].Type) {
         | 
| 712 | 
            +
                if (ConvertSidToStringSid(pRenderedValues[EvtSystemUserID].SidVal, &pwsSid)) {
         | 
| 713 | 
            +
                  rbstr = rb_utf8_str_new_cstr(pwsSid);
         | 
| 714 | 
            +
                  rb_hash_aset(hash, rb_str_new2("UserID"), rbstr);
         | 
| 715 | 
            +
                  LocalFree(pwsSid);
         | 
| 716 | 
            +
                }
         | 
| 717 | 
            +
              }
         | 
| 718 | 
            +
             | 
| 719 | 
            +
              EvtClose(hContext);
         | 
| 720 | 
            +
              ALLOCV_END(vRenderedValues);
         | 
| 721 | 
            +
             | 
| 722 | 
            +
              return hash;
         | 
| 723 | 
            +
            }
         |