Skip to content

Instantly share code, notes, and snippets.

@cavaliercoder
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cavaliercoder/d09139eb68abcdbfed16 to your computer and use it in GitHub Desktop.
Save cavaliercoder/d09139eb68abcdbfed16 to your computer and use it in GitHub Desktop.
Windows service discovery in Zabbix v2.2.8
diff -ur zabbix-2.2.8/include/sysinfo.h ZBXNEXT-1368/include/sysinfo.h
--- zabbix-2.2.8/include/sysinfo.h 2014-12-16 14:38:17.000000000 +0800
+++ ZBXNEXT-1368/include/sysinfo.h 2015-02-16 14:51:38.800892200 +0800
@@ -243,6 +243,7 @@
int PERF_COUNTER(AGENT_REQUEST *request, AGENT_RESULT *result);
int SERVICE_STATE(AGENT_REQUEST *request, AGENT_RESULT *result);
int SERVICES(AGENT_REQUEST *request, AGENT_RESULT *result);
+int SERVICE_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result);
int PROC_INFO(AGENT_REQUEST *request, AGENT_RESULT *result);
int NET_IF_LIST(AGENT_REQUEST *request, AGENT_RESULT *result);
int WMI_GET(AGENT_REQUEST *request, AGENT_RESULT *result);
diff -ur zabbix-2.2.8/src/libs/zbxsysinfo/win32/services.c ZBXNEXT-1368/src/libs/zbxsysinfo/win32/services.c
--- zabbix-2.2.8/src/libs/zbxsysinfo/win32/services.c 2014-12-16 14:38:18.000000000 +0800
+++ ZBXNEXT-1368/src/libs/zbxsysinfo/win32/services.c 2015-02-16 14:49:31.269481600 +0800
@@ -20,6 +20,7 @@
#include "common.h"
#include "sysinfo.h"
#include "log.h"
+#include "zbxjson.h"
int SERVICE_STATE(AGENT_REQUEST *request, AGENT_RESULT *result)
{
@@ -272,3 +273,130 @@
return SYSINFO_RET_OK;
}
+
+/*
+ * Custom key services.discovery ZBX-1368
+ *
+ * Returns:
+ * {
+ * "data":[
+ * {
+ * "{#SERVICE_NAME}":"Name",
+ * "{#SERVICE_DISPLAYNAME}":"Description",
+ * "{#SERVICE_TYPE}":"service",
+ * "{#SERVICE_PATH}":"C:\path\to\executable.exe -args",
+ * "{#SERVICE_USERNAME}":"localSystem",
+ * "{#SERVICE_START_TYPE}":"manual|automatic|disabled"},
+ * {...}]}
+ */
+int SERVICE_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result)
+{
+ int ret;
+ char *utf8;
+ SC_HANDLE h_mgr, h_srv;
+ ENUM_SERVICE_STATUS_PROCESS *ssp = NULL;
+ QUERY_SERVICE_CONFIG *qsc = NULL;
+ DWORD sz = 0, szn, i, services, resume_handle = 0;
+ struct zbx_json j;
+
+ if (0 < request->nparam)
+ return SYSINFO_RET_FAIL;
+
+ // Get a handle to the Service Control Manager
+ if (NULL == (h_mgr = OpenSCManager(NULL, NULL, GENERIC_READ)))
+ return SYSINFO_RET_FAIL;
+
+ // Init JSON return object
+ zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN);
+ zbx_json_addarray(&j, ZBX_PROTO_TAG_DATA);
+
+ // Enumerate services with EnumServicesStatusEx (XP/2003+)
+ while (0 != (ret = EnumServicesStatusEx(h_mgr, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,
+ (LPBYTE)ssp, sz, &szn, &services, &resume_handle, NULL)) || ERROR_MORE_DATA == GetLastError())
+ {
+ for (i = 0; i < services; i++)
+ {
+ // Get a handle to the service
+ if (NULL == (h_srv = OpenService(h_mgr, ssp[i].lpServiceName, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG)))
+ continue;
+
+ // Populate JSON response with service details
+ zbx_json_addobject(&j, NULL);
+
+ utf8 = zbx_unicode_to_utf8(ssp[i].lpServiceName);
+ zbx_json_addstring(&j, "{#SERVICE_NAME}", utf8, ZBX_JSON_TYPE_STRING);
+ zbx_free(utf8);
+
+ utf8 = zbx_unicode_to_utf8(ssp[i].lpDisplayName);
+ zbx_json_addstring(&j, "{#SERVICE_DISPLAYNAME}", utf8, ZBX_JSON_TYPE_STRING);
+ zbx_free(utf8);
+
+ if((SERVICE_FILE_SYSTEM_DRIVER | SERVICE_KERNEL_DRIVER) & ssp[i].ServiceStatusProcess.dwServiceType)
+ utf8 = "driver";
+ else if((SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS) & ssp[i].ServiceStatusProcess.dwServiceType)
+ utf8 = "service";
+ else
+ utf8 = "Unknown";
+
+ zbx_json_addstring(&j, "{#SERVICE_TYPE}", utf8, ZBX_JSON_TYPE_STRING);
+
+ // Get service configuration with QueryServiceConfig (XP/2003+)
+ QueryServiceConfig(h_srv, qsc, 0, &sz);
+ if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
+ // Expand buffer size
+ qsc = (QUERY_SERVICE_CONFIG *)zbx_malloc((void *)qsc, sz);
+ if (0 != QueryServiceConfig(h_srv, qsc, sz, &sz))
+ {
+ // Populate JSON respose with service config
+ utf8 = zbx_unicode_to_utf8(qsc->lpBinaryPathName);
+ zbx_json_addstring(&j, "{#SERVICE_PATH}", utf8, ZBX_JSON_TYPE_STRING);
+ zbx_free(utf8);
+
+ utf8 = zbx_unicode_to_utf8(qsc->lpServiceStartName);
+ zbx_json_addstring(&j, "{#SERVICE_USERNAME}", utf8, ZBX_JSON_TYPE_STRING);
+ zbx_free(utf8);
+
+ if(SERVICE_DEMAND_START == qsc->dwStartType)
+ utf8 = "manual";
+ else if(SERVICE_DISABLED == qsc->dwStartType)
+ utf8 = "disabled";
+ else if(
+ SERVICE_AUTO_START == qsc->dwStartType
+ || SERVICE_BOOT_START == qsc->dwStartType
+ || SERVICE_SYSTEM_START == qsc->dwStartType
+ )
+ utf8 = "automatic";
+ else
+ utf8 = "unknown";
+
+ zbx_json_addstring(&j, "{#SERVICE_START_TYPE}", utf8, ZBX_JSON_TYPE_STRING);
+ }
+
+ zbx_free(qsc);
+ }
+
+ zbx_json_close(&j);
+
+ CloseServiceHandle(h_srv);
+ }
+
+ if (0 == szn)
+ break;
+
+ if (NULL == ssp)
+ {
+ sz = szn;
+ ssp = (ENUM_SERVICE_STATUS_PROCESS *)zbx_malloc((void *)ssp, sz);
+ }
+ }
+
+ zbx_free(ssp);
+
+ CloseServiceHandle(h_mgr);
+
+ zbx_json_close(&j);
+ SET_STR_RESULT(result, strdup(j.buffer));
+ zbx_json_free(&j);
+
+ return SYSINFO_RET_OK;
+}
\ No newline at end of file
diff -ur zabbix-2.2.8/src/libs/zbxsysinfo/win32/win32.c ZBXNEXT-1368/src/libs/zbxsysinfo/win32/win32.c
--- zabbix-2.2.8/src/libs/zbxsysinfo/win32/win32.c 2014-12-16 14:38:18.000000000 +0800
+++ ZBXNEXT-1368/src/libs/zbxsysinfo/win32/win32.c 2015-02-16 14:51:18.122097700 +0800
@@ -54,6 +54,7 @@
{"service_state", CF_HAVEPARAMS, SERVICE_STATE, ZABBIX_SERVICE_NAME},
{"services", CF_HAVEPARAMS, SERVICES, NULL},
+ {"service.discovery", CF_HAVEPARAMS, SERVICE_DISCOVERY, NULL},
{"perf_counter", CF_HAVEPARAMS, PERF_COUNTER, "\\System\\Processes"},
{"proc_info", CF_HAVEPARAMS, PROC_INFO, "svchost.exe"},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment