Class: Winevt::EventLog::Query

Inherits:
Object
  • Object
show all
Defined in:
ext/winevt/winevt_query.c,
lib/winevt/query.rb,
ext/winevt/winevt.c,
ext/winevt/winevt_query.c

Overview

Query Windows EventLog channel.

Examples:

require 'winevt'

@query = Winevt::EventLog::Query.new("Application", "*[System[(Level <= 3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]")

@query.each do |eventlog, message, string_inserts|
  puts ({eventlog: eventlog, data: message})
end

Defined Under Namespace

Modules: Flag Classes: Error

Instance Method Summary collapse

Constructor Details

#initialize(channel, xpath, session = nil) ⇒ Query

Initialize Query class.

Parameters:

  • channel (String)

    Querying EventLog channel.

  • xpath (String)

    Querying XPath.

  • session (Session) (defaults to: nil)

    Session information for remoting access.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'ext/winevt/winevt_query.c', line 113

static VALUE
rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
{
  PWSTR evtChannel, evtXPath;
  VALUE channel, xpath, session, rb_flags;
  struct WinevtQuery* winevtQuery;
  struct WinevtSession* winevtSession;
  EVT_HANDLE hRemoteHandle = NULL;
  DWORD len, flags = 0;
  VALUE wchannelBuf, wpathBuf;
  DWORD err = ERROR_SUCCESS;

  rb_scan_args(argc, argv, "22", &channel, &xpath, &session, &rb_flags);
  Check_Type(channel, T_STRING);
  Check_Type(xpath, T_STRING);

  if (rb_obj_is_kind_of(session, rb_cSession)) {
    winevtSession = EventSession(session);

    hRemoteHandle = connect_to_remote(winevtSession->server,
                                      winevtSession->domain,
                                      winevtSession->username,
                                      winevtSession->password,
                                      winevtSession->flags,
                                      &err);
    if (err != ERROR_SUCCESS) {
      raise_system_error(rb_eRuntimeError, err);
    }
  }

  switch (TYPE(rb_flags)) {
  case T_FIXNUM:
    flags = NUM2LONG(rb_flags);
    break;
  case T_NIL:
    flags = EvtQueryChannelPath | EvtQueryTolerateQueryErrors;
    break;
  default:
    if (hRemoteHandle != NULL) {
      EvtClose(hRemoteHandle);
    }
    rb_raise(rb_eArgError, "Expected a String, a Symbol, a Fixnum, or a NilClass instance");
  }

  // channel : To wide char
  len =
    MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
  evtChannel = ALLOCV_N(WCHAR, wchannelBuf, len + 1);
  MultiByteToWideChar(
    CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), evtChannel, len);
  evtChannel[len] = L'\0';

  // xpath : To wide char
  len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), NULL, 0);
  evtXPath = ALLOCV_N(WCHAR, wpathBuf, len + 1);
  MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), evtXPath, len);
  evtXPath[len] = L'\0';

  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  if (hRemoteHandle != NULL) {
    struct query_args args;

    args.session = hRemoteHandle;
    args.channel = evtChannel;
    args.xpath = evtXPath;
    args.flags = flags;
    args.handle = NULL;
    args.error_code = ERROR_SUCCESS;

    // EvtOpenSession only builds the session object; this is the first call
    // that reaches the remote machine, so it is the one that can stall.
    rb_thread_call_without_gvl(query_without_gvl, &args, NULL, NULL);

    winevtQuery->query = args.handle;
    err = args.error_code;
  } else {
    winevtQuery->query = EvtQuery(hRemoteHandle, evtChannel, evtXPath, flags);
    if (winevtQuery->query == NULL) {
      err = GetLastError();
    }
  }

  if (winevtQuery->query == NULL) {
    if (hRemoteHandle != NULL) {
      EvtClose(hRemoteHandle);
    }
    if (err == ERROR_EVT_CHANNEL_NOT_FOUND) {
      raise_channel_not_found_error(channel);
    }
    raise_system_error(rb_eRuntimeError, err);
  }
  winevtQuery->offset = 0L;
  winevtQuery->timeout = 0L;
  winevtQuery->renderAsXML = TRUE;
  winevtQuery->preserveQualifiers = FALSE;
  winevtQuery->localeInfo = &default_locale;
  winevtQuery->remoteHandle = hRemoteHandle;
  winevtQuery->preserveSID = TRUE;
  winevtQuery->unresolvedMessageCount = 0;

  ALLOCV_END(wchannelBuf);
  ALLOCV_END(wpathBuf);

  return Qnil;
}

Instance Method Details

#cancelBoolean

This method cancels channel query.

Returns:

  • (Boolean)

