void RenderContext::openForValues(const wchar_t* const* values, std::size_t n)
{
  handle_.reset(EvtCreateRenderContext(n, const_cast<const wchar_t**>(values), EvtRenderEventValues));
  if (!handle_)
  {
      throw WinException(L"EvtCreateRenderContext", GetLastError());
  }
}
/* Get specific values from an event */
PEVT_VARIANT GetEventInfo(EVT_HANDLE hEvent)
{
	EVT_HANDLE hContext = NULL;
	PEVT_VARIANT pRenderedEvents = NULL;
	LPWSTR ppValues[] = {L"Event/System/Provider/@Name",
						 L"Event/System/TimeCreated/@SystemTime",
						 L"Event/System/EventID",
						 L"Event/System/Level",
						 L"Event/System/Keywords"};
    DWORD count = COUNT_OF(ppValues);
    DWORD dwReturned = 0;
	DWORD dwBufferSize = (256*sizeof(LPWSTR)*count);
	DWORD dwValuesCount = 0;
	DWORD status = 0;

	/* Create the context to use for EvtRender */
	hContext = EvtCreateRenderContext(count, (LPCWSTR*)ppValues, EvtRenderContextValues);
	if (NULL == hContext) {
		Log(LOG_ERROR|LOG_SYS, "EvtCreateRenderContext failed");
		goto cleanup;
	}

	pRenderedEvents = (PEVT_VARIANT)malloc(dwBufferSize);
	/* Use EvtRender to capture the Publisher name from the Event */
	/* Log Errors to the event log if things go wrong */
	if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedEvents, &dwReturned, &dwValuesCount)) {
		if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
			dwBufferSize = dwReturned;
			realloc(pRenderedEvents, dwBufferSize);
			if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedEvents, &dwReturned, &dwValuesCount)) {
				if (LogInteractive)
					Log(LOG_ERROR|LOG_SYS, "Error Rendering Event");
				status = ERR_FAIL;
			}
		} else {
			status = ERR_FAIL;
			if (LogInteractive)
				Log(LOG_ERROR|LOG_SYS, "Error Rendering Event");
		}
	}

cleanup:
	if (hContext)
		EvtClose(hContext);

	if (status == ERR_FAIL)
		return NULL;
	else 
		return pRenderedEvents;
}
void send_channel_event(EVT_HANDLE evt, os_channel *channel)
{
    DWORD buffer_length = 0;
    PEVT_VARIANT properties_values = NULL;
    DWORD count = 0;
    EVT_HANDLE context = NULL;
    os_event event = {0};
    char final_msg[OS_MAXSTR];
    int result = 0;

    if ((context = EvtCreateRenderContext(count, NULL, EvtRenderContextSystem)) == NULL) {
        log2file(
            "%s: ERROR: Could not EvtCreateRenderContext() for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    /* Make initial call to determine buffer size necessary */
    result = EvtRender(context,
                       evt,
                       EvtRenderEventValues,
                       0,
                       NULL,
                       &buffer_length,
                       &count);
    if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        log2file(
            "%s: ERROR: Could not EvtRender() to determine buffer size for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if ((properties_values = malloc(buffer_length)) == NULL) {
        log2file(
            "%s: ERROR: Could not malloc() memory to process event (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    if (!EvtRender(context,
                   evt,
                   EvtRenderEventValues,
                   buffer_length,
                   properties_values,
                   &buffer_length,
                   &count)) {
        log2file(
            "%s: ERROR: Could not EvtRender() for (%s) which returned (%lu)",
            ARGV0,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    event.name = get_property_value(&properties_values[EvtSystemChannel]);
    event.id = properties_values[EvtSystemEventID].UInt16Val;
    event.source = get_property_value(&properties_values[EvtSystemProviderName]);
    event.uid = properties_values[EvtSystemUserID].Type == EvtVarTypeNull ? NULL : properties_values[EvtSystemUserID].SidVal;
    event.computer = get_property_value(&properties_values[EvtSystemComputer]);
    event.time_created = properties_values[EvtSystemTimeCreated].FileTimeVal;
    event.keywords = properties_values[EvtSystemKeywords].Type == EvtVarTypeNull ? 0 : properties_values[EvtSystemKeywords].UInt64Val;
    event.level = properties_values[EvtSystemLevel].Type == EvtVarTypeNull ? -1 : properties_values[EvtSystemLevel].ByteVal;

    switch (event.level) {
        case WINEVENT_CRITICAL:
            event.category = "CRITICAL";
            break;
        case WINEVENT_ERROR:
            event.category = "ERROR";
            break;
        case WINEVENT_WARNING:
            event.category = "WARNING";
            break;
        case WINEVENT_INFORMATION:
            event.category = "INFORMATION";
            break;
        case WINEVENT_VERBOSE:
            event.category = "DEBUG";
            break;
        case WINEVENT_AUDIT:
            if (event.keywords & WINEVENT_AUDIT_FAILURE) {
                event.category = "AUDIT_FAILURE";
                break;
            } else if (event.keywords & WINEVENT_AUDIT_SUCCESS) {
                event.category = "AUDIT_SUCCESS";
                break;
            }
        default:
            event.category = "Unknown";
            break;
    }

    if ((event.timestamp = WinEvtTimeToString(event.time_created)) == NULL) {
        log2file(
            "%s: ERROR: Could not convert timestamp for (%s)",
            ARGV0,
            channel->evt_log);
        goto cleanup;
    }

    /* Determine user and domain */
    get_username_and_domain(&event);

    /* Get event log message */
    if ((event.message = get_message(evt, properties_values[EvtSystemProviderName].StringVal, EvtFormatMessageEvent)) == NULL) {
        log2file(
            "%s: ERROR: Could not get message for (%s)",
            ARGV0,
            channel->evt_log);
    } else {
        /* Format message */
        win_format_event_string(event.message);
    }

    snprintf(
        final_msg,
        sizeof(final_msg),
        "%s WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s",
        event.timestamp,
        event.name,
        event.category,
        event.id,
        event.source && strlen(event.source) ? event.source : "no source",
        event.user && strlen(event.user) ? event.user : "******",
        event.domain && strlen(event.domain) ? event.domain : "no domain",
        event.computer && strlen(event.computer) ? event.computer : "no computer",
        event.message && strlen(event.message) ? event.message : "(no message)"
    );

    if (SendMSG(logr_queue, final_msg, "WinEvtLog", LOCALFILE_MQ) < 0) {
        merror(QUEUE_SEND, ARGV0);
    }

    if (channel->bookmark_enabled) {
        update_bookmark(evt, channel);
    }

cleanup:
    free(properties_values);
    free_event(&event);

    if (context != NULL) {
        EvtClose(context);
    }

    return;
}
Exemple #4
0
/* open eventlog using API 6 and return the number of records */
static int	zbx_open_eventlog6(const wchar_t *wsource, zbx_uint64_t *lastlogsize, EVT_HANDLE *render_context,
		zbx_uint64_t *FirstID, zbx_uint64_t *LastID)
{
	const char	*__function_name = "zbx_open_eventlog6";
	EVT_HANDLE	log = NULL;
	EVT_VARIANT	var;
	EVT_HANDLE	tmp_all_event_query = NULL;
	EVT_HANDLE	event_bookmark = NULL;
	EVT_VARIANT*	renderedContent = NULL;
	DWORD		status = 0;
	DWORD		size_required = 0;
	DWORD		size = DEFAULT_EVENT_CONTENT_SIZE;
	DWORD		bookmarkedCount = 0;
	zbx_uint64_t	numIDs = 0;
	char		*tmp_str = NULL;
	int		ret = FAIL;

	*FirstID = 0;
	*LastID = 0;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	/* try to open the desired log */
	if (NULL == (log = EvtOpenLog(NULL, wsource, EvtOpenChannelPath)))
	{
		tmp_str = zbx_unicode_to_utf8(wsource);
		zabbix_log(LOG_LEVEL_WARNING, "cannot open eventlog '%s':%s", tmp_str,
				strerror_from_system(GetLastError()));
		goto out;
	}

	/* obtain the number of records in the log */
	if (TRUE != EvtGetLogInfo(log, EvtLogNumberOfLogRecords, sizeof(var), &var, &size_required))
	{
		zabbix_log(LOG_LEVEL_WARNING, "EvtGetLogInfo failed:%s",
				strerror_from_system(GetLastError()));
		goto out;
	}

	numIDs = var.UInt64Val;

	/* get the number of the oldest record in the log				*/
	/* "EvtGetLogInfo()" does not work properly with "EvtLogOldestRecordNumber"	*/
	/* we have to get it from the first EventRecordID				*/

	/* create the system render */
	if (NULL == (*render_context = EvtCreateRenderContext(RENDER_ITEMS_COUNT, RENDER_ITEMS, EvtRenderContextValues)))
	{
		zabbix_log(LOG_LEVEL_WARNING, "EvtCreateRenderContext failed:%s", strerror_from_system(GetLastError()));
		goto out;
	}

	/* get all eventlog */
	tmp_all_event_query = EvtQuery(NULL, wsource, NULL, EvtQueryChannelPath);
	if (NULL == tmp_all_event_query)
	{
		if (ERROR_EVT_CHANNEL_NOT_FOUND == (status = GetLastError()))
			zabbix_log(LOG_LEVEL_WARNING, "EvtQuery channel missed:%s", strerror_from_system(status));
		else
			zabbix_log(LOG_LEVEL_WARNING, "EvtQuery failed:%s", strerror_from_system(status));

		goto out;
	}

	/* get the entries and allocate the required space */
	renderedContent = zbx_malloc(renderedContent, size);
	if (TRUE != EvtNext(tmp_all_event_query, 1, &event_bookmark, INFINITE, 0, &size_required))
	{
		/* no data in eventlog */
		zabbix_log(LOG_LEVEL_DEBUG, "first EvtNext failed:%s", strerror_from_system(GetLastError()));
		*FirstID = 1;
		*LastID = 1;
		numIDs = 0;
		*lastlogsize = 0;
		ret = SUCCEED;
		goto out;
	}

	/* obtain the information from selected events */
	if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent,
			&size_required, &bookmarkedCount))
	{
		/* information exceeds the allocated space */
		if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
		{
			zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed:%s", strerror_from_system(GetLastError()));
			goto out;
		}

		renderedContent = (EVT_VARIANT*)zbx_realloc((void *)renderedContent, size_required);
		size = size_required;

		if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent,
				&size_required, &bookmarkedCount))
		{
			zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed:%s", strerror_from_system(GetLastError()));
			goto out;
		}
	}

	*FirstID = VAR_RECORD_NUMBER(renderedContent);
	*LastID = *FirstID + numIDs;

	if (*lastlogsize >= *LastID)
	{
		*lastlogsize = *FirstID - 1;
		zabbix_log(LOG_LEVEL_DEBUG, "lastlogsize is too big. It is set to:" ZBX_FS_UI64, *lastlogsize);
	}

	ret = SUCCEED;
out:
	if (NULL != log)
		EvtClose(log);
	if (NULL != tmp_all_event_query)
		EvtClose(tmp_all_event_query);
	if (NULL != event_bookmark)
		EvtClose(event_bookmark);
	zbx_free(tmp_str);
	zbx_free(renderedContent);
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s FirstID:" ZBX_FS_UI64 " LastID:" ZBX_FS_UI64 " numIDs:" ZBX_FS_UI64,
			__function_name, zbx_result_string(ret), *FirstID, *LastID, numIDs);

	return ret;
}
Exemple #5
0
static int	zbx_get_eventlog_message_xpath(LPCTSTR wsource, zbx_uint64_t *lastlogsize, char **out_source, char **out_message,
										   unsigned short *out_severity, unsigned long *out_timestamp, unsigned long *out_eventid,  unsigned char skip_old_data, void **pcontext)
{
	const char	*__function_name = "zbx_get_eventlog_message_xpath";
	int		ret = FAIL;
	LPSTR		tmp_str = NULL;
	LPWSTR		tmp_wstr = NULL;
	LPWSTR		event_query = NULL; /* L"Event/System[EventRecordID=WHICH]" */
	unsigned long	status = ERROR_SUCCESS;
	PEVT_VARIANT	eventlog_array = NULL;
	HANDLE			providermetadata_handle = NULL;
	LPWSTR		query_array[] = {
		L"/Event/System/Provider/@Name",
		L"/Event/System/EventID",
		L"/Event/System/Level",
		L"/Event/System/TimeCreated/@SystemTime",
		L"/Event/System/EventRecordID"};
	DWORD		array_count = 5;
	DWORD		dwReturned = 0, dwValuesCount = 0, dwBufferSize = 0;
	const ULONGLONG	sec_1970 = 116444736000000000;
	static HMODULE hmod_wevtapi = NULL;

	zbx_eventlog_context *context;

	assert(out_source);
	assert(out_message);
	assert(out_severity);
	assert(out_timestamp);
	assert(out_eventid);

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() which:%lld", __function_name, *lastlogsize);
	
	*out_source	= NULL;
	*out_message	= NULL;
	*out_severity	= 0;
	*out_timestamp	= 0;
	*out_eventid = 0;

	/* We have to use LoadLibrary() to load wevtapi.dll to avoid it required even before Vista. */
	/* load wevtapi.dll once */
	if (NULL == hmod_wevtapi)
	{
		hmod_wevtapi = LoadLibrary(L"wevtapi.dll");
		if (NULL == hmod_wevtapi)
		{
			zabbix_log(LOG_LEVEL_WARNING, "Can't load wevtapi.dll");
			goto finish;
		}
		zabbix_log(LOG_LEVEL_DEBUG, "wevtapi.dll was loaded");
		/* get function pointer from wevtapi.dll */
		(FARPROC)EvtQuery = GetProcAddress(hmod_wevtapi, "EvtQuery");
		(FARPROC)EvtCreateRenderContext = GetProcAddress(hmod_wevtapi, "EvtCreateRenderContext");
		(FARPROC)EvtNext = GetProcAddress(hmod_wevtapi, "EvtNext");
		(FARPROC)EvtRender = GetProcAddress(hmod_wevtapi, "EvtRender");
		(FARPROC)EvtOpenPublisherMetadata = GetProcAddress(hmod_wevtapi, "EvtOpenPublisherMetadata");
		(FARPROC)EvtFormatMessage = GetProcAddress(hmod_wevtapi, "EvtFormatMessage");
		(FARPROC)EvtClose = GetProcAddress(hmod_wevtapi, "EvtClose");
		if (NULL == EvtQuery ||
			NULL == EvtCreateRenderContext ||
			NULL == EvtNext ||
			NULL == EvtRender ||
			NULL == EvtOpenPublisherMetadata ||
			NULL == EvtFormatMessage ||
			NULL == EvtClose)
		{
			zabbix_log(LOG_LEVEL_WARNING, "Can't load wevtapi.dll functions");
			goto finish;
		}
		zabbix_log(LOG_LEVEL_DEBUG, "wevtapi.dll functions were loaded");
	}
	
	context = *pcontext;
	if (context == NULL)
	{
		context = zbx_malloc(NULL, sizeof(*context));
		memset(context, 0, sizeof(*context));
		
		tmp_str = zbx_dsprintf(NULL, "Event/System[EventRecordID>%lld]", *lastlogsize);
		event_query = zbx_utf8_to_unicode(tmp_str);
		zbx_free(tmp_str);
		
		context->handle = EvtQuery(NULL, wsource, event_query, skip_old_data? EvtQueryChannelPath|EvtQueryReverseDirection: EvtQueryChannelPath);
		
		if (NULL == context->handle)
		{
			status = GetLastError();
			
			if (ERROR_EVT_CHANNEL_NOT_FOUND == status)
			{
				zabbix_log(LOG_LEVEL_WARNING, "Missed eventlog");
			}
			else
			{
				zabbix_log(LOG_LEVEL_WARNING, "EvtQuery failed");
			}
			goto finish;
		}
		
		context->context_handle = EvtCreateRenderContext(array_count, (LPCWSTR*)query_array, EvtRenderContextValues);
		if (NULL == context->context_handle)
		{
			zabbix_log(LOG_LEVEL_WARNING, "EvtCreateRenderContext failed");
			goto finish;
		}
		*pcontext = context;
	}

	if (context->each_handle)
	{
		EvtClose(context->each_handle);
		context->each_handle = NULL;
	}
	if (!EvtNext(context->handle, 1, &context->each_handle, INFINITE, 0, &dwReturned))
	{
		status = GetLastError();
		if (ERROR_NO_MORE_ITEMS == status)
		{
			zabbix_log(LOG_LEVEL_DEBUG, "EvtNext no more items.");
			ret = SUCCEED;
		}
		else
		{
			zabbix_log(LOG_LEVEL_WARNING, "First EvtNext failed with %lu", status);
		}
		goto finish;
	}

	if (!EvtRender(context->context_handle, context->each_handle, EvtRenderEventValues,
				   dwBufferSize, eventlog_array, &dwReturned, &dwValuesCount))
	{
		if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
		{
			dwBufferSize = dwReturned;
			if (NULL == (eventlog_array = (PEVT_VARIANT)zbx_malloc(eventlog_array, dwBufferSize)))
			{
				zabbix_log(LOG_LEVEL_WARNING, "EvtRender malloc failed");
				goto finish;
			}
			if (!EvtRender(context->context_handle, context->each_handle, EvtRenderEventValues,
						   dwBufferSize, eventlog_array, &dwReturned, &dwValuesCount))
			{
				zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed");
				goto finish;
			}
		}
		
		if (ERROR_SUCCESS != (status = GetLastError()))
		{
			zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed with %d", status);
			goto finish;
		}
	}

	*out_source = zbx_unicode_to_utf8(eventlog_array[0].StringVal);
	
	providermetadata_handle = EvtOpenPublisherMetadata(NULL, eventlog_array[0].StringVal, NULL, 0, 0);
	if (NULL != providermetadata_handle)
	{
		dwBufferSize = 0;
		dwReturned = 0;
		
		if (!EvtFormatMessage(providermetadata_handle, context->each_handle, 0, 0,
							  NULL, EvtFormatMessageEvent, dwBufferSize, tmp_wstr, &dwReturned))
		{
			if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
			{
				dwBufferSize = dwReturned;
				if (NULL == (tmp_wstr = (LPWSTR)zbx_malloc(tmp_wstr, dwBufferSize * sizeof(WCHAR))))
				{
					zabbix_log(LOG_LEVEL_WARNING, "EvtFormatMessage malloc failed");
					goto finish;
				}
				if (!EvtFormatMessage(providermetadata_handle, context->each_handle, 0, 0,
									  NULL, EvtFormatMessageEvent, dwBufferSize, tmp_wstr, &dwReturned))
				{
					zabbix_log(LOG_LEVEL_WARNING, "EvtFormatMessage failed");
					goto finish;
				}
			}
			
			if (ERROR_SUCCESS != (status = GetLastError()))
			{
				zabbix_log(LOG_LEVEL_WARNING, "EvtFormatMessage failed with %d", status);
				goto finish;
			}
		}
		*out_message= zbx_unicode_to_utf8(tmp_wstr);
	}
	else
	{
		zabbix_log(LOG_LEVEL_DEBUG, "EvtOpenPublisherMetadata failed with %d: no description availabel", GetLastError());
		*out_message = zbx_strdup(NULL, "");
	}

	*out_eventid = eventlog_array[1].UInt16Val;
	*out_severity = eventlog_array[2].ByteVal;
	*out_timestamp = (unsigned long)((eventlog_array[3].FileTimeVal - sec_1970) / 10000000);
	*lastlogsize = eventlog_array[4].UInt64Val;

	ret = SUCCEED;
	
finish:
	zbx_free(tmp_str);
	zbx_free(tmp_wstr);
	zbx_free(event_query);
	zbx_free(eventlog_array);
	if (FAIL == ret)
	{
		zbx_free(*out_source);
		zbx_free(*out_message);
	}

	if (providermetadata_handle)
		EvtClose(providermetadata_handle);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Exemple #6
0
int	get_eventlog_keywords(void *v, zbx_uint64_t *out_keywords)
{
	const char	*__function_name = "zbx_get_event_keyword";
	int ret = FAIL;
	zbx_eventlog_context *context = v;
	LPWSTR query = L"/Event/System/Keywords";
	PEVT_VARIANT	eventlog_array = NULL;
	DWORD		dwReturned = 0, dwValuesCount = 0, dwBufferSize = 0;
	unsigned long	status = ERROR_SUCCESS;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
	*out_keywords = 0;
	context = v;
	if (context == NULL)
	{
		zabbix_log(LOG_LEVEL_WARNING, "invalid context");
		goto finish;
	}
	
	if (context->keyword_context_handle == NULL)
	{
		context->keyword_context_handle = EvtCreateRenderContext(1, &query, EvtRenderContextValues);
		if (context->keyword_context_handle == NULL)
		{
			zabbix_log(LOG_LEVEL_WARNING, "can't create render context");
			goto finish;
		}
	}
	if (!EvtRender(context->keyword_context_handle, context->each_handle, EvtRenderEventValues,
				   dwBufferSize, eventlog_array, &dwReturned, &dwValuesCount))
	{
		if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
		{
			dwBufferSize = dwReturned;
			if (NULL == (eventlog_array = (PEVT_VARIANT)zbx_malloc(eventlog_array, dwBufferSize)))
			{
				zabbix_log(LOG_LEVEL_WARNING, "EvtRender malloc failed");
				goto finish;
			}
			if (!EvtRender(context->keyword_context_handle, context->each_handle, EvtRenderEventValues,
						   dwBufferSize, eventlog_array, &dwReturned, &dwValuesCount))
			{
				zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed");
				goto finish;
			}
		}
		
		if (ERROR_SUCCESS != (status = GetLastError()))
		{
			zabbix_log(LOG_LEVEL_WARNING, "EvtRender failed with %d", GetLastError());
			goto finish;
		}
	}

	*out_keywords = eventlog_array[0].UInt64Val;
	ret = SUCCEED;
	
finish:
	zbx_free(eventlog_array);
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));
	return ret;
}
/**
* @brief Enumerate all the events in the result set.
* @param eventHandle A handle to an event.
*
* @return returns Print event status.
*/
DWORD EventLogReader::PrintEvent(EVT_HANDLE eventHandle)
{
    EVT_HANDLE context = nullptr;
    PEVT_VARIANT renderedValues = nullptr;
    DWORD status = ERROR_SUCCESS;
    do
    {
        // Identify the components of the event that you want to render. In this case,
        // render the system section of the event.
        context = EvtCreateRenderContext(0, nullptr, EvtRenderContextSystem);
        if (context == nullptr)
        {
            status = GetLastError();
            break;
        }
        // When you render the user data or system section of the event, you must specify
        // the EvtRenderEventValues flag. The function returns an array of variant values
        // for each element in the user data or system section of the event. For user data
        // or event data, the values are returned in the same order as the elements are
        // defined in the event. For system data, the values are returned in the order defined
        // in the EVT_SYSTEM_PROPERTY_ID enumeration.
        DWORD bufferSize = 0;
        DWORD bufferUsed = 0;
        DWORD propertyCount = 0;
        if (!EvtRender(context, eventHandle, EvtRenderEventValues, bufferSize, renderedValues, &bufferUsed, &propertyCount))
        {
            status = GetLastError();
            if (status == ERROR_INSUFFICIENT_BUFFER)
            {
                bufferSize = bufferUsed;
                renderedValues = (PEVT_VARIANT)malloc(bufferSize);
                if (renderedValues != nullptr)
                {
                    EvtRender(context, eventHandle, EvtRenderEventValues, bufferSize, renderedValues, &bufferUsed, &propertyCount);
                    status = GetLastError();
                }
                else
                {
                    status = ERROR_OUTOFMEMORY;
                    break;
                }
            }
            if (status != ERROR_SUCCESS)
                break;
        }
        std::map<std::string, std::string> eventData;

        std::wstring tempBuf = (renderedValues[EvtSystemProviderName].StringVal) ? renderedValues[EvtSystemProviderName].StringVal : L"";
        eventData["providername"] = base::wstring_to_string(tempBuf);
        if (renderedValues[EvtSystemProviderGuid].GuidVal != nullptr)
        {
            WCHAR guid[50] = {0};
            StringFromGUID2(*(renderedValues[EvtSystemProviderGuid].GuidVal), guid, sizeof(guid) / sizeof(WCHAR));
            eventData["providerguid"] = base::wstring_to_string(guid);
        }

        DWORD eventId = renderedValues[EvtSystemEventID].UInt16Val;
        if (renderedValues[EvtSystemQualifiers].Type == EvtVarTypeNull)
            eventId = MAKELONG(renderedValues[EvtSystemEventID].UInt16Val, renderedValues[EvtSystemQualifiers].UInt16Val);
        char buf[1024] = { 0 };
        snprintf(buf, sizeof(buf), "%lu", eventId);
        eventData["eventid"] = buf;

        snprintf(buf, sizeof(buf), "%u", (renderedValues[EvtSystemVersion].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemVersion].ByteVal);
        eventData["version"] = buf;

        snprintf(buf, sizeof(buf), "%u", (renderedValues[EvtSystemLevel].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemLevel].ByteVal);
        eventData["level"] = buf;

        snprintf(buf, sizeof(buf), "%hu", (renderedValues[EvtSystemTask].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemTask].ByteVal);
        eventData["task"] = buf;

        snprintf(buf, sizeof(buf), "%u", (renderedValues[EvtSystemOpcode].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemOpcode].UInt16Val);
        eventData["opcode"] = buf;

        snprintf(buf, sizeof(buf), "%0x%I64x", (renderedValues[EvtSystemKeywords].Type == EvtVarTypeNull) ? 0 : renderedValues[EvtSystemOpcode].UInt64Val);
        eventData["keywords"] = buf;

        ULONGLONG ullTimeStamp = renderedValues[EvtSystemTimeCreated].FileTimeVal;
        FILETIME ft;
        ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
        ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);
        SYSTEMTIME st;
        FileTimeToSystemTime(&ft, &st);
        ULONGLONG ullNanoseconds = (ullTimeStamp % 10000000) * 100; // Display nanoseconds instead of milliseconds for higher resolution
        snprintf(buf, sizeof(buf), "%02d/%02d/%02d %02d:%02d:%02d.%I64u", st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, ullNanoseconds);
        eventData["timecreated"] = buf;

        snprintf(buf, sizeof(buf), "%I64u", renderedValues[EvtSystemEventRecordId].UInt64Val);
        eventData["eventrecordid"] = buf;

        if (renderedValues[EvtSystemActivityID].Type != EvtVarTypeNull)
        {
            WCHAR guid[50] = { 0 };
            StringFromGUID2(*(renderedValues[EvtSystemActivityID].GuidVal), guid, sizeof(guid) / sizeof(WCHAR));;
            eventData["activityid"] = base::wstring_to_string(guid);
        }

        if (renderedValues[EvtSystemRelatedActivityID].Type != EvtVarTypeNull)
        {
            WCHAR guid[50] = { 0 };
            StringFromGUID2(*(renderedValues[EvtSystemRelatedActivityID].GuidVal), guid, sizeof(guid) / sizeof(WCHAR));;
            eventData["relatedactivityid"] = base::wstring_to_string(guid);
        }

        snprintf(buf, sizeof(buf), "%lu", renderedValues[EvtSystemProcessID].UInt32Val);
        eventData["processid"] = buf;

        snprintf(buf, sizeof(buf), "%lu", renderedValues[EvtSystemThreadID].UInt32Val);
        eventData["threadid"] = buf;

        tempBuf = (renderedValues[EvtSystemChannel].Type == EvtVarTypeNull) ? renderedValues[EvtSystemChannel].StringVal : L"";
        eventData["channel"] = base::wstring_to_string(tempBuf);

        eventData["computer"] = base::wstring_to_string(renderedValues[EvtSystemComputer].StringVal);

        if (renderedValues[EvtSystemUserID].Type != EvtVarTypeNull)
        {
            LPWSTR pwsSid = nullptr;
            if (ConvertSidToStringSid(renderedValues[EvtSystemUserID].SidVal, &pwsSid))
            {
                eventData["secuserid"] = base::wstring_to_string(pwsSid);
                LocalFree(pwsSid);
            }
        }
        // Get the handle to the provider's metadata that contains the message strings.
        EVT_HANDLE providerMetadata = EvtOpenPublisherMetadata(nullptr, renderedValues[EvtSystemProviderName].StringVal, nullptr, 0, 0);
        if (providerMetadata == nullptr)
            break;
        eventData["message"] = GetMessageString(providerMetadata, eventHandle);
        _printResultsCallback(eventData);
    } while (false);

    if (context)
        EvtClose(context);
    if (renderedValues)
        free(renderedValues);
    return status;
}