Я пытаюсь использовать функцию EvtSubscribe в заголовке winevt.h, предоставленном в Windows C ++ API.
В настоящее время мой звонок в EvtSubscibe выглядит следующим образом:
EvtSubscribeData data;
hResults = EvtSubscribe(
NULL, NULL, L"Security", L"Event/System[EventID=4624]", NULL, reinterpret_cast<void *>(&data), (EVT_SUBSCRIBE_CALLBACK)callback, EvtSubscribeStartAtOldestRecord
);
EvtSubscribeData - это класс, в котором есть функция с именем subscribe
, и моя функция обратного вызова выглядит следующим образом:
DWORD callback(EVT_SUBSCRIBE_NOTIFY_ACTION Action, PVOID UserContext,EVT_HANDLE Event) {
return reinterpret_cast<EvtSubscribeData *>(UserContext)->subscribe(Action, Event);
}
Как вы можете сказать, я использую параметр Context, который позволяет мне использовать данные, возвращаемые в обратном вызове, для заполнения переменных-членов класса EvtSubscribeData.
Единственная проблема заключается в том, что возвращается одна точка данных, а затем программа останавливается. Функция EVT_SUBSCRIBE_CALLBACK сообщает, что функция subscribe
блокируется, поэтому я сначала подумал, что callback
никогда не возвращается, но после отладки callback
возвращает 0, что правильно возвращается из EvtSubscribeData::subscribe
.
Когда я удаляю аргумент Context и использую EvtSubscribeData::subscribe
как функцию вместо функции-члена (как в примерах, показанных здесь ), все работает, как и должно быть, с сотнями напечатанных событий.
Баскетбольная функция EvtSubscribeData:
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;
}
};