Since:

  • 0.9.1



672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
# File 'ext/winevt/winevt_query.c', line 672

static VALUE
rb_winevt_query_cancel(VALUE self)
{
  struct WinevtQuery* winevtQuery;
  BOOL result = FALSE;

  TypedData_Get_Struct(
    self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  if (winevtQuery->query) {
    result = EvtCancel(winevtQuery->query);
  }

  if (result) {
    return Qtrue;
  } else {
    return Qfalse;
  }
}

#closeObject

This method closes channel handles forcibly.

Since:

  • 0.9.1



697
698
699
700
701
702
703
704
705
706
707
708
# File 'ext/winevt/winevt_query.c', line 697

static VALUE
rb_winevt_query_close(VALUE self)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(
    self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  close_handles(winevtQuery);

  return Qnil;
}

#eachObject



489
490
491
492
493
494
495
496
497
498
499
# File 'ext/winevt/winevt_query.c', line 489

static VALUE
rb_winevt_query_each(VALUE self)
{
  RETURN_ENUMERATOR(self, 0, 0);

  while (rb_winevt_query_next(self)) {
    rb_ensure(rb_winevt_query_each_yield, self, rb_winevt_query_close_handle, self);
  }

  return Qnil;
}

#localeObject

This method obtains specified locale with [String].

Since:

  • 0.8.0



596
597
598
599
600
601
602
603
604
605
606
607
608
609
# File 'ext/winevt/winevt_query.c', line 596

static VALUE
rb_winevt_query_get_locale(VALUE self)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(
    self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  if (winevtQuery->localeInfo->langCode) {
    return rb_str_new2(winevtQuery->localeInfo->langCode);
  } else {
    return rb_str_new2(default_locale.langCode);
  }
}

#locale=(rb_locale_str) ⇒ Object

This method specifies locale with [String].

Parameters:

  • rb_locale_str (String)

Since:

  • 0.8.0



575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
# File 'ext/winevt/winevt_query.c', line 575

static VALUE
rb_winevt_query_set_locale(VALUE self, VALUE rb_locale_str)
{
  struct WinevtQuery* winevtQuery;
  LocaleInfo* locale_info = &default_locale;

  TypedData_Get_Struct(
    self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  locale_info = get_locale_info_from_rb_str(rb_locale_str);

  winevtQuery->localeInfo = locale_info;

  return Qnil;
}

#nextObject



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
# File 'ext/winevt/winevt_query.c', line 292

static VALUE
rb_winevt_query_next(VALUE self)
{
  EVT_HANDLE hEvents[QUERY_ARRAY_SIZE];
  ULONG count;
  DWORD status = ERROR_SUCCESS;
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  if (!EvtNext(winevtQuery->query, QUERY_ARRAY_SIZE, hEvents, INFINITE, 0, &count)) {
    status = GetLastError();
    if (ERROR_CANCELLED == status) {
      return Qfalse;
    }
    if (ERROR_NO_MORE_ITEMS != status) {
      return Qfalse;
    }
  }

  if (status == ERROR_SUCCESS) {
    // #each frees each batch in its ensure block; this covers calling #next
    // directly in a loop.
    for (ULONG i = 0; i < winevtQuery->count; i++) {
      if (winevtQuery->hEvents[i]) {
        EvtClose(winevtQuery->hEvents[i]);
        winevtQuery->hEvents[i] = NULL;
      }
    }

    winevtQuery->count = count;
    for (ULONG i = 0; i < count; i++) {
      winevtQuery->hEvents[i] = hEvents[i];
    }

    return Qtrue;
  }

  return Qfalse;
}

#offsetObject



225
226
227
228
229
230
231
232
233
# File 'ext/winevt/winevt_query.c', line 225

static VALUE
rb_winevt_query_get_offset(VALUE self)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  return LONG2NUM(winevtQuery->offset);
}

#offset=(offset) ⇒ Object



240
241
242
243
244
245
246
247
248
249
250
# File 'ext/winevt/winevt_query.c', line 240

static VALUE
rb_winevt_query_set_offset(VALUE self, VALUE offset)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  winevtQuery->offset = NUM2LONG(offset);

  return Qnil;
}

#preserve_qualifiers=(rb_preserve_qualifiers) ⇒ Object

This method specifies whether preserving qualifiers key or not.

Parameters:

  • rb_preserve_qualifiers (Boolean)

Since:

  • 0.7.3



539
540
541
542
543
544
545
546
547
548
549
550
# File 'ext/winevt/winevt_query.c', line 539

static VALUE
rb_winevt_query_set_preserve_qualifiers(VALUE self, VALUE rb_preserve_qualifiers)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(
    self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  winevtQuery->preserveQualifiers = RTEST(rb_preserve_qualifiers);

  return Qnil;
}

#preserve_qualifiers?Integer

This method returns whether preserving qualifiers or not.

Returns:

  • (Integer)

Since:

  • 0.7.3



558
559
560
561
562
563
564
565
566
567
# File 'ext/winevt/winevt_query.c', line 558

static VALUE
rb_winevt_query_get_preserve_qualifiers_p(VALUE self)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(
    self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  return winevtQuery->preserveQualifiers ? Qtrue : Qfalse;
}

#preserve_sid=(rb_preserve_sid_p) ⇒ Object

This method specifies whether preserving SID or not.

Parameters:

  • rb_preserve_sid_p (Boolean)


616
617
618
619
620
621
622
623
624
625
626
627
# File 'ext/winevt/winevt_query.c', line 616

static VALUE
rb_winevt_query_set_preserve_sid(VALUE self, VALUE rb_preserve_sid_p)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(
    self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  winevtQuery->preserveSID = RTEST(rb_preserve_sid_p);

  return Qnil;
}

#preserve_sid?Boolean

This method returns whether preserving SID or not.

Returns:

  • (Boolean)


634
635
636
637
638
639
640
641
642
643
# File 'ext/winevt/winevt_query.c', line 634

static VALUE
rb_winevt_query_preserve_sid_p(VALUE self)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(
    self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  return winevtQuery->preserveSID ? Qtrue : Qfalse;
}

#render_as_xml=(rb_render_as_xml) ⇒ Object



521
522
523
524
525
526
527
528
529
530
531
# File 'ext/winevt/winevt_query.c', line 521

static VALUE
rb_winevt_query_set_render_as_xml(VALUE self, VALUE rb_render_as_xml)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  winevtQuery->renderAsXML = RTEST(rb_render_as_xml);

  return Qnil;
}

#render_as_xml?Object



506
507
508
509
510
511
512
513
514
# File 'ext/winevt/winevt_query.c', line 506

static VALUE
rb_winevt_query_render_as_xml_p(VALUE self)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  return winevtQuery->renderAsXML ? Qtrue : Qfalse;
}

#seek(bookmark_or_flag) ⇒ Object



401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'ext/winevt/winevt_query.c', line 401

static VALUE
rb_winevt_query_seek(VALUE self, VALUE bookmark_or_flag)
{
  struct WinevtQuery* winevtQuery;
  struct WinevtBookmark* winevtBookmark = NULL;
  DWORD flag = 0;

  switch (TYPE(bookmark_or_flag)) {
    case T_SYMBOL:
      flag = get_evt_seek_flag_from_cstr(RSTRING_PTR(rb_sym2str(bookmark_or_flag)));
      break;
    case T_STRING:
      flag = get_evt_seek_flag_from_cstr(StringValueCStr(bookmark_or_flag));
      break;
    case T_FIXNUM:
      flag = NUM2LONG(bookmark_or_flag);
      break;
    default:
      if (!rb_obj_is_kind_of(bookmark_or_flag, rb_cBookmark))
        rb_raise(rb_eArgError, "Expected a String or a Symbol or a Bookmark instance");

      winevtBookmark = EventBookMark(bookmark_or_flag);
  }

  if (winevtBookmark) {
    TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
    if (EvtSeek(winevtQuery->query,
                winevtQuery->offset,
                winevtBookmark->bookmark,
                winevtQuery->timeout,
                EvtSeekRelativeToBookmark))
      return Qtrue;
  } else {
    TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
    if (EvtSeek(
          winevtQuery->query, winevtQuery->offset, NULL, winevtQuery->timeout, flag)) {
      return Qtrue;
    }
  }

  return Qfalse;
}

#timeoutObject



257
258
259
260
261
262
263
264
265
# File 'ext/winevt/winevt_query.c', line 257

static VALUE
rb_winevt_query_get_timeout(VALUE self)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  return LONG2NUM(winevtQuery->timeout);
}

#timeout=(timeout) ⇒ Object



272
273
274
275
276
277
278
279
280
281
282
# File 'ext/winevt/winevt_query.c', line 272

static VALUE
rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  winevtQuery->timeout = NUM2LONG(timeout);

  return Qnil;
}

#unresolved_message_countObject



655
656
657
658
659
660
661
662
663
664
# File 'ext/winevt/winevt_query.c', line 655

static VALUE
rb_winevt_query_get_unresolved_message_count(VALUE self)
{
  struct WinevtQuery* winevtQuery;

  TypedData_Get_Struct(
    self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);

  return ULL2NUM(winevtQuery->unresolvedMessageCount);
}