/* expand the string message from a specific event handler */ static char *expand_message6(const wchar_t *pname, EVT_HANDLE event) { const char *__function_name = "expand_message6"; wchar_t *pmessage = NULL; EVT_HANDLE provider = NULL; DWORD require = 0; char *out_message = NULL; char *tmp_pname = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (NULL == (provider = EvtOpenPublisherMetadata(NULL, pname, NULL, 0, 0))) { tmp_pname = zbx_unicode_to_utf8(pname); zabbix_log(LOG_LEVEL_DEBUG, "provider '%s' could not be opened: %s", strerror_from_system(GetLastError()), tmp_pname); zbx_free(tmp_pname); goto out; } if (TRUE != EvtFormatMessage(provider, event, 0, 0, NULL, EvtFormatMessageEvent, 0, NULL, &require)) { if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { DWORD error = ERROR_SUCCESS; pmessage = zbx_malloc(pmessage, sizeof(WCHAR) * require); if (TRUE != EvtFormatMessage(provider, event, 0, 0, NULL, EvtFormatMessageEvent, require, pmessage, &require)) { error = GetLastError(); } if (ERROR_SUCCESS == error || ERROR_EVT_UNRESOLVED_VALUE_INSERT == error || ERROR_EVT_UNRESOLVED_PARAMETER_INSERT == error || ERROR_EVT_MAX_INSERTS_REACHED == error) { out_message = zbx_unicode_to_utf8(pmessage); } else { zabbix_log(LOG_LEVEL_DEBUG, "%s() cannot format message: %s", __function_name, strerror_from_system(error)); goto out; } } } out: if (NULL != provider) EvtClose(provider); zbx_free(pmessage); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, out_message); /* should be freed */ return out_message; }
/* expand the string message from a specific event handler */ static char *expand_message6(const wchar_t *pname, EVT_HANDLE event) { const char *__function_name = "expand_message6"; wchar_t *pmessage = NULL; EVT_HANDLE provider = NULL; DWORD require = 0; char *out_message = NULL; char *tmp_pname = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (NULL == (provider = EvtOpenPublisherMetadata(NULL, pname, NULL, 0, 0))) { tmp_pname = zbx_unicode_to_utf8(pname); zabbix_log(LOG_LEVEL_DEBUG, "provider '%s' could not be opened: %s", strerror_from_system(GetLastError()), tmp_pname); zbx_free(tmp_pname); goto finish; } if (TRUE != EvtFormatMessage(provider, event, 0, 0, NULL, EvtFormatMessageEvent, 0, NULL, &require) ) { if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { pmessage = zbx_malloc(pmessage, sizeof(WCHAR) * require); if (TRUE != EvtFormatMessage(provider, event, 0, 0, NULL, EvtFormatMessageEvent, require, pmessage, &require)) { zabbix_log(LOG_LEVEL_DEBUG, "formatting message failed: %s", strerror_from_system(GetLastError())); goto finish; } out_message = zbx_unicode_to_utf8(pmessage); } } finish: if (NULL != provider) EvtClose(provider); zbx_free(pmessage); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, out_message); /* should be freed*/ return out_message; }
/** * @brief Gets the specified message string from the event. If the event does not * contain the specified message, the function returns empty string. * @param metadata A handle to the provider's metadata that the EvtOpenPublisherMetadata function returns. * The handle acts as a formatting context for the event or message identifier * @param eventHandle A handle to an event. * * @return returns message string from the event. */ std::string EventLogReader::GetMessageString(EVT_HANDLE metadata, EVT_HANDLE eventHandle) { DWORD bufferSize = 0; DWORD bufferUsed = 0; DWORD status = 0; std::vector<WCHAR> buffer; if (!EvtFormatMessage(metadata, eventHandle, 0, 0, nullptr, EvtFormatMessageEvent, bufferSize, nullptr, &bufferUsed)) { status = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == status) { bufferSize = bufferUsed; buffer.resize(bufferUsed); EvtFormatMessage(metadata, eventHandle, 0, 0, nullptr, EvtFormatMessageEvent, bufferSize, &buffer[0], &bufferUsed); } } std::wstring temp(buffer.begin(), buffer.end()); return base::wstring_to_string(temp); }
/* Gets the specified message string from the event. If the event does not contain the specified message, the function returns NULL. */ LPWSTR GetMessageString(EVT_HANDLE hMetadata, EVT_HANDLE hEvent) { LPWSTR pBuffer = NULL; DWORD dwBufferSize = 0; DWORD dwBufferUsed = 0; DWORD status = 0; /* Get the message string from the provider */ EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, EvtFormatMessageEvent, dwBufferSize, pBuffer, &dwBufferUsed); /* Ensure the call succeeded */ /* If buffer was not large enough realloc it */ status = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == status) { dwBufferSize = dwBufferUsed; pBuffer = (LPWSTR)malloc(dwBufferSize * sizeof(WCHAR)); /* Once we have realloc'd the buffer try to grab the message string again */ if (pBuffer) EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, EvtFormatMessageEvent, dwBufferSize, pBuffer, &dwBufferUsed); else { Log(LOG_ERROR|LOG_SYS, "EvtFormatMessage: malloc failed"); return NULL; } } else if (ERROR_EVT_MESSAGE_NOT_FOUND == status || ERROR_EVT_MESSAGE_ID_NOT_FOUND == status) { if (pBuffer) free(pBuffer); return NULL; } else { Log(LOG_ERROR|LOG_SYS, "EvtFormatMessage failed: could not get message string"); if (pBuffer) free(pBuffer); return NULL; } /* Success */ return pBuffer; }
/**** * GetEventMessageDescription * * DESC: * Gets the specified message string from the event. If the event does not * contain the specified message, the function returns NULL. * * ARGS: * hMetaData - Handle to open metadata for an event * hEvent - Handle to open event * * RETURNS: * If a message has been found, returns a string containing the message. * Otherwise if no message has been found, returns NULL * * Note: Caller is responsible for freeing the memory used by the string */ LPWSTR GetEventMessageDescription(EVT_HANDLE hMetadata, EVT_HANDLE hEvent) { // The raw message string LPWSTR pBuffer = NULL; // The processed message string (make it safe for JSON encoding) LPWSTR done = NULL; // Size of the message string DWORD dwBufferSize = 0; // Number of bytes used for message string DWORD dwBufferUsed = 0; // Type of message string to retrieve from event log EVT_FORMAT_MESSAGE_FLAGS flags = EvtFormatMessageEvent; // Attempt to read provider-specific message from this event if (!EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, flags, dwBufferSize, pBuffer, &dwBufferUsed)) { // An error occurred. Retrieve this error DWORD dwError = GetLastError(); // If the error was due to our destination buffer being too small if (dwError == ERROR_INSUFFICIENT_BUFFER) { if ((flags == EvtFormatMessageKeyword)) pBuffer[dwBufferSize-1] = L'\0'; else dwBufferSize = dwBufferUsed; // Re-allocate our buffer with the required size pBuffer = (LPWSTR)malloc(dwBufferSize * sizeof(WCHAR)); // If the re-allocation was successful if (pBuffer) { // Re-attempt to retrieve event message EvtFormatMessage(hMetadata, hEvent, 0, 0, NULL, flags, dwBufferSize, pBuffer, &dwBufferUsed); if ((flags == EvtFormatMessageKeyword)) pBuffer[dwBufferUsed-1] = L'\0'; // Replace new lines with "\n" characters for client to handle // This makes the string JSON friendly done = repl_wcs(pBuffer, L"\\", L"\\\\"); } else { // Allocation failed fwprintf(stderr, L"[Error][GetEventMessageDescription]: malloc failed\n"); } } else if (dwError == ERROR_EVT_MESSAGE_NOT_FOUND) { // Message was not found. Will return NULL } else if (dwError == ERROR_EVT_MESSAGE_ID_NOT_FOUND) { // Message ID not found. Will return NULL } else { // Unexpected error. Output to screen fwprintf(stderr, L"[Error][GetEventMessageDescription]: EvtFormatMessage failed with %u\n", dwError); } } // Return the JSON-friendly string return done; }
DWORD GetEventRawDescriptions ( __in PCWSTR ProviderName, __in LCID Locale ) /*++ Routine Description: This function gets the raw event description strings. Parameters: ProviderName - Supplies the provider name. Locale - Supplies the LCID. Return Value: Win32 error code indicating the status of the function execution. --*/ { PWSTR Description; ULONG BufferLength; ULONG BufferLengthNeeded; ULONG BufferUsed; EVT_VARIANT EventId; EVT_VARIANT EventMessageId; EVT_HANDLE EventMeta; EVT_HANDLE EventMetaEnum; EVT_HANDLE ProviderMetadata; ULONG Status; // // Open the provider meta data. // ProviderMetadata = EvtOpenPublisherMetadata(NULL, ProviderName, NULL, Locale, 0); if (ProviderMetadata == NULL) { return GetLastError(); } // // Open the Event meta data associated with the provider. // EventMetaEnum = EvtOpenEventMetadataEnum(ProviderMetadata, 0); if (EventMetaEnum == NULL) { Status = GetLastError(); EvtClose(ProviderMetadata); return Status; } Description = NULL; BufferLength = 0; BufferLengthNeeded = 0; while ((EventMeta = EvtNextEventMetadata(EventMetaEnum, 0)) != NULL) { // // Get the event & message IDs. // if ((EvtGetEventMetadataProperty(EventMeta, EventMetadataEventMessageID, 0, sizeof(EVT_VARIANT), &EventMessageId, &BufferUsed) == FALSE) || (EvtGetEventMetadataProperty(EventMeta, EventMetadataEventID, 0, sizeof(EVT_VARIANT), &EventId, &BufferUsed) == FALSE)) { EvtClose(EventMeta); continue; } // // Get the description, reallocating the buffer if needed. // do { if (BufferLengthNeeded > BufferLength) { free(Description); BufferLength = BufferLengthNeeded; Description = (PWSTR)malloc(BufferLength * sizeof(WCHAR)); if (Description == NULL) { Status = ERROR_OUTOFMEMORY; BufferLength = 0; break; } } if (EvtFormatMessage(ProviderMetadata, NULL, EventMessageId.UInt32Val, 0, NULL, EvtFormatMessageId, BufferLength, Description, &BufferLengthNeeded) != FALSE) { Status = ERROR_SUCCESS; } else { Status = GetLastError(); } } while (Status == ERROR_INSUFFICIENT_BUFFER); // // Display either the event message or an error message. // switch (Status) { case ERROR_SUCCESS: case ERROR_EVT_UNRESOLVED_VALUE_INSERT: case ERROR_EVT_UNRESOLVED_PARAMETER_INSERT: case ERROR_EVT_MAX_INSERTS_REACHED: wprintf(L"Event %u raw description is: %s\n", EventId.UInt32Val, Description); break; default: wprintf(L"Get raw event description failed with error code %u\n", Status); } // // Close this event's metadata and go to the next one. // EvtClose(EventMeta); } Status = GetLastError(); if (Status == ERROR_NO_MORE_ITEMS) { Status = ERROR_SUCCESS; } free(Description); EvtClose(EventMetaEnum); EvtClose(ProviderMetadata); return Status; }
char *get_message(EVT_HANDLE evt, LPCWSTR provider_name, DWORD flags) { char *message = NULL; EVT_HANDLE publisher = NULL; DWORD size = 0; wchar_t *buffer = NULL; int result = 0; publisher = EvtOpenPublisherMetadata(NULL, provider_name, NULL, 0, 0); if (publisher == NULL) { log2file( "%s: ERROR: Could not EvtOpenPublisherMetadata() with flags (%lu) which returned (%lu)", ARGV0, flags, GetLastError()); goto cleanup; } /* Make initial call to determine buffer size */ result = EvtFormatMessage(publisher, evt, 0, 0, NULL, flags, 0, NULL, &size); if (result != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { log2file( "%s: ERROR: Could not EvtFormatMessage() to determine buffer size with flags (%lu) which returned (%lu)", ARGV0, flags, GetLastError()); goto cleanup; } if ((buffer = calloc(size, sizeof(wchar_t))) == NULL) { log2file( "%s: ERROR: Could not calloc() memory which returned [(%d)-(%s)]", ARGV0, errno, strerror(errno)); goto cleanup; } result = EvtFormatMessage(publisher, evt, 0, 0, NULL, flags, size, buffer, &size); if (result == FALSE) { log2file( "%s: ERROR: Could not EvtFormatMessage() with flags (%lu) which returned (%lu)", ARGV0, flags, GetLastError()); goto cleanup; } message = convert_windows_string(buffer); cleanup: free(buffer); if (publisher != NULL) { EvtClose(publisher); } return (message); }
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; }