/* 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; }
/* 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; }
/* 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; }