c++ read windows's event log by source

42 views Asked by At

I have this c++ code collect logs from Windows Even Log for a specific source:

#include <windows.h>
#include <winevt.h>
#include <iostream>
#include <fstream>

#pragma comment(lib, "wevtapi.lib")

// Function to retrieve and print the message associated with an event.
static void PrintEventMessage(EVT_HANDLE hEvent, std::wofstream& logFile) {
    DWORD status = ERROR_SUCCESS;
    DWORD dwBufferSize = 0;
    DWORD dwBufferUsed = 0;
    LPWSTR pMessage = NULL;
    EVT_HANDLE hMetadata = NULL;

    // Open the publisher metadata for the provider of the event.
    hMetadata = EvtOpenPublisherMetadata(NULL, L"my application", NULL, 0, 0);
    if (NULL == hMetadata) {
        std::wcout << L"EvtOpenPublisherMetadata failed with " << GetLastError() << L".\n";
        goto cleanup;
    }

    // Use EvtFormatMessage to get the formatted message string.
    if (!EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, EvtFormatMessageEvent, dwBufferSize, pMessage, &dwBufferUsed)) {
        if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError())) {
            dwBufferSize = dwBufferUsed;
            pMessage = (LPWSTR)malloc(dwBufferSize * sizeof(WCHAR));
            if (pMessage) {
                EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, EvtFormatMessageEvent, dwBufferSize, pMessage, &dwBufferUsed);
            }
        }

        if (ERROR_SUCCESS != (status = GetLastError())) {
            if (pMessage) {
                free(pMessage);
            }
            std::wcout << L"EvtFormatMessage failed with " << status << L".\n";
            goto cleanup;
        }
    }

    // Print and save the message string.
    std::wcout << pMessage << std::endl;
    logFile << pMessage << std::endl;

cleanup:
    if (hMetadata)
        EvtClose(hMetadata);
    if (pMessage)
        free(pMessage);
}

int main() {
    EVT_HANDLE hResults = NULL;
    EVT_HANDLE hEvent = NULL;
    DWORD status = ERROR_SUCCESS;
    DWORD dwReturned = 0;
    WCHAR query[] = L"*[System[Provider[@Name='my application']]]";
    std::wofstream logFile("EventLog.txt");

    // Open the Application log.
    hResults = EvtQuery(NULL, L"Application", query, EvtQueryChannelPath | EvtQueryReverseDirection);
    if (NULL == hResults) {
        status = GetLastError();
        if (ERROR_EVT_CHANNEL_NOT_FOUND == status)
            std::wcout << L"The Application log does not exist.\n";
        else
            std::wcout << L"EvtQuery failed with " << status << L".\n";
        goto cleanup;
    }

    // Loop through the results and print the event data.
    while (true) {
        if (!EvtNext(hResults, 1, &hEvent, INFINITE, 0, &dwReturned)) {
            if (ERROR_NO_MORE_ITEMS != (status = GetLastError())) {
                std::wcout << L"EvtNext failed with " << status << L".\n";
            }
            break;
        }

        // Call the function to print the event message.
        PrintEventMessage(hEvent, logFile);

        EvtClose(hEvent);
        hEvent = NULL;
    }

cleanup:
    if (hResults)
        EvtClose(hResults);
    if (hEvent)
        EvtClose(hEvent);
    if (logFile.is_open())
        logFile.close();

    return 0;
}

Now this code works fine and I get the logs printed correctly in the console and in a txt file, however it does display only the log message I want to extend it to display the log time as well but couldn't find how.

0

There are 0 answers