Exemplo n.º 1
0
/* 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;
}
Exemplo n.º 2
0
void RenderContext::getValues(const Event& event, Variant* values, std::size_t n)
{
  EVT_HANDLE handle = handle_.get();
  DWORD used = 0;
  DWORD properties = 0;
  bool success = EvtRender(
        handle,
        event.getHandle(),
        EvtRenderEventValues,
        n * sizeof(EVT_VARIANT),
        values,
        &used,
        &properties);

  if (!success) {
    throw WinException(L"EvtRender", GetLastError());
  }

  if (n * sizeof(EVT_VARIANT) > used || n != properties) {
    throw WinException(L"RenderContext::getValues", ERROR_BAD_ARGUMENTS);
  }
}
Exemplo n.º 3
0
/****
 * DumpEventInfo
 *
 * DESC:
 *     This function has two purposes depending on the mode. It will
 *     either (1) Print the contents of an event (if normal mode) or
 *     (2) return the latest record ID (if "last record" mode)
 *
 * ARGS:
 *     hRemote - Remote session context
 *     hResults - An open set of results
 *     outputFormat - 0 for JSON, otherwise XML
 *     mode - last record vs print results
 *     debug - set to 0 (none) 1 (basic) or 2 (verbose)
 *
 * REMARKS:
 */
DWORD64 DumpEventInfo(EVT_HANDLE hRemote, EVT_HANDLE hEvent, INT outputFormat, INT mode, INT debug)
{
    DWORD64 dwError = ERROR_SUCCESS;
    DWORD dwBufferSize = 0;
    DWORD dwBufferUsed = 0;
    DWORD dwPropertyCount = 0;
    LPWSTR pwsBuffer = NULL;
	rapidxml::xml_document<WCHAR> doc;

	if( debug >= DEBUG_L2 ) {
		wprintf(L"[DumpEventInfo]: Attempting to read event XML with no buffer\n" );
	}

    // Attempt to read the event as an XML string
	//
	// Note: We are expecting this call to fail, as we have NOT provided a buffer. Therefore
	// the purpose of this call is to fail, and have dwBufferUsed updated with required space	
    if (!EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pwsBuffer, &dwBufferUsed, &dwPropertyCount)) 
	{
		// Reading was NOT successful, as expected
		if( debug >= DEBUG_L2 ) {
			wprintf(L"[DumpEventInfo]: Required buffer space: %lu\n", dwBufferUsed );
		}

		// Get the error code
		dwError = GetLastError();

		if( debug >= DEBUG_L2 ) {
			wprintf(L"[DumpEventInfo]: Raw error code is: %lu\n", dwError );
		}

		// If call failed due to insufficient buffer (as we should expect)
        if (dwError == ERROR_INSUFFICIENT_BUFFER)
        {
			if( debug >= DEBUG_L2 ) {
				wprintf(L"[DumpEventInfo]: Last error code is insufficient buffer (as expecteted)\n" );
			}

			// Adjust the buffer size to the required amount as indicated by dwBufferUsed		
            dwBufferSize = dwBufferUsed;

			if( debug >= DEBUG_L2 ) {
				wprintf(L"[DumpEventInfo]: Attempting to reallocate buffer size: %lu\n", dwBufferSize );
			}

			// Re-allocate our buffer with the required size
            pwsBuffer = (LPWSTR)malloc(dwBufferSize);

			// If allocaton was successful
            if (pwsBuffer)
            {
				if( debug >= DEBUG_L2 ) {
					wprintf(L"[DumpEventInfo]: Allocation successful. Re-attempting to read event data\n" );
				}

				// Re-attempt to read event (as XML) now that we have appropriate buffer size
                if( EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pwsBuffer, &dwBufferUsed, &dwPropertyCount) ) 
				{
					if( debug >= DEBUG_L2 ) {
						wprintf(L"[DumpEventInfo]: Read successful. Last error code is: %lu\n", dwError );
					}

					// Reading was successful
					dwError = GetLastError();

					if( debug >= DEBUG_L2 ) {
						wprintf( L"[DumpEventInfo]: Raw XML: %s\n", pwsBuffer );
					}

					// Parse the XML string into our XML reader
					doc.parse<0>( pwsBuffer );

					if( debug >= DEBUG_L2 ) {
						wprintf( L"[DumpEventInfo]: XML parsing successful\n" );
					}

					// Retrieve the <Event> node
					rapidxml::xml_node<WCHAR> *nodeEvent = doc.first_node(L"Event");

					// Retrieve the <System> node
					rapidxml::xml_node<WCHAR> *nodeSystem = nodeEvent->first_node(L"System");
					// Children of the <System> node
					// You will recongize these as elements when viewing the event log in your viewer
					rapidxml::xml_node<WCHAR> *nodeEventID = nodeSystem->first_node(L"EventID");
					rapidxml::xml_node<WCHAR> *nodeChannel = nodeSystem->first_node(L"Channel");
					rapidxml::xml_node<WCHAR> *nodeEventRecordID = nodeSystem->first_node(L"EventRecordID");
					rapidxml::xml_node<WCHAR> *nodeProvider = nodeSystem->first_node(L"Provider");
					rapidxml::xml_node<WCHAR> *nodeComputer = nodeSystem->first_node(L"Computer");
					rapidxml::xml_node<WCHAR> *nodeTimeCreated = nodeSystem->first_node(L"TimeCreated");
					rapidxml::xml_node<WCHAR> *nodeTask = nodeSystem->first_node(L"Task");
					rapidxml::xml_node<WCHAR> *nodeLevel = nodeSystem->first_node(L"Level");

					if( debug >= DEBUG_L2 ) {
						wprintf( L"[DumpEventInfo]: Extracting XML elements successful\n" );
					}

					// Recall there are two modes. The default mode will parse the event log XML, and the "last record" mode
					// (called MODE_FETCH_LAST_RECORD) will fetch only the last record and exit afterwards. 
					if( mode == MODE_FETCH_LAST_RECORD ) {
						if( debug >= DEBUG_L2 ) {
							wprintf( L"[DumpEventInfo]: Record ID is '%s'\n", nodeEventRecordID->value() );
						}

						DWORD64 lastRecord = _wcstoui64( nodeEventRecordID->value(), NULL, 10 );

						if( debug >= DEBUG_L2 ) {
							wprintf( L"[DumpEventInfo]: Record ID converted to 64-bit number: %I64d\n", lastRecord );
						}

						return lastRecord;
					}

					// Extract the publisher name from the <Provider> node
					// We will need this to lookup the message string for this publisher
					LPWSTR pwszPublisherName = nodeProvider->first_attribute(L"Name")->value();

					if( debug >= DEBUG_L2 ) {
						wprintf( L"[DumpEventInfo] Publisher is: %s\n", pwszPublisherName );
					}

					// Setup an empty string to read the message string
					LPWSTR pwsMessage = NULL;

					// Get the handle to the provider's metadata that contains the message strings.
					EVT_HANDLE hProviderMetadata = EvtOpenPublisherMetadata(hRemote, pwszPublisherName, NULL, 0, 0);

					// If a provider handle was found
					if( hProviderMetadata != NULL ) 
					{
						if( debug >= DEBUG_L2 ) {
							wprintf( L"[DumpEventInfo] Publisher metadata found. Attempting to get message string\n");
						}

						// Get the message string associated with this event type
						pwsMessage = GetEventMessageDescription(hProviderMetadata, hEvent);

						// If a message was not found, default to an empty string
						if( pwsMessage == NULL ) {
							// Why are we setting to empty string?
							//pwsMessage = L"";

							if( debug >= DEBUG_L2 ) {
								wprintf( L"[DumpEventInfo] Message string not found. Assume empty\n");
							}
						}
					}
					else 
					{
						// Publisher/provider cannot be found. Do not display an error message. It occurs all too often when a 
						// publisher is not found, and skews the JSON results. when it prints itself to the main screen
						// printf("Error: EvtOpenPublisherMetadata for %s failed with %d\n", pwszPublisherName, GetLastError());						

						// Default the publisher to an empty string so we can continue
						pwszPublisherName = L"";

						if( debug >= DEBUG_L2 ) {
							wprintf( L"[DumpEventInfo] Publisher metadata not found. Assume empty\n");
						}
					}

					// We have all the results; print them to the screen
					if( outputFormat == OUTPUT_FORMAT_JSON ) 
					{
						wprintf(L"{\"record_id\":\"%s\",\"event_id\":\"%s\",\"logname\":\"%s\",\"source\":\"%s\",\"computer\":\"%s\",\"time_created\":\"%s\",\"task\":\"%s\",\"level\":\"%s\"", 
							nodeEventRecordID->value(), 
							nodeEventID->value(), 
							nodeChannel->value(), 
							nodeProvider->first_attribute(L"Name")->value(), 
							nodeComputer->value(), 
							nodeTimeCreated->first_attribute(L"SystemTime")->value(),
							nodeTask->value(),
							nodeLevel->value());
						
						// If a message string was found
						if( pwsMessage != NULL ) 
						{
							wprintf(L",\"message\":\"%s\"}", pwsMessage);

							if( debug >= DEBUG_L2 ) {
								wprintf( L"[DumpEventInfo] Attempting to free pwsMessage\n");
							}

							free(pwsMessage);

							if( debug >= DEBUG_L2 ) {
								wprintf( L"[DumpEventInfo] pwsMessage successfully freed\n");
							}
						} 
						else 
						{
							wprintf(L",\"message\":\"\"}");

							if( debug >= DEBUG_L2 ) {
								wprintf( L"[DumpEventInfo] No pwsMessage found to free\n");
							}
						}
					} 
					else 
					{
						// Note: A new line is not printed yet (see next steps)
						wprintf(L"%s||%s||%s||%s||%s||%s||%s||%s||", 
							nodeEventRecordID->value(), 
							nodeEventID->value(), 
							nodeChannel->value(), 
							nodeProvider->first_attribute(L"Name")->value(), 
							nodeComputer->value(), 
							nodeTimeCreated->first_attribute(L"SystemTime")->value(),
							nodeTask->value(),
							nodeLevel->value());

						// If a message string was found
						if( pwsMessage != NULL ) 
						{
							wprintf(L"%s\n", pwsMessage);
							free(pwsMessage);
						} 
						else 
						{
							wprintf(L"(no message provided)\n");
						}
					}
				} 
				else
				{
					// Reading was NOT successful

					// This time we were not expecting it to fail. Get the error code
					dwError = GetLastError();

					// Print error results to the screen
					fwprintf(stderr, L"[DumpEventInfo] Failed to render results with: %d\n", GetLastError());

					// Free up our allocation
					free(pwsBuffer);
				}				
            }
            else
            {
				// Allocation was unsuccessful
                fwprintf(stderr, L"[DumpEventInfo] malloc failed\n");
                dwError = ERROR_OUTOFMEMORY;
            }
        }
	}

	if( debug >= DEBUG_L2 ) {
		wprintf( L"[DumpEventInfo]: Data dump completed\n" );
	}

    return dwError;
}
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;
}
/* Update the log position of a bookmark */
int update_bookmark(EVT_HANDLE evt, os_channel *channel)
{
    DWORD size = 0;
    DWORD count = 0;
    wchar_t *buffer = NULL;
    int result = 0;
    int status = 0;
    int clean_tmp = 0;
    EVT_HANDLE bookmark = NULL;
    FILE *fp = NULL;
    char tmp_file[OS_MAXSTR];

    /* Create temporary bookmark file name */
    snprintf(tmp_file,
             sizeof(tmp_file),
             "%s/%s-XXXXXX",
             TMP_DIR,
             channel->bookmark_name);

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

    if (!EvtUpdateBookmark(bookmark, evt)) {
        log2file(
            "%s: ERROR: Could not EvtUpdateBookmark() bookmark (%s) for (%s) which returned (%lu)",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            GetLastError());
        goto cleanup;
    }

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

    if ((buffer = calloc(size, sizeof(char))) == NULL) {
        log2file(
            "%s: ERROR: Could not calloc() memory to save bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            channel->bookmark_filename,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    if (!EvtRender(NULL,
                   bookmark,
                   EvtRenderBookmark,
                   size,
                   buffer,
                   &size,
                   &count)) {
        log2file(
            "%s: ERROR: Could not EvtRender() bookmark (%s) for (%s) which returned (%lu)",
            ARGV0, channel->bookmark_filename, channel->evt_log,
            GetLastError());
        goto cleanup;
    }

    if (mkstemp_ex(tmp_file)) {
        log2file(
            "%s: ERROR: Could not mkstemp_ex() temporary bookmark (%s) for (%s)",
            ARGV0,
            tmp_file,
            channel->evt_log);
        goto cleanup;
    }

    if ((fp = fopen(tmp_file, "w")) == NULL) {
        log2file(
            "%s: ERROR: Could not fopen() temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            tmp_file,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    /* Help to determine whether or not temporary file needs to be removed when
     * function cleans up after itself
     */
    clean_tmp = 1;

    if ((fwrite(buffer, 1, size, fp)) < size) {
        log2file(
            "%s: ERROR: Could not fwrite() to temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
            ARGV0,
            tmp_file,
            channel->evt_log,
            errno,
            strerror(errno));
        goto cleanup;
    }

    fclose(fp);

    if (rename_ex(tmp_file, channel->bookmark_filename)) {
        log2file(
            "%s: ERROR: Could not rename_ex() temporary bookmark (%s) to (%s) for (%s)",
            ARGV0,
            tmp_file,
            channel->bookmark_filename,
            channel->evt_log);
        goto cleanup;
    }

    /* Success */
    status = 1;

cleanup:
    free(buffer);

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

    if (fp) {
        fclose(fp);
    }

    if (status == 0 && clean_tmp == 1 && unlink(tmp_file)) {
        log2file(DELETE_ERROR,
                 ARGV0,
                 tmp_file,
                 errno,
                 strerror(errno));
    }

    return (status);
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
/* Update the log position of a bookmark */
int update_bookmark(EVT_HANDLE evt, os_channel *channel)
{
	DWORD size = 0;
	DWORD count = 0;
	wchar_t *buffer = NULL;
	int result = 0;
	EVT_HANDLE bookmark = NULL;
	FILE *fp = NULL;
	char tmp_file[OS_MAXSTR];

	/* Create bookmark temporary file name */
	snprintf(
		tmp_file,
		sizeof(tmp_file),
		"%s/%s-XXXXXX",
		TMP_DIR,
		channel->evt_log
	);

	replace_slash(tmp_file);

	if ((bookmark = EvtCreateBookmark(NULL)) == NULL)
	{
		log2file(
			"%s: ERROR: Could not EvtCreateBookmark() bookmark (%s) for (%s) which returned (%lu)",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			GetLastError()
		);

		return(0);
	}

	if (!EvtUpdateBookmark(bookmark, evt))
	{
		log2file(
			"%s: ERROR: Could not EvtUpdateBookmark() bookmark (%s) for (%s) which returned (%lu)",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			GetLastError()
		);

		return(0);
	}

	/* Make initial call to determine buffer size */
	result = EvtRender(NULL, bookmark, EvtRenderBookmark, 0, NULL, &size, &count);

	if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
	{
		log2file(
			"%s: ERROR: Could not EvtRender() to get buffer size to update bookmark (%s) for (%s) which returned (%lu)",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			GetLastError()
		);

		return(0);
	}

	if ((buffer = calloc(size, 1)) == NULL)
	{
		log2file(
			"%s: ERROR: Could not calloc() memory to save bookmark (%s) for (%s) which returned [(%d)-(%s)]",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			errno,
			strerror(errno)
		);

		return(0);
	}

	if (!EvtRender(NULL, bookmark, EvtRenderBookmark, size, buffer, &size, &count))
	{
		log2file(
			"%s: ERROR: Could not EvtRender() bookmark (%s) for (%s) which returned (%lu)",
			ARGV0,
			channel->bookmark_filename,
			channel->evt_log,
			GetLastError()
		);

		return(0);
	}

	if (mkstemp_ex(tmp_file))
	{
		log2file(
			"%s: ERROR: Could not mkstemp_ex() temporary bookmark (%s) for (%s)",
			ARGV0,
			tmp_file,
			channel->evt_log
		);

		return(0);
	}

	if ((fp = fopen(tmp_file, "w")) == NULL)
	{
		log2file(
			"%s: ERROR: Could not fopen() temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
			ARGV0,
			tmp_file,
			channel->evt_log,
			errno,
			strerror(errno)
		);

		goto error;
	}

	if ((fwrite(buffer, 1, size, fp)) < size)
	{
		log2file(
			"%s: ERROR: Could not fwrite() to temporary bookmark (%s) for (%s) which returned [(%d)-(%s)]",
			ARGV0,
			tmp_file,
			channel->evt_log,
			errno,
			strerror(errno)
		);

		goto error;
	}

	fclose(fp);

	if (rename_ex(tmp_file, channel->bookmark_filename))
	{
		log2file(
			"%s: ERROR: Could not rename_ex() temporary bookmark (%s) to (%s) for (%s)",
			ARGV0,
			tmp_file,
			channel->bookmark_filename,
			channel->evt_log
		);

		goto error;
	}

	/* success */
	return(1);

error:
	if (fp)
		fclose(fp);

	if (unlink(tmp_file))
	{
		log2file(DELETE_ERROR, ARGV0, tmp_file, errno, strerror(errno));
	}

	return(0);
}
Exemplo n.º 13
0
/**
* @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;
}