/****************************************************************************** * * * Function: zbx_get_message_files * * * * Purpose: gets event message and parameter translation files from registry * * * * Parameters: szLogName - [IN] the log name * * szSourceName - [IN] the log source name * * pEventMessageFile - [OUT] the event message file * * pParamMessageFile - [OUT] the parameter message file * * * ******************************************************************************/ static void zbx_get_message_files(LPCTSTR szLogName, LPCTSTR szSourceName, LPTSTR *pEventMessageFile, LPTSTR *pParamMessageFile) { TCHAR buf[MAX_PATH]; HKEY hKey = NULL; DWORD szData; /* Get path to message dll */ zbx_wsnprintf(buf, MAX_PATH, EVENTLOG_REG_PATH TEXT("%s\\%s"), szLogName, szSourceName); if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, buf, 0, KEY_READ, &hKey)) return; if (ERROR_SUCCESS == RegQueryValueEx(hKey, TEXT("EventMessageFile"), NULL, NULL, NULL, &szData)) { *pEventMessageFile = zbx_malloc(*pEventMessageFile, szData); if (ERROR_SUCCESS != RegQueryValueEx(hKey, TEXT("EventMessageFile"), NULL, NULL, (LPBYTE)*pEventMessageFile, &szData)) { zbx_free(*pEventMessageFile); } } if (ERROR_SUCCESS == RegQueryValueEx(hKey, TEXT("ParameterMessageFile"), NULL, NULL, NULL, &szData)) { *pParamMessageFile = zbx_malloc(*pParamMessageFile, szData); if (ERROR_SUCCESS != RegQueryValueEx(hKey, TEXT("ParameterMessageFile"), NULL, NULL, (LPBYTE)*pParamMessageFile, &szData)) { zbx_free(*pParamMessageFile); } } RegCloseKey(hKey); }
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; }
static void svc_get_command_line(const char *path, int multiple_agents, LPTSTR cmdLine, size_t max_cmdLine) { TCHAR path1[MAX_PATH], path2[MAX_PATH]; svc_get_fullpath(path, path2, MAX_PATH); if (NULL == zbx_strstr(path2, TEXT(".exe"))) zbx_wsnprintf(path1, MAX_PATH, TEXT("%s.exe"), path2); else zbx_wsnprintf(path1, MAX_PATH, path2); if (NULL != CONFIG_FILE) { svc_get_fullpath(CONFIG_FILE, path2, MAX_PATH); zbx_wsnprintf(cmdLine, max_cmdLine, TEXT("\"%s\" %s--config \"%s\""), path1, (0 == multiple_agents) ? TEXT("") : TEXT("--multiple-agents "), path2); } else zbx_wsnprintf(cmdLine, max_cmdLine, TEXT("\"%s\""), path1); }
/* open event logger and return number of records */ static int zbx_open_eventlog(LPCTSTR wsource, HANDLE *eventlog_handle, long *pNumRecords, long *pLatestRecord) { const char *__function_name = "zbx_open_eventlog"; TCHAR reg_path[MAX_PATH]; HKEY hk = NULL; int ret = FAIL; assert(eventlog_handle); assert(pNumRecords); assert(pLatestRecord); zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); *eventlog_handle = NULL; *pNumRecords = 0; *pLatestRecord = 0; /* Get path to eventlog */ zbx_wsnprintf(reg_path, MAX_PATH, EVENTLOG_REG_PATH TEXT("%s"), wsource); if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &hk)) goto out; RegCloseKey(hk); if (NULL == (*eventlog_handle = OpenEventLog(NULL, wsource))) /* open log file */ goto out; if (0 == GetNumberOfEventLogRecords(*eventlog_handle, (unsigned long*)pNumRecords)) /* get number of records */ goto out; if (0 == GetOldestEventLogRecord(*eventlog_handle, (unsigned long*)pLatestRecord)) goto out; zabbix_log(LOG_LEVEL_DEBUG, "%s() pNumRecords:%ld pLatestRecord:%ld", __function_name, *pNumRecords, *pLatestRecord); ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
static int svc_RemoveEventSource() { TCHAR regkey[256]; LPTSTR wevent_source; int ret = FAIL; 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 == RegDeleteKey(HKEY_LOCAL_MACHINE, regkey)) { zbx_error("event source [%s] uninstalled successfully", ZABBIX_EVENT_SOURCE); ret = SUCCEED; } else { zbx_error("unable to uninstall event source [%s]: %s", ZABBIX_EVENT_SOURCE, strerror_from_system(GetLastError())); } return SUCCEED; }
int init_cpu_collector(ZBX_CPUS_STAT_DATA *pcpus) { const char *__function_name = "init_cpu_collector"; int cpu_num, ret = FAIL; #ifdef _WINDOWS TCHAR cpu[8]; char counterPath[PDH_MAX_COUNTER_PATH]; PDH_COUNTER_PATH_ELEMENTS cpe; #else #ifdef HAVE_KSTAT_H kstat_ctl_t *kc; kstat_t *k, *kd; #endif #endif zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); #ifdef _WINDOWS cpe.szMachineName = NULL; cpe.szObjectName = get_counter_name(PCI_PROCESSOR); cpe.szInstanceName = cpu; cpe.szParentInstance = NULL; cpe.dwInstanceIndex = -1; cpe.szCounterName = get_counter_name(PCI_PROCESSOR_TIME); for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) { if (0 == cpu_num) zbx_wsnprintf(cpu, sizeof(cpu) / sizeof(TCHAR), TEXT("_Total")); else _itow_s(cpu_num - 1, cpu, sizeof(cpu) / sizeof(TCHAR), 10); if (ERROR_SUCCESS != zbx_PdhMakeCounterPath(__function_name, &cpe, counterPath)) goto clean; if (NULL == (pcpus->cpu_counter[cpu_num] = add_perf_counter(NULL, counterPath, MAX_CPU_HISTORY))) goto clean; } cpe.szObjectName = get_counter_name(PCI_SYSTEM); cpe.szInstanceName = NULL; cpe.szCounterName = get_counter_name(PCI_PROCESSOR_QUEUE_LENGTH); if (ERROR_SUCCESS != zbx_PdhMakeCounterPath(__function_name, &cpe, counterPath)) goto clean; if (NULL == (pcpus->queue_counter = add_perf_counter(NULL, counterPath, MAX_CPU_HISTORY))) goto clean; ret = SUCCEED; clean: #else /* not _WINDOWS */ if (ZBX_MUTEX_ERROR == zbx_mutex_create_force(&cpustats_lock, ZBX_MUTEX_CPUSTATS)) { zbx_error("unable to create mutex for cpu collector"); exit(FAIL); } for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) pcpus->cpu[cpu_num].cpu_num = cpu_num; #ifdef HAVE_KSTAT_H /* Solaris */ if (NULL != (kc = kstat_open())) { if (NULL != (k = kstat_lookup(kc, "unix", 0, "kstat_headers")) && -1 != kstat_read(kc, k, NULL)) { int i; for (i = 0, cpu_num = 1; i < k->ks_ndata; i++) { kd = (kstat_t *)k->ks_data; if (0 == strcmp(kd[i].ks_module, "cpu_info")) pcpus->cpu[cpu_num++].cpu_num = kd[i].ks_instance + 1; } } kstat_close(kc); } #endif /* HAVE_KSTAT_H */ ret = SUCCEED; #endif /* _WINDOWS */ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
int SYSTEM_UNAME(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #if defined(_WINDOWS) DWORD dwSize = 256; TCHAR computerName[256], osVersion[256], *cpuType, wide_buffer[MAX_STRING_LEN]; SYSTEM_INFO sysInfo; OSVERSIONINFO versionInfo; /* Buffer size is chosen large enough to contain any DNS name, not just MAX_COMPUTERNAME_LENGTH + 1 */ /* characters. MAX_COMPUTERNAME_LENGTH is usually less than 32, but it varies among systems, so we */ /* cannot use the constant in a precompiled Windows agent, which is expected to work on any system. */ if (0 == GetComputerName(computerName, &dwSize)) *computerName = '\0'; versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&versionInfo); switch (versionInfo.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: switch (versionInfo.dwMinorVersion) { case 0: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows 95-%s"), versionInfo.szCSDVersion); break; case 10: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows 98-%s"), versionInfo.szCSDVersion); break; case 90: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows Me-%s"), versionInfo.szCSDVersion); break; default: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows [Unknown Version]")); } break; case VER_PLATFORM_WIN32_NT: switch (versionInfo.dwMajorVersion) { case 4: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows NT 4.0 %s"), versionInfo.szCSDVersion); break; case 5: switch (versionInfo.dwMinorVersion) { case 1: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows XP %s"), versionInfo.szCSDVersion); break; case 2: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows Server 2003 %s"), versionInfo.szCSDVersion); break; default: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows [Unknown Version]")); } break; case 6: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows Server 2008 %s"), versionInfo.szCSDVersion); break; default: zbx_wsnprintf(osVersion, sizeof(osVersion)/sizeof(TCHAR), TEXT("Windows [Unknown Version]")); break; } } GetSystemInfo(&sysInfo); switch(sysInfo.wProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_INTEL: cpuType=TEXT("Intel IA-32"); break; case PROCESSOR_ARCHITECTURE_MIPS: cpuType=TEXT("MIPS"); break; case PROCESSOR_ARCHITECTURE_ALPHA: cpuType=TEXT("Alpha"); break; case PROCESSOR_ARCHITECTURE_PPC: cpuType=TEXT("PowerPC"); break; case PROCESSOR_ARCHITECTURE_IA64: cpuType=TEXT("Intel IA-64"); break; case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: cpuType=TEXT("IA-32 on IA-64"); break; case PROCESSOR_ARCHITECTURE_AMD64: cpuType=TEXT("AMD-64"); break; default: cpuType=TEXT("unknown"); break; } zbx_wsnprintf(wide_buffer, MAX_STRING_LEN, TEXT("Windows %s %d.%d.%d %s %s"), computerName, versionInfo.dwMajorVersion, versionInfo.dwMinorVersion, versionInfo.dwBuildNumber, osVersion, cpuType); SET_STR_RESULT(result, zbx_unicode_to_utf8(wide_buffer)); return SYSINFO_RET_OK; #else return EXECUTE_STR(cmd, "uname -a", flags, result); #endif /* _WINDOWS */ }
/* 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; }
int init_cpu_collector(ZBX_CPUS_STAT_DATA *pcpus) { const char *__function_name = "init_cpu_collector"; int cpu_num, ret = FAIL; #ifdef _WINDOWS TCHAR cpu[8]; char counterPath[PDH_MAX_COUNTER_PATH]; PDH_COUNTER_PATH_ELEMENTS cpe; #endif zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); #ifdef _WINDOWS cpe.szMachineName = NULL; cpe.szObjectName = get_counter_name(PCI_PROCESSOR); cpe.szInstanceName = cpu; cpe.szParentInstance = NULL; cpe.dwInstanceIndex = -1; cpe.szCounterName = get_counter_name(PCI_PROCESSOR_TIME); for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) { if (0 == cpu_num) zbx_wsnprintf(cpu, sizeof(cpu) / sizeof(TCHAR), TEXT("_Total")); else _itow_s(cpu_num - 1, cpu, sizeof(cpu) / sizeof(TCHAR), 10); if (ERROR_SUCCESS != zbx_PdhMakeCounterPath(__function_name, &cpe, counterPath)) goto clean; if (NULL == (pcpus->cpu_counter[cpu_num] = add_perf_counter(NULL, counterPath, MAX_CPU_HISTORY))) goto clean; } cpe.szObjectName = get_counter_name(PCI_SYSTEM); cpe.szInstanceName = NULL; cpe.szCounterName = get_counter_name(PCI_PROCESSOR_QUEUE_LENGTH); if (ERROR_SUCCESS != zbx_PdhMakeCounterPath(__function_name, &cpe, counterPath)) goto clean; if (NULL == (pcpus->queue_counter = add_perf_counter(NULL, counterPath, MAX_CPU_HISTORY))) goto clean; ret = SUCCEED; clean: #else /* not _WINDOWS */ if (ZBX_MUTEX_ERROR == zbx_mutex_create_force(&cpustats_lock, ZBX_MUTEX_CPUSTATS)) { zbx_error("unable to create mutex for cpu collector"); exit(EXIT_FAILURE); } #ifndef HAVE_KSTAT_H for (cpu_num = 0; cpu_num <= pcpus->count; cpu_num++) pcpus->cpu[cpu_num].cpu_num = cpu_num; #else /* Solaris */ /* CPU instance numbers on Solaris can be non-contiguous, we don't know them yet */ pcpus->cpu[0].cpu_num = 0; for (cpu_num = 1; cpu_num <= pcpus->count; cpu_num++) pcpus->cpu[cpu_num].cpu_num = -1; if (NULL == (kc = kstat_open())) { zbx_error("kstat_open() failed"); exit(EXIT_FAILURE); } kc_id = kc->kc_chain_id; if (NULL == ksp) ksp = zbx_malloc(ksp, sizeof(kstat_t *) * pcpus->count); if (SUCCEED != refresh_kstat(pcpus)) { zbx_error("kstat_chain_update() failed"); exit(EXIT_FAILURE); } #endif /* HAVE_KSTAT_H */ ret = SUCCEED; #endif /* _WINDOWS */ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }