Как использовать аргумент Context в EvtSubscribe в winevt.h Windows C ++ API - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь использовать функцию 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;
  }
};

1 Ответ

0 голосов
/ 08 января 2019

Единственная проблема в том, что возвращается одна точка данных, затем программа останавливается.

Добавьте WINAPI в функцию обратного вызова, чтобы проверить, работает ли она. Без ключевого слова WINAPI это приводит к исключению «Чтение нарушения доступа» (а не «блокирование функции подписки»).

Обратному звонку понравится:

DWORD WINAPI callback(EVT_SUBSCRIBE_NOTIFY_ACTION Action, PVOID UserContext, EVT_HANDLE Event) {
    return reinterpret_cast<EvtSubscribeData *>(UserContext)->subscribe(Action, Event);
}

Это работает для меня.

Дополнительная справка: « Что означает« WINAPI »в основной функции? »

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...