I am trying to use the EvtSubscribe function in the winevt.h header provided in the Windows C++ API.
Currently, my call to EvtSubscibe looks like this:
EvtSubscribeData data;
hResults = EvtSubscribe(
NULL, NULL, L"Security", L"Event/System[EventID=4624]", NULL, reinterpret_cast<void *>(&data), (EVT_SUBSCRIBE_CALLBACK)callback, EvtSubscribeStartAtOldestRecord
);
EvtSubscribeData is a class that has a function called subscribe
and my callback function looks like this:
DWORD callback(EVT_SUBSCRIBE_NOTIFY_ACTION Action, PVOID UserContext,EVT_HANDLE Event) {
return reinterpret_cast<EvtSubscribeData *>(UserContext)->subscribe(Action, Event);
}
As you can tell, I am using the Context parameter which allows me to use the data returned in the callback to populate the EvtSubscribeData class member variables.
The only problem is that one data point is returned, then the program stops. The EVT_SUBSCRIBE_CALLBACK function says that the subscribe
function is blocking, so my first thought was that callback
was never returning, but after debugging, callback
is returning 0, which is correctly being returned from EvtSubscribeData::subscribe
.
When I remove the Context argument and use EvtSubscribeData::subscribe
as a function instead of a member function (like in the examples shown here) everything works as it should with hundreds of events being printed.
A barebones EvtSubscribeData function:
class EvtSubscribeData {
public:
EvtSubscribeData() {}
DWORD WINAPI subscribe(EVT_SUBSCRIBE_NOTIFY_ACTION action, EVT_HANDLE event) {
auto status = ERROR_SUCCESS;
switch (action) {
case EvtSubscribeActionError:
if (ERROR_EVT_QUERY_RESULT_STALE == (DWORD)event) {
std::cout << "event records are missing" << std::endl;
} else {
std::cout << "win32 Error" << (DWORD)event << std::endl;
}
break;
case EvtSubscribeActionDeliver:
status = PrintEvent(event);
break;
}
return status;
}
};