/* Get specific values from an event */ PEVT_VARIANT GetEventInfo(EVT_HANDLE hEvent) { EVT_HANDLE hContext = NULL; PEVT_VARIANT pRenderedEvents = NULL; LPWSTR ppValues[] = {L"Event/System/Provider/@Name", L"Event/System/TimeCreated/@SystemTime", L"Event/System/EventID", L"Event/System/Level", L"Event/System/Keywords"}; DWORD count = COUNT_OF(ppValues); DWORD dwReturned = 0; DWORD dwBufferSize = (256*sizeof(LPWSTR)*count); DWORD dwValuesCount = 0; DWORD status = 0; /* Create the context to use for EvtRender */ hContext = EvtCreateRenderContext(count, (LPCWSTR*)ppValues, EvtRenderContextValues); if (NULL == hContext) { Log(LOG_ERROR|LOG_SYS, "EvtCreateRenderContext failed"); goto cleanup; } pRenderedEvents = (PEVT_VARIANT)malloc(dwBufferSize); /* Use EvtRender to capture the Publisher name from the Event */ /* Log Errors to the event log if things go wrong */ if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedEvents, &dwReturned, &dwValuesCount)) { if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { dwBufferSize = dwReturned; realloc(pRenderedEvents, dwBufferSize); if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedEvents, &dwReturned, &dwValuesCount)) { if (LogInteractive) Log(LOG_ERROR|LOG_SYS, "Error Rendering Event"); status = ERR_FAIL; } } else { status = ERR_FAIL; if (LogInteractive) Log(LOG_ERROR|LOG_SYS, "Error Rendering Event"); } } cleanup: if (hContext) EvtClose(hContext); if (status == ERR_FAIL) return NULL; else return pRenderedEvents; }
void 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); } }
/**** * 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); }
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; }
/* 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; }
/* 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; }
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; }
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; }
/* 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; }
/* 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); }
/** * @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; }