Esempio n. 1
0
/**
* @brief Enumerate all the events in the result set.

* @param results The handle to a query or subscription result set that
*                the EvtQuery function or the EvtSubscribe function returns.
*
* @return returns Status code.
*/
DWORD EventLogReader::PrintResults(EVT_HANDLE results)
{
    DWORD status = ERROR_SUCCESS;
    static const int ArraySize = 10;

    DWORD returned = 0;
    EVT_HANDLE events[ArraySize] = { 0 };
    bool run = true;
    while (run)
    {
        // Get a block of events from the result set.
        if (!EvtNext(results, ArraySize, events, INFINITE, 0, &returned))
            break;
        // For each event, call the PrintEvent function which renders the
        // event for display. PrintEvent is shown in RenderingEvents.
        for (DWORD i = 0; i < returned; i++)
        {
            _position++;
            status = PrintEvent(events[i]);
            if (status == ERROR_SUCCESS)
            {
                EvtClose(events[i]);
                events[i] = nullptr;
            }
            else
            {
                run = false;
                break;
            }
        }
    }
    for (DWORD i = 0; i < returned; i++)
    {
        if (events[i] != nullptr)
            EvtClose(events[i]);
    }
    return status;
}
Esempio n. 2
0
/****
 * ProcessResults
 *
 * DESC:
 *     Creates a remote context 
 *
 * ARGS:
 *     hRemote - Remote session context
 *     hResults - An open set of results
 *     outputFormat - 0 for JSON, otherwise XML
 *     mode - last record vs dump results
 *     debug - set to 0 (none) 1 (basic) or 2 (verbose)
 */
DWORD64 ProcessResults(EVT_HANDLE hRemote, EVT_HANDLE hResults, int outputFormat, int mode, int debug)
{
    DWORD64 status = ERROR_SUCCESS;
    EVT_HANDLE hEvents[CHUNK_SIZE + 1];
    DWORD dwReturned = 0;
	BOOL completed = FALSE;	
	BOOL firstRecordCompleted = FALSE;

	// Print header information for our events
	if( outputFormat == OUTPUT_FORMAT_JSON ) {
		// Note: Marc requested this to be removed
		//wprintf(L"[");
	} else {
		wprintf(L"%s||%s||%s||%s||%s||%s||%s||%s\n\n", L"RecordID", L"EventID", L"Channel", L"Provider", L"Computer", L"TimeCreated", L"Task", L"Level");
	}

	// Begin an infinite loop, as we want to continue reading records as long as they are available.
	// The break-condition is a manual one at the bottom (i.e. no more records found)
    while (TRUE)
    {
        // Get a block of events from the result set.
        if (EvtNext(hResults, CHUNK_SIZE, hEvents, INFINITE, 0, &dwReturned))
        {
			// Cycle through all the events that we received
			for (DWORD i = 0; i < dwReturned; i++)
			{
				// Only print the separator characters once the first record is completed
				if( firstRecordCompleted )
					wprintf(L"||");

				// Extract event details and output the screen
				DWORD64 result = DumpEventInfo(hRemote, hEvents[i], outputFormat, mode, debug);
				
				// Set flag indicating first record is completed so that
				// the top of our loop knows to begin printing the separator character
				firstRecordCompleted = TRUE;

				// Close the handle to the current event, as we are done
				EvtClose(hEvents[i]);

				// Clear the event handle so our cleanup routine does not attempt to re-close
				hEvents[i] = NULL;

				// If currently in "last record" mode			
				if( mode == MODE_FETCH_LAST_RECORD ) {
					// We do not need to process anymore events
					// Recall that all we were looking for was the record ID of the most recent record
					// This should be stored in "status" as, this is the variable that's returned
					status = result;

					completed = true;

					break;
				}
			}
        }
		else 
		{
			// Call to retrieve events failed. Get the error code
			status = GetLastError();

			// If the error was the result of not having any more records
            if (status == ERROR_NO_MORE_ITEMS)
            {
				// Exit the loop. No more records to process
				completed = TRUE;
            }
			else 
			{
				// Otherwise, notify user of the error
                fwprintf(stderr, L"Failed to fetch next batch with following error: %lu\n", status);
			}
		}

		// Cycle through all records that we received
		// Recall that dwReturned contains the number of records received
		for (DWORD i = 0; i < dwReturned; i++)
		{
			// If the event isn't already closed
			if (hEvents[i] != NULL) 
			{
				// Close the event record
				EvtClose(hEvents[i]);
			}
		}

		// Exit the loop if required (i.e. we're done)
		if( completed )
			break;
	}

	// Add closing tag if this is JSON
	if( outputFormat == OUTPUT_FORMAT_JSON ) {
		// Marc requested this to be removed
		// wprintf(L"]");
	}

    return status;
}
Esempio n. 3
0
ULONG
QueryEvents (
    __in PCWSTR Channel,
    __in PCWSTR XPath
)

/*++

Routine Description:

    This function queries events from the given channel and prints their
    description to the standard output.

Arguments:

    Channel - Supplies the name of the channel whose events will be displayed.

    XPath - Supplies the XPath expression to filter events with.

Return Value:

    Win32 error code indicating if querying was successful.

--*/

{
    PWSTR Buffer;
    ULONG BufferSize;
    ULONG BufferSizeNeeded;
    ULONG Count;
    EVT_HANDLE Event;
    EVT_HANDLE Query;
    ULONG Status;

    //
    // Create the query.
    //

    Query = EvtQuery(NULL, Channel, XPath, EvtQueryChannelPath);
    if (Query == NULL) {
        return GetLastError();
    }

    //
    // Read each event and render it as XML.
    //

    Buffer = NULL;
    BufferSize = 0;
    BufferSizeNeeded = 0;

    while (EvtNext(Query, 1, &Event, INFINITE, 0, &Count) != FALSE) {

        do {
            if (BufferSizeNeeded > BufferSize) {
                free(Buffer);
                BufferSize = BufferSizeNeeded;
                Buffer = malloc(BufferSize);
                if (Buffer == NULL) {
                    Status = ERROR_OUTOFMEMORY;
                    BufferSize = 0;
                    break;
                }
            }

            if (EvtRender(NULL,
                          Event,
                          EvtRenderEventXml,
                          BufferSize,
                          Buffer,
                          &BufferSizeNeeded,
                          &Count) != FALSE) {
                Status = ERROR_SUCCESS;
            } else {
                Status = GetLastError();
            }
        } while (Status == ERROR_INSUFFICIENT_BUFFER);

        //
        // Display either the event xml or an error message.
        //

        if (Status == ERROR_SUCCESS) {
            wprintf(L"%s\n", Buffer);
        } else {
            wprintf(L"Error rendering event.\n");
        }

        EvtClose(Event);
    }

    //
    // When EvtNextChannelPath returns ERROR_NO_MORE_ITEMS, we have actually
    // iterated through all matching events and thus succeeded.
    //

    Status = GetLastError();
    if (Status == ERROR_NO_MORE_ITEMS) {
        Status = ERROR_SUCCESS;
    }

    //
    // Free resources.
    //

    EvtClose(Query);
    free(Buffer);

    return Status;
}
Esempio n. 4
0
/* obtain a particular message from a desired eventlog */
static int	zbx_get_eventlog_message6(const wchar_t *wsource, zbx_uint64_t *which, unsigned short *out_severity,
		unsigned long *out_timestamp, char **out_provider, char **out_source, char **out_message,
		unsigned long *out_eventid, EVT_HANDLE *render_context, EVT_HANDLE *query, zbx_uint64_t *keywords)
{
	const char		*__function_name = "zbx_get_eventlog_message6";
	EVT_HANDLE		event_bookmark = NULL;
	EVT_VARIANT*		renderedContent = NULL;
	const wchar_t		*pprovider = NULL;
	char			*tmp_str = NULL;
	DWORD			size = DEFAULT_EVENT_CONTENT_SIZE;
	DWORD			bookmarkedCount = 0;
	DWORD			require = 0;
	const zbx_uint64_t	sec_1970 = 116444736000000000;
	const zbx_uint64_t	success_audit = 0x20000000000000;
	const zbx_uint64_t	failure_audit = 0x10000000000000;
	int			ret = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() EventRecordID:" ZBX_FS_UI64, __function_name, *which);

	if (NULL == *query)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "%s() no EvtQuery handle", __function_name);
		goto out;
	}

	/* get the entries */
	if (TRUE != EvtNext(*query, 1, &event_bookmark, INFINITE, 0, &require))
	{
		/* The event reading query had less items than we calculated before. */
		/* Either the eventlog was cleaned or our calculations were wrong.   */
		/* Either way we can safely abort the query by setting NULL value    */
		/* and returning success, which is interpreted as empty eventlog.    */
		if (ERROR_NO_MORE_ITEMS == GetLastError())
		{
			ret = SUCCEED;
		}
		else
		{
			zabbix_log(LOG_LEVEL_WARNING, "EvtNext failed: %s, EventRecordID:" ZBX_FS_UI64,
				strerror_from_system(GetLastError()), *which);
		}
		goto out;
	}

	/* obtain the information from the selected events */

	renderedContent = (EVT_VARIANT *)zbx_malloc((void *)renderedContent, size);

	if (TRUE != EvtRender(*render_context, event_bookmark, EvtRenderEventValues, size, renderedContent,
			&require, &bookmarkedCount))
	{
		/* information exceeds the space allocated */
		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, require);
		size = require;

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

	pprovider = VAR_PROVIDER_NAME(renderedContent);
	*out_provider = zbx_unicode_to_utf8(pprovider);

	if (NULL != VAR_SOURCE_NAME(renderedContent))
	{
		*out_source = zbx_unicode_to_utf8(VAR_SOURCE_NAME(renderedContent));
	}

	*keywords = VAR_KEYWORDS(renderedContent) & (success_audit | failure_audit);
	*out_severity = VAR_LEVEL(renderedContent);
	*out_timestamp = (unsigned long)((VAR_TIME_CREATED(renderedContent) - sec_1970) / 10000000);
	*out_eventid = VAR_EVENT_ID(renderedContent);
	*out_message = expand_message6(pprovider, event_bookmark);

	tmp_str = zbx_unicode_to_utf8(wsource);

	if (VAR_RECORD_NUMBER(renderedContent) != *which)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "%s() Overwriting expected EventRecordID:" ZBX_FS_UI64 " with the real"
				" EventRecordID:" ZBX_FS_UI64 " in eventlog '%s'", __function_name, *which,
				VAR_RECORD_NUMBER(renderedContent), tmp_str);
		*which = VAR_RECORD_NUMBER(renderedContent);
	}

	/* some events don't have enough information for making event message */
	if (NULL == *out_message)
	{
		*out_message = zbx_strdcatf(*out_message, "The description for Event ID:%lu in Source:'%s'"
				" cannot be found. Either the component that raises this event is not installed"
				" on your local computer or the installation is corrupted. You can install or repair"
				" the component on the local computer. If the event originated on another computer,"
				" the display information had to be saved with the event.", *out_eventid,
				NULL == *out_provider ? "" : *out_provider);

		if (EvtVarTypeString == (VAR_EVENT_DATA_TYPE(renderedContent) & EVT_VARIANT_TYPE_MASK))
		{
			unsigned int	i;
			char		*data = NULL;

			if (0 != (VAR_EVENT_DATA_TYPE(renderedContent) & EVT_VARIANT_TYPE_ARRAY) &&
				0 < VAR_EVENT_DATA_COUNT(renderedContent))
			{
				*out_message = zbx_strdcatf(*out_message, " The following information was included"
						" with the event: ");

				for (i = 0; i < VAR_EVENT_DATA_COUNT(renderedContent); i++)
				{
					if (NULL != VAR_EVENT_DATA_STRING_ARRAY(renderedContent, i))
					{
						if (0 < i)
							*out_message = zbx_strdcat(*out_message, "; ");

						data = zbx_unicode_to_utf8(VAR_EVENT_DATA_STRING_ARRAY(renderedContent, i));
						*out_message = zbx_strdcatf(*out_message, "%s", data);
						zbx_free(data);
					}
				}
			}
			else if (NULL != VAR_EVENT_DATA_STRING(renderedContent))
			{
				data = zbx_unicode_to_utf8(VAR_EVENT_DATA_STRING(renderedContent));
				*out_message = zbx_strdcatf(*out_message, "The following information was included"
						" with the event: %s", data);
				zbx_free(data);
			}
		}
	}

	ret = SUCCEED;
out:
	if (NULL != event_bookmark)
		EvtClose(event_bookmark);
	zbx_free(tmp_str);
	zbx_free(renderedContent);
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
    PWHEA_ERROR_RECORD ErrorRecord;
    EVT_HANDLE EventHandle;
    DWORD LastError;
    DWORD PropertyCount;
    DWORD RecordSize;
    EVT_HANDLE RenderContext;
    BOOL Result;
    DWORD Returned;
    PEVT_VARIANT Variant;

    EventHandle = NULL;
    RenderContext = NULL;
    Buffer = NULL;
    LastError = NO_ERROR;

    Result = EvtNext(QueryHandle, 1, &EventHandle, (DWORD)-1, 0, &Returned);
    if (Result == FALSE) {
        EventHandle = NULL;
        goto GetNextWheaLogEntryEnd;
    }

    RenderContext = EvtCreateRenderContext(0, NULL, EvtRenderContextUser);
    if (RenderContext == NULL) {
        Result = FALSE;
        goto GetNextWheaLogEntryEnd;
    }

    //
    // Make the call to the rendering routine to determine the buffer size
    // required to contain the rendered event. This call should fail with an
    // insufficient buffer error. Anything else (including success) is an
Esempio n. 8
0
/* obtain a particular message from a desired eventlog */
static int	zbx_get_eventlog_message6(const wchar_t *wsource, zbx_uint64_t *which, unsigned short *out_severity,
		unsigned long *out_timestamp, char **out_provider, char **out_source, char **out_message,
		unsigned long *out_eventid, EVT_HANDLE *render_context, EVT_HANDLE *query, zbx_uint64_t *keywords)
{
	const char		*__function_name = "zbx_get_eventlog_message6";
	EVT_HANDLE		event_bookmark = NULL;
	EVT_VARIANT*		renderedContent = NULL;
	const wchar_t		*pprovider = NULL;
	char			*tmp_str = NULL;
	DWORD			size = DEFAULT_EVENT_CONTENT_SIZE;
	DWORD			bookmarkedCount = 0;
	DWORD			require = 0;
	const zbx_uint64_t	sec_1970 = 116444736000000000;
	const zbx_uint64_t	success_audit = 0x20000000000000;
	const zbx_uint64_t	failure_audit = 0x10000000000000;
	int			ret = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() lastlogsize:" ZBX_FS_UI64, __function_name, *which);

	if (NULL == *query)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "no EvtQuery handle");
		goto finish;
	}

	/* get the entries and allocate required space */
	renderedContent = zbx_malloc(renderedContent, size);
	if (TRUE != EvtNext(*query, 1, &event_bookmark, INFINITE, 0, &require))
	{
		zabbix_log(LOG_LEVEL_WARNING, "EvtNext failed: %s, lastlogsize:" ZBX_FS_UI64,
				strerror_from_system(GetLastError()), *which);
		goto finish;
	}

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

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

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

	pprovider = VAR_PROVIDER_NAME(renderedContent);
	*out_provider = zbx_unicode_to_utf8(pprovider);

	if (NULL != VAR_SOURCE_NAME(renderedContent))
	{
		*out_source = zbx_unicode_to_utf8(VAR_SOURCE_NAME(renderedContent));
	}

	*keywords = VAR_KEYWORDS(renderedContent) & (success_audit | failure_audit);
	*out_severity = VAR_LEVEL(renderedContent);
	*out_timestamp = (unsigned long)((VAR_TIME_CREATED(renderedContent) - sec_1970) / 10000000);
	*out_eventid = VAR_EVENT_ID(renderedContent);
	*out_message = expand_message6(pprovider, event_bookmark);

	tmp_str = zbx_unicode_to_utf8(wsource);

	if (VAR_RECORD_NUMBER(renderedContent) != *which)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "Overwriting expected EventRecordID:" ZBX_FS_UI64 " with the real"
				" EventRecordID:" ZBX_FS_UI64 " in eventlog '%s'", *which,
				VAR_RECORD_NUMBER(renderedContent), tmp_str);
		*which = VAR_RECORD_NUMBER(renderedContent);
	}

	/* some events dont have enough information for making event message */
	if (NULL == *out_message)
	{
		*out_message = zbx_strdcatf(*out_message, "The description for Event ID:%lu in Source:'%s'"
				" cannot be found. Either the component that raises this event is not installed"
				" on your local computer or the installation is corrupted. You can install or repair"
				" the component on the local computer. If the event originated on another computer,"
				" the display information had to be saved with the event.", *out_eventid,
				NULL == *out_provider ? "" : *out_provider);
	}

	ret = SUCCEED;

finish:
	if (NULL != event_bookmark)
		EvtClose(event_bookmark);
	zbx_free(tmp_str);
	zbx_free(renderedContent);
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}