static int svc_install_event_source(const char *path) { HKEY hKey; DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; TCHAR execName[MAX_PATH]; TCHAR regkey[256], *wevent_source; svc_get_fullpath(path, execName, MAX_PATH); wevent_source = zbx_utf8_to_unicode(ZABBIX_EVENT_SOURCE); zbx_wsnprintf(regkey, sizeof(regkey)/sizeof(TCHAR), EVENTLOG_REG_PATH TEXT("System\\%s"), wevent_source); zbx_free(wevent_source); if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_LOCAL_MACHINE, regkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL)) { zbx_error("unable to create registry key: %s", strerror_from_system(GetLastError())); return FAIL; } RegSetValueEx(hKey, TEXT("TypesSupported"), 0, REG_DWORD, (BYTE *)&dwTypes, sizeof(DWORD)); RegSetValueEx(hKey, TEXT("EventMessageFile"), 0, REG_EXPAND_SZ, (BYTE *)execName, (DWORD)(zbx_strlen(execName) + 1) * sizeof(TCHAR)); RegCloseKey(hKey); zbx_error("event source [%s] installed successfully", ZABBIX_EVENT_SOURCE); return SUCCEED; }
/* get Nth error from event log. 1 is the first. */ static int zbx_get_eventlog_message(LPCTSTR wsource, HANDLE eventlog_handle, long which, char **out_source, char **out_message, unsigned short *out_severity, unsigned long *out_timestamp, unsigned long *out_eventid) { const char *__function_name = "zbx_get_eventlog_message"; int buffer_size = 512; EVENTLOGRECORD *pELR = NULL; DWORD dwRead, dwNeeded, dwErr; TCHAR stat_buf[MAX_PATH], MsgDll[MAX_PATH]; HKEY hk = NULL; LPTSTR pFile = NULL, pNextFile = NULL; DWORD szData, Type; HINSTANCE hLib = NULL; /* handle to the messagetable DLL */ LPTSTR pCh, aInsertStrs[MAX_INSERT_STRS]; /* array of pointers to insert */ LPTSTR msgBuf = NULL; /* hold text of the error message */ char *buf = NULL; long i, err = 0; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() which:%ld", __function_name, which); *out_source = NULL; *out_message = NULL; *out_severity = 0; *out_timestamp = 0; *out_eventid = 0; memset(aInsertStrs, 0, sizeof(aInsertStrs)); pELR = (EVENTLOGRECORD *)zbx_malloc((void *)pELR, buffer_size); retry: if (0 == ReadEventLog(eventlog_handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, which, pELR, buffer_size, &dwRead, &dwNeeded)) { dwErr = GetLastError(); if (dwErr == ERROR_INSUFFICIENT_BUFFER) { buffer_size = dwNeeded; pELR = (EVENTLOGRECORD *)zbx_realloc((void *)pELR, buffer_size); goto retry; } else { zabbix_log(LOG_LEVEL_DEBUG, "%s(): %s", __function_name, strerror_from_system(dwErr)); goto out; } } *out_severity = pELR->EventType; /* return event type */ *out_timestamp = pELR->TimeGenerated; /* return timestamp */ *out_eventid = pELR->EventID & 0xffff; *out_source = zbx_unicode_to_utf8((LPTSTR)(pELR + 1)); /* copy source name */ err = FAIL; /* prepare the array of insert strings for FormatMessage - the insert strings are in the log entry. */ for (i = 0, pCh = (LPTSTR)((LPBYTE)pELR + pELR->StringOffset); i < pELR->NumStrings && i < MAX_INSERT_STRS; i++, pCh += zbx_strlen(pCh) + 1) /* point to next string */ { aInsertStrs[i] = pCh; } /* Get path to message dll */ zbx_wsnprintf(stat_buf, MAX_PATH, EVENTLOG_REG_PATH TEXT("%s\\%s"), wsource, (LPTSTR)(pELR + 1)); if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, stat_buf, 0, KEY_READ, &hk)) { if (ERROR_SUCCESS == RegQueryValueEx(hk, TEXT("EventMessageFile"), NULL, &Type, NULL, &szData)) { buf = zbx_malloc(buf, szData); if (ERROR_SUCCESS == RegQueryValueEx(hk, TEXT("EventMessageFile"), NULL, &Type, (LPBYTE)buf, &szData)) pFile = (LPTSTR)buf; } RegCloseKey(hk); } err = FAIL; while (NULL != pFile && FAIL == err) { if (NULL != (pNextFile = zbx_strchr(pFile, ';'))) { *pNextFile = '\0'; pNextFile++; } if (ExpandEnvironmentStrings(pFile, MsgDll, MAX_PATH)) { if (NULL != (hLib = LoadLibraryEx(MsgDll, NULL, LOAD_LIBRARY_AS_DATAFILE))) { /* Format the message from the message DLL with the insert strings */ if (0 != FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, /* do not generate new line breaks */ hLib, /* the messagetable DLL handle */ pELR->EventID, /* message ID */ MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_US), /* language ID */ (LPTSTR)&msgBuf, /* address of pointer to buffer for message */ 0, (va_list *)aInsertStrs)) /* array of insert strings for the message */ { *out_message = zbx_unicode_to_utf8(msgBuf); zbx_rtrim(*out_message, "\r\n "); /* Free the buffer that FormatMessage allocated for us. */ LocalFree((HLOCAL)msgBuf); err = SUCCEED; } FreeLibrary(hLib); } } pFile = pNextFile; } zbx_free(buf); if (SUCCEED != err) { *out_message = zbx_strdcatf(*out_message, "The description for Event ID (%lu) in Source (%s) cannot be found." " The local computer may not have the necessary registry information or message DLL files to" " display messages from a remote computer.", *out_eventid, NULL == *out_source ? "" : *out_source); if (pELR->NumStrings) *out_message = zbx_strdcatf(*out_message, " The following information is part of the event: "); for (i = 0; i < pELR->NumStrings && i < MAX_INSERT_STRS; i++) { if (i > 0) *out_message = zbx_strdcatf(*out_message, "; "); if (aInsertStrs[i]) { buf = zbx_unicode_to_utf8(aInsertStrs[i]); *out_message = zbx_strdcatf(*out_message, "%s", buf); zbx_free(buf); } } } ret = SUCCEED; out: zbx_free(pELR); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/* get Nth error from event log. 1 is the first. */ static int zbx_get_eventlog_message(LPCTSTR wsource, HANDLE eventlog_handle, long which, char **out_source, char **out_message, unsigned short *out_severity, unsigned long *out_timestamp, unsigned long *out_eventid) { const char *__function_name = "zbx_get_eventlog_message"; int buffer_size = 512; EVENTLOGRECORD *pELR = NULL; DWORD dwRead, dwNeeded, dwErr; LPTSTR pEventMessageFile = NULL, pParamMessageFile = NULL, pFile = NULL, pNextFile = NULL, pCh, *pInsertStrings = NULL; HINSTANCE hLib = NULL, hParamLib = NULL; long i, err = 0; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() which:%ld", __function_name, which); *out_source = NULL; *out_message = NULL; *out_severity = 0; *out_timestamp = 0; *out_eventid = 0; pELR = (EVENTLOGRECORD *)zbx_malloc((void *)pELR, buffer_size); while (0 == ReadEventLog(eventlog_handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, which, pELR, buffer_size, &dwRead, &dwNeeded)) { if (ERROR_INSUFFICIENT_BUFFER != (dwErr = GetLastError())) { zabbix_log(LOG_LEVEL_DEBUG, "%s(): %s", __function_name, strerror_from_system(dwErr)); goto out; } buffer_size = dwNeeded; pELR = (EVENTLOGRECORD *)zbx_realloc((void *)pELR, buffer_size); } *out_severity = pELR->EventType; /* return event type */ *out_timestamp = pELR->TimeGenerated; /* return timestamp */ *out_eventid = pELR->EventID & 0xffff; *out_source = zbx_unicode_to_utf8((LPTSTR)(pELR + 1)); /* copy source name */ /* get message file names */ zbx_get_message_files(wsource, (LPTSTR)(pELR + 1), &pEventMessageFile, &pParamMessageFile); /* prepare insert string array */ if (0 < pELR->NumStrings) { pInsertStrings = zbx_malloc(NULL, sizeof(LPWSTR) * pELR->NumStrings); pCh = (LPWSTR)((LPBYTE)pELR + pELR->StringOffset); for (i = 0; i < pELR->NumStrings; i++) { pInsertStrings[i] = pCh; pCh += zbx_strlen(pCh) + 1; } } err = FAIL; for (pFile = pEventMessageFile; NULL != pFile && err != SUCCEED; pFile = pNextFile) { if (NULL != (pNextFile = zbx_strchr(pFile, ';'))) { *pNextFile = '\0'; pNextFile++; } if (NULL != (hLib = zbx_load_message_file(pFile))) { if (NULL != (*out_message = zbx_format_message(hLib, pELR->EventID, pInsertStrings))) { err = SUCCEED; if (NULL != (hParamLib = zbx_load_message_file(pParamMessageFile))) { zbx_translate_message_params(out_message, hParamLib); FreeLibrary(hParamLib); } } FreeLibrary(hLib); } } zbx_free(pInsertStrings); zbx_free(pEventMessageFile); zbx_free(pParamMessageFile); if (SUCCEED != err) { *out_message = zbx_strdcatf(*out_message, "The description for Event ID:%lu in Source:'%s'" " cannot be found. The local computer may not have the necessary registry" " information or message DLL files to display messages from a remote computer.", *out_eventid, NULL == *out_source ? "" : *out_source); if (0 < pELR->NumStrings) { char *buf; *out_message = zbx_strdcat(*out_message, " The following information is part of the event: "); for (i = 0, pCh = (LPWSTR)((LPBYTE)pELR + pELR->StringOffset); i < pELR->NumStrings; i++, pCh += zbx_strlen(pCh) + 1) { if (0 < i) *out_message = zbx_strdcat(*out_message, "; "); buf = zbx_unicode_to_utf8(pCh); *out_message = zbx_strdcat(*out_message, buf); zbx_free(buf); } } } ret = SUCCEED; out: zbx_free(pELR); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }