int SERVICE_STATE(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { SC_HANDLE mgr, service; char name[MAX_STRING_LEN]; LPTSTR wname; TCHAR service_name[MAX_STRING_LEN]; DWORD max_len_name = MAX_STRING_LEN; int i, ret = SYSINFO_RET_FAIL; SERVICE_STATUS status; if (num_param(param) > 1) return SYSINFO_RET_FAIL; if (get_param(param, 1, name, sizeof(name)) != 0) return SYSINFO_RET_FAIL; if ('\0' == *name) return SYSINFO_RET_FAIL; if (NULL == (mgr = OpenSCManager(NULL,NULL,GENERIC_READ)) ) return SYSINFO_RET_FAIL; wname = zbx_utf8_to_unicode(name); service = OpenService(mgr, wname, SERVICE_QUERY_STATUS); if (NULL == service && 0 != GetServiceKeyName(mgr, wname, service_name, &max_len_name)) service = OpenService(mgr, service_name, SERVICE_QUERY_STATUS); zbx_free(wname); if(NULL == service) { SET_UI64_RESULT(result, 255); } else { if (QueryServiceStatus(service, &status)) { static DWORD states[7] = {SERVICE_RUNNING, SERVICE_PAUSED, SERVICE_START_PENDING, SERVICE_PAUSE_PENDING, SERVICE_CONTINUE_PENDING, SERVICE_STOP_PENDING, SERVICE_STOPPED}; for (i = 0; i < 7 && status.dwCurrentState != states[i]; i++) ; SET_UI64_RESULT(result, i); } else { SET_UI64_RESULT(result, 7); } CloseServiceHandle(service); } CloseServiceHandle(mgr); return SYSINFO_RET_OK; }
service_info get_service_info(const std::string computer, const std::string service) { std::wstring comp = utf8::cvt<std::wstring>(computer); service_handle sc = OpenSCManager(comp.empty() ? NULL : comp.c_str(), NULL, SC_MANAGER_ENUMERATE_SERVICE); if (!sc) throw nsclient::nsclient_exception("Failed to open service manager: " + error::lookup::last_error()); service_handle hService = OpenService(sc, utf8::cvt<std::wstring>(service).c_str(), SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS); if (!hService) { DWORD error = GetLastError(); if (error == ERROR_SERVICE_DOES_NOT_EXIST) { hlp::buffer<wchar_t> buf(2048); DWORD size = buf.size(); if (!GetServiceKeyName(sc, utf8::cvt<std::wstring>(service).c_str(), buf.get(), &size)) { throw nsclient::nsclient_exception("Failed to open service " + service + ": " + error::lookup::last_error(error)); } hService = OpenService(sc, buf.get(), SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS); if (!hService) throw nsclient::nsclient_exception("Failed to open service " + service + ": " + error::lookup::last_error(error)); } else throw nsclient::nsclient_exception("Failed to open service " + service + ": " + error::lookup::last_error(error)); } hlp::buffer<BYTE, SERVICE_STATUS_PROCESS*> ssp = queryServiceStatusEx(hService, service); service_info info(service, "TODO"); info.pid = ssp.get()->dwProcessId; info.state = ssp.get()->dwCurrentState; info.type = ssp.get()->dwServiceType; DWORD bytesNeeded2 = 0; DWORD deErr = 0; if (QueryServiceConfig(hService, NULL, 0, &bytesNeeded2) || (deErr = GetLastError()) != ERROR_INSUFFICIENT_BUFFER) throw nsclient::nsclient_exception("Failed to open service " + info.name + ": " + error::lookup::last_error(deErr)); hlp::buffer<BYTE> buf2(bytesNeeded2 + 10); if (!QueryServiceConfig(hService, reinterpret_cast<QUERY_SERVICE_CONFIG*>(buf2.get()), bytesNeeded2, &bytesNeeded2)) throw nsclient::nsclient_exception("Failed to open service: " + info.name); QUERY_SERVICE_CONFIG *data2 = reinterpret_cast<QUERY_SERVICE_CONFIG*>(buf2.get()); info.start_type = data2->dwStartType; info.binary_path = utf8::cvt<std::string>(data2->lpBinaryPathName); info.error_control = data2->dwErrorControl; info.displayname = utf8::cvt<std::string>(data2->lpDisplayName); fetch_delayed(hService, info); fetch_triggers(hService, info); return info; }
char *get_service_name(char *display_name) { /* Get the service's true name from the SCM on NT/2000, since it * can be changed by the user on 2000, especially, from the * service control panel. We can't trust the service name to * match a space-collapsed display name. */ char service_name[MAX_PATH]; if (isWindowsNT()) { SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); DWORD namelen = sizeof(service_name); if (scm) { BOOL ok = GetServiceKeyName(scm, display_name, service_name, &namelen); CloseServiceHandle(scm); if (ok) return strdup(service_name); } } ap_remove_spaces(service_name, display_name); return strdup(service_name); }
int SERVICE_STATE(AGENT_REQUEST *request, AGENT_RESULT *result) { SC_HANDLE mgr, service; char *name; wchar_t *wname; wchar_t service_name[MAX_STRING_LEN]; DWORD max_len_name = MAX_STRING_LEN; int i; SERVICE_STATUS status; if (1 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } name = get_rparam(request, 0); if (NULL == name || '\0' == *name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } if (NULL == (mgr = OpenSCManager(NULL, NULL, GENERIC_READ))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information.")); return SYSINFO_RET_FAIL; } wname = zbx_utf8_to_unicode(name); service = OpenService(mgr, wname, SERVICE_QUERY_STATUS); if (NULL == service && 0 != GetServiceKeyName(mgr, wname, service_name, &max_len_name)) service = OpenService(mgr, service_name, SERVICE_QUERY_STATUS); zbx_free(wname); if (NULL == service) { SET_UI64_RESULT(result, 255); } else { if (0 != QueryServiceStatus(service, &status)) { for (i = 0; i < ARRSIZE(service_states) && status.dwCurrentState != service_states[i]; i++) ; SET_UI64_RESULT(result, i); } else SET_UI64_RESULT(result, 7); CloseServiceHandle(service); } CloseServiceHandle(mgr); return SYSINFO_RET_OK; }
int SERVICE_INFO(AGENT_REQUEST *request, AGENT_RESULT *result) { QUERY_SERVICE_CONFIG *qsc = NULL; SERVICE_DESCRIPTION *scd = NULL; SERVICE_STATUS status; SC_HANDLE h_mgr, h_srv; DWORD sz = 0; int param_type, i; char *name, *param; wchar_t *wname, service_name[MAX_STRING_LEN]; DWORD max_len_name = MAX_STRING_LEN; if (2 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } name = get_rparam(request, 0); param = get_rparam(request, 1); if (NULL == name || '\0' == *name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } if (NULL == param || '\0' == *param || 0 == strcmp(param, "state")) /* default second parameter */ param_type = ZBX_SRV_PARAM_STATE; else if (0 == strcmp(param, "displayname")) param_type = ZBX_SRV_PARAM_DISPLAYNAME; else if (0 == strcmp(param, "path")) param_type = ZBX_SRV_PARAM_PATH; else if (0 == strcmp(param, "user")) param_type = ZBX_SRV_PARAM_USER; else if (0 == strcmp(param, "startup")) param_type = ZBX_SRV_PARAM_STARTUP; else if (0 == strcmp(param, "description")) param_type = ZBX_SRV_PARAM_DESCRIPTION; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); return SYSINFO_RET_FAIL; } if (NULL == (h_mgr = OpenSCManager(NULL, NULL, GENERIC_READ))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information.")); return SYSINFO_RET_FAIL; } wname = zbx_utf8_to_unicode(name); h_srv = OpenService(h_mgr, wname, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); if (NULL == h_srv && 0 != GetServiceKeyName(h_mgr, wname, service_name, &max_len_name)) h_srv = OpenService(h_mgr, service_name, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); zbx_free(wname); if (NULL == h_srv) { int ret; if (ZBX_SRV_PARAM_STATE == param_type) { SET_UI64_RESULT(result, 255); ret = SYSINFO_RET_OK; } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot find the specified service.")); ret = SYSINFO_RET_FAIL; } CloseServiceHandle(h_mgr); return ret; } if (ZBX_SRV_PARAM_STATE == param_type) { if (0 != QueryServiceStatus(h_srv, &status)) { for (i = 0; i < ARRSIZE(service_states) && status.dwCurrentState != service_states[i]; i++) ; SET_UI64_RESULT(result, i); } else SET_UI64_RESULT(result, 7); } else if (ZBX_SRV_PARAM_DESCRIPTION == param_type) { QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &sz); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s", strerror_from_system(GetLastError()))); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } scd = (SERVICE_DESCRIPTION *)zbx_malloc(scd, sz); if (0 == QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)scd, sz, &sz)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s", strerror_from_system(GetLastError()))); zbx_free(scd); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } if (NULL == scd->lpDescription) SET_TEXT_RESULT(result, zbx_strdup(NULL, "")); else SET_TEXT_RESULT(result, zbx_unicode_to_utf8(scd->lpDescription)); zbx_free(scd); } else { QueryServiceConfig(h_srv, NULL, 0, &sz); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s", strerror_from_system(GetLastError()))); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } qsc = (QUERY_SERVICE_CONFIG *)zbx_malloc(qsc, sz); if (0 == QueryServiceConfig(h_srv, qsc, sz, &sz)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s", strerror_from_system(GetLastError()))); zbx_free(qsc); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } switch (param_type) { case ZBX_SRV_PARAM_DISPLAYNAME: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpDisplayName)); break; case ZBX_SRV_PARAM_PATH: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpBinaryPathName)); break; case ZBX_SRV_PARAM_USER: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpServiceStartName)); break; case ZBX_SRV_PARAM_STARTUP: if (SERVICE_AUTO_START == qsc->dwStartType) { if (SUCCEED == check_delayed_start(h_srv)) SET_UI64_RESULT(result, 1); else SET_UI64_RESULT(result, 0); } else { for (i = 2; i < ARRSIZE(start_types) && qsc->dwStartType != start_types[i]; i++) ; SET_UI64_RESULT(result, i); } break; } zbx_free(qsc); } CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_OK; }