Skip to content

Commit c1f85b7

Browse files
committed
query: Implement to traverse feature for stored evtx files
Signed-off-by: Hiroshi Hatake <[email protected]>
1 parent 0a9a3f8 commit c1f85b7

File tree

1 file changed

+72
-4
lines changed

1 file changed

+72
-4
lines changed

ext/winevt/winevt_query.c

+72-4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,26 @@ rb_winevt_query_alloc(VALUE klass)
7171
return obj;
7272
}
7373

74+
static DWORD
75+
get_evt_query_flag_from_cstr(char* flag_str)
76+
{
77+
if (strcmp(flag_str, "channel") == 0)
78+
return EvtQueryChannelPath;
79+
else if (strcmp(flag_str, "file") == 0)
80+
return EvtQueryFilePath;
81+
else if (strcmp(flag_str, "forward") == 0)
82+
return EvtQueryForwardDirection;
83+
else if (strcmp(flag_str, "reverse") == 0)
84+
return EvtQueryReverseDirection;
85+
else if (strcmp(flag_str, "tolerate_query_errors") == 0 ||
86+
strcmp(flag_str, "tolerate_errors") == 0)
87+
return EvtQueryTolerateQueryErrors;
88+
else
89+
rb_raise(rb_eArgError, "Unknown query flag: %s", flag_str);
90+
91+
return 0;
92+
}
93+
7494
/*
7595
* Initalize Query class.
7696
*
@@ -85,15 +105,15 @@ static VALUE
85105
rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
86106
{
87107
PWSTR evtChannel, evtXPath;
88-
VALUE channel, xpath, session;
108+
VALUE channel, xpath, session, rb_flags;
89109
struct WinevtQuery* winevtQuery;
90110
struct WinevtSession* winevtSession;
91111
EVT_HANDLE hRemoteHandle = NULL;
92-
DWORD len;
112+
DWORD len, flags = 0;
93113
VALUE wchannelBuf, wpathBuf;
94114
DWORD err = ERROR_SUCCESS;
95115

96-
rb_scan_args(argc, argv, "21", &channel, &xpath, &session);
116+
rb_scan_args(argc, argv, "22", &channel, &xpath, &session, &rb_flags);
97117
Check_Type(channel, T_STRING);
98118
Check_Type(xpath, T_STRING);
99119

@@ -111,6 +131,23 @@ rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
111131
}
112132
}
113133

134+
switch (TYPE(rb_flags)) {
135+
case T_SYMBOL:
136+
flags = get_evt_query_flag_from_cstr(RSTRING_PTR(rb_sym2str(rb_flags)));
137+
break;
138+
case T_STRING:
139+
flags = get_evt_query_flag_from_cstr(StringValuePtr(rb_flags));
140+
break;
141+
case T_FIXNUM:
142+
flags = NUM2LONG(rb_flags);
143+
break;
144+
case T_NIL:
145+
flags = EvtQueryChannelPath | EvtQueryTolerateQueryErrors;
146+
break;
147+
default:
148+
rb_raise(rb_eArgError, "Expected a String, a Symbol, a Fixnum, or a NilClass instance");
149+
}
150+
114151
// channel : To wide char
115152
len =
116153
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
@@ -128,7 +165,7 @@ rb_winevt_query_initialize(VALUE argc, VALUE *argv, VALUE self)
128165
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
129166

130167
winevtQuery->query = EvtQuery(
131-
hRemoteHandle, evtChannel, evtXPath, EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
168+
hRemoteHandle, evtChannel, evtXPath, flags);
132169
err = GetLastError();
133170
if (err != ERROR_SUCCESS) {
134171
if (err == ERROR_EVT_CHANNEL_NOT_FOUND) {
@@ -613,6 +650,37 @@ Init_winevt_query(VALUE rb_cEventLog)
613650
* @see https://msdn.microsoft.com/en-us/windows/desktop/aa385575#EvtSeekStrict
614651
*/
615652
rb_define_const(rb_cFlag, "Strict", LONG2NUM(EvtSeekStrict));
653+
654+
/*
655+
* EVT_QUERY_FLAGS enumeration: EvtQueryChannelPath
656+
* @since 0.10.3
657+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
658+
*/
659+
rb_define_const(rb_cFlag, "ChannelPath", LONG2NUM(EvtQueryChannelPath));
660+
/*
661+
* EVT_QUERY_FLAGS enumeration: EvtQueryFilePath
662+
* @since 0.10.3
663+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
664+
*/
665+
rb_define_const(rb_cFlag, "FilePath", LONG2NUM(EvtQueryFilePath));
666+
/*
667+
* EVT_QUERY_FLAGS enumeration: EvtQueryForwardDirection
668+
* @since 0.10.3
669+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
670+
*/
671+
rb_define_const(rb_cFlag, "ForwardDirection", LONG2NUM(EvtQueryForwardDirection));
672+
/*
673+
* EVT_QUERY_FLAGS enumeration: EvtQueryReverseDirection
674+
* @since 0.10.3
675+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
676+
*/
677+
rb_define_const(rb_cFlag, "ReverseDirection", LONG2NUM(EvtQueryReverseDirection));
678+
/*
679+
* EVT_QUERY_FLAGS enumeration: EvtSeekOriginMask
680+
* @since 0.10.3
681+
* @see https://learn.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_query_flags
682+
*/
683+
rb_define_const(rb_cFlag, "TolerateQueryErrors", LONG2NUM(EvtQueryTolerateQueryErrors));
616684
/* clang-format on */
617685

618686
rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, -1);

0 commit comments

Comments
 (0)