Windows API中如何使用QueryEVT获取多个事件?

问题描述 投票:0回答:0

我按照 Windows 文档link 进行操作,也许我做错了什么,但似乎要遍历所有事件返回所要做的就是调用

EvtNext()
link 直到它返回 false。

我正在尝试检索 EventID 为 5379 的所有事件。对于这张图片,我有很多 EventID 5739 的条目:

以下 C 代码是我用来尝试从安全日志中检索 ID 为 5379 的事件的代码。它目前只输出一个事件,然后程序结束。

#include <windows.h>
#include <sddl.h>
#include <stdio.h>
#include <winevt.h>

#pragma comment(lib, "wevtapi.lib")
#define ARRAY_SIZE 10
#define TIMEOUT 5000  // 5 second; Set and use in place of INFINITE in EvtNext call

LPWSTR GetMessageString(EVT_HANDLE hMetadata, EVT_HANDLE hEvent, EVT_FORMAT_MESSAGE_FLAGS FormatId);

void main(void)
{
    EVT_HANDLE hProviderMetadata = NULL;
    EVT_HANDLE hResults = NULL;
    EVT_HANDLE hEvent = NULL;
    DWORD status = ERROR_SUCCESS;
    DWORD dwReturned = 0;
    LPWSTR pwsMessage = NULL;
    const wchar_t* pwsPath = L"Security";
    const wchar_t* pwsQuery = L"Event/System[EventID=5379]";
    const wchar_t* pwszPublisherName = L"Microsoft-Windows-Security-Auditing";

    // Get the handle to the provider's metadata that contains the message strings.
    hProviderMetadata = EvtOpenPublisherMetadata(NULL, pwszPublisherName, NULL, 0, 0);
    if (NULL == hProviderMetadata)
    {
        wprintf(L"EvtOpenPublisherMetadata failed with %d\n", GetLastError());
        // Cleanup
        if (hEvent)
            EvtClose(hEvent);

        if (hResults)
            EvtClose(hResults);

        if (hProviderMetadata)
            EvtClose(hProviderMetadata);
    }

    // Query for an event.
    hResults = EvtQuery(NULL, pwsPath, pwsQuery, 0x1200);
    if (NULL == hResults)
    {
        status = GetLastError();

        if (ERROR_EVT_CHANNEL_NOT_FOUND == status)
            wprintf(L"Channel %s was not found.\n", pwsPath);
        else
            wprintf(L"EvtQuery failed with %lu.\n", status);

        // Cleanup
        if (hEvent)
            EvtClose(hEvent);

        if (hResults)
            EvtClose(hResults);

        if (hProviderMetadata)
            EvtClose(hProviderMetadata);
    }

    // Get a single event from the result set.
    while (EvtNext(hResults, 1, &hEvent, INFINITE, 0, &dwReturned) != FALSE)
    {

        // Get the various message strings from the event.
        pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageEvent);
        if (pwsMessage)
        {
            wprintf(L"Event message string: %s\n\n", pwsMessage);
            free(pwsMessage);
            pwsMessage = NULL;
        }

        pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageLevel);
        if (pwsMessage)
        {
            wprintf(L"Level message string: %s\n\n", pwsMessage);
            free(pwsMessage);
            pwsMessage = NULL;
        }

        pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageTask);
        if (pwsMessage)
        {
            wprintf(L"Task message string: %s\n\n", pwsMessage);
            free(pwsMessage);
            pwsMessage = NULL;
        }

        pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageOpcode);
        if (pwsMessage)
        {
            wprintf(L"Opcode message string: %s\n\n", pwsMessage);
            free(pwsMessage);
            pwsMessage = NULL;
        }

        pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageKeyword);
        if (pwsMessage)
        {
            LPWSTR ptemp = pwsMessage;

            wprintf(L"Keyword message string: %s", ptemp);

            while (*(ptemp += wcslen(ptemp) + 1))
                wprintf(L", %s", ptemp);

            wprintf(L"\n\n");
            free(pwsMessage);
            pwsMessage = NULL;
        }

        pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageChannel);
        if (pwsMessage)
        {
            wprintf(L"Channel message string: %s\n\n", pwsMessage);
            free(pwsMessage);
            pwsMessage = NULL;
        }

        pwsMessage = GetMessageString(hProviderMetadata, hEvent, EvtFormatMessageProvider);
        if (pwsMessage)
        {
            wprintf(L"Provider message string: %s\n\n", pwsMessage);
            free(pwsMessage);
            pwsMessage = NULL;
        }

    }

    status = GetLastError();
    if (status == ERROR_NO_MORE_ITEMS) 
    {
        wprintf(L"NO MORE ITEMS\n\n");
        status = ERROR_SUCCESS;
    }

    // Cleanup
    if (hEvent)
        EvtClose(hEvent);

    if (hResults)
        EvtClose(hResults);

    if (hProviderMetadata)
        EvtClose(hProviderMetadata);
}


// Gets the specified message string from the event. If the event does not
// contain the specified message, the function returns NULL.
LPWSTR GetMessageString(EVT_HANDLE hMetadata, EVT_HANDLE hEvent, EVT_FORMAT_MESSAGE_FLAGS FormatId)
{
    LPWSTR pBuffer = NULL;
    DWORD dwBufferSize = 0;
    DWORD dwBufferUsed = 0;
    DWORD status = 0;

    if (!EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, FormatId, dwBufferSize, pBuffer, &dwBufferUsed))
    {
        status = GetLastError();
        if (ERROR_INSUFFICIENT_BUFFER == status)
        {
            // An event can contain one or more keywords. The function returns keywords
            // as a list of keyword strings. To process the list, you need to know the
            // size of the buffer, so you know when you have read the last string, or you
            // can terminate the list of strings with a second null terminator character 
            // as this example does.
            if ((EvtFormatMessageKeyword == FormatId))
                pBuffer[dwBufferSize - 1] = L'\0';
            else
                dwBufferSize = dwBufferUsed;

            pBuffer = (LPWSTR)malloc(dwBufferSize * sizeof(WCHAR));

            if (pBuffer)
            {
                EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, FormatId, dwBufferSize, pBuffer, &dwBufferUsed);

                // Add the second null terminator character.
                if ((EvtFormatMessageKeyword == FormatId))
                    pBuffer[dwBufferUsed - 1] = L'\0';
            }
            else
            {
                wprintf(L"malloc failed\n");
            }
        }
        else if (ERROR_EVT_MESSAGE_NOT_FOUND == status || ERROR_EVT_MESSAGE_ID_NOT_FOUND == status)
            wprintf(L"!!! -- EvtFormatMessage failed with Message Not Found %u -- !!!\n", status);
        else
        {
            wprintf(L"EvtFormatMessage failed with %u\n", status);
        }
    }

    return pBuffer;
}

我做错了什么?也许是 XPATH 可能只返回一项?我计划在 3 小时后回到家时更深入地回顾一下,以防万一。


友情链接

c++ c winapi event-log
© www.soinside.com 2019 - 2024. All rights reserved.