Exemple #1
0
int	SERVICE_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result)
{
	ENUM_SERVICE_STATUS_PROCESS	*ssp = NULL;
	QUERY_SERVICE_CONFIG		*qsc = NULL;
	SERVICE_DESCRIPTION		*scd = NULL;
	SC_HANDLE			h_mgr;
	DWORD				sz = 0, szn, i, k, services, resume_handle = 0;
	char				*utf8;
	struct zbx_json			j;

	if (NULL == (h_mgr = OpenSCManager(NULL, NULL, GENERIC_READ)))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information."));
		return SYSINFO_RET_FAIL;
	}

	zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN);
	zbx_json_addarray(&j, ZBX_PROTO_TAG_DATA);

	while (0 != 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++)
		{
			SC_HANDLE	h_srv;
			DWORD		current_state;

			if (NULL == (h_srv = OpenService(h_mgr, ssp[i].lpServiceName, SERVICE_QUERY_CONFIG)))
				continue;

			QueryServiceConfig(h_srv, NULL, 0, &sz);

			if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
			{
				zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain configuration of service \"%s\": %s",
						ssp[i].lpServiceName, strerror_from_system(GetLastError()));
				goto next;
			}

			qsc = (QUERY_SERVICE_CONFIG *)zbx_malloc(qsc, sz);

			if (0 == QueryServiceConfig(h_srv, qsc, sz, &sz))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain configuration of service \"%s\": %s",
						ssp[i].lpServiceName, strerror_from_system(GetLastError()));
				goto next;
			}

			QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &sz);

			if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
			{
				zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain description of service \"%s\": %s",
						ssp[i].lpServiceName, strerror_from_system(GetLastError()));
				goto next;
			}

			scd = (SERVICE_DESCRIPTION *)zbx_malloc(scd, sz);

			if (0 == QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)scd, sz, &sz))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain description of service \"%s\": %s",
						ssp[i].lpServiceName, strerror_from_system(GetLastError()));
				goto next;
			}

			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 (NULL != scd->lpDescription)
			{
				utf8 = zbx_unicode_to_utf8(scd->lpDescription);
				zbx_json_addstring(&j, "{#SERVICE.DESCRIPTION}", utf8, ZBX_JSON_TYPE_STRING);
				zbx_free(utf8);
			}
			else
				zbx_json_addstring(&j, "{#SERVICE.DESCRIPTION}", "", ZBX_JSON_TYPE_STRING);

			current_state = ssp[i].ServiceStatusProcess.dwCurrentState;
			for (k = 0; k < ARRSIZE(service_states) && current_state != service_states[k]; k++)
				;

			zbx_json_adduint64(&j, "{#SERVICE.STATE}", k);
			zbx_json_addstring(&j, "{#SERVICE.STATENAME}", get_state_string(current_state),
					ZBX_JSON_TYPE_STRING);

			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.USER}", utf8, ZBX_JSON_TYPE_STRING);
			zbx_free(utf8);

			if (SERVICE_AUTO_START == qsc->dwStartType)
			{
				if (SUCCEED == check_delayed_start(h_srv))
				{
					zbx_json_adduint64(&j, "{#SERVICE.STARTUP}", 1);
					zbx_json_addstring(&j, "{#SERVICE.STARTUPNAME}", "automatic delayed",
							ZBX_JSON_TYPE_STRING);
				}
				else
				{
					zbx_json_adduint64(&j, "{#SERVICE.STARTUP}", 0);
					zbx_json_addstring(&j, "{#SERVICE.STARTUPNAME}", "automatic",
							ZBX_JSON_TYPE_STRING);
				}
			}
			else
			{
				for (k = 2; k < ARRSIZE(start_types) &&	qsc->dwStartType != start_types[k]; k++)
					;

				zbx_json_adduint64(&j, "{#SERVICE.STARTUP}", k);
				zbx_json_addstring(&j, "{#SERVICE.STARTUPNAME}", get_startup_string(qsc->dwStartType),
						ZBX_JSON_TYPE_STRING);
			}

			zbx_json_close(&j);
next:
			zbx_free(scd);
			zbx_free(qsc);

			CloseServiceHandle(h_srv);
		}

		if (0 == szn)
			break;

		if (NULL == ssp)
		{
			sz = szn;
			ssp = (ENUM_SERVICE_STATUS_PROCESS *)zbx_malloc(ssp, sz);
		}
	}

	zbx_free(ssp);

	CloseServiceHandle(h_mgr);

	zbx_json_close(&j);

	SET_STR_RESULT(result, zbx_strdup(NULL, j.buffer));

	zbx_json_free(&j);

	return SYSINFO_RET_OK;
}
Exemple #2
0
/*
 * Get service config information. Returns:
 * - display_name
 * - binpath
 * - username
 * - startup_type
 */
PyObject *
psutil_winservice_query_config(PyObject *self, PyObject *args) {
    char *service_name;
    SC_HANDLE hService = NULL;
    BOOL ok;
    DWORD bytesNeeded = 0;
    DWORD resumeHandle = 0;
    DWORD dwBytes = 0;
    QUERY_SERVICE_CONFIG *qsc = NULL;
    PyObject *py_tuple = NULL;
    PyObject *py_unicode_display_name = NULL;
    PyObject *py_unicode_binpath = NULL;
    PyObject *py_unicode_username = NULL;

    if (!PyArg_ParseTuple(args, "s", &service_name))
        return NULL;
    hService = psutil_get_service_handler(
        service_name, SC_MANAGER_ENUMERATE_SERVICE, SERVICE_QUERY_CONFIG);
    if (hService == NULL)
        goto error;

    // First call to QueryServiceConfig() is necessary to get the
    // right size.
    bytesNeeded = 0;
    QueryServiceConfig(hService, NULL, 0, &bytesNeeded);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }
    qsc = (QUERY_SERVICE_CONFIG *)malloc(bytesNeeded);
    ok = QueryServiceConfig(hService, qsc, bytesNeeded, &bytesNeeded);
    if (ok == 0) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    // Get unicode display name.
    py_unicode_display_name = PyUnicode_Decode(
        qsc->lpDisplayName,
        _tcslen(qsc->lpDisplayName),
        Py_FileSystemDefaultEncoding,
        "replace");
    if (py_unicode_display_name == NULL)
        goto error;

    // Get unicode bin path.
    py_unicode_binpath = PyUnicode_Decode(
        qsc->lpBinaryPathName,
        _tcslen(qsc->lpBinaryPathName),
        Py_FileSystemDefaultEncoding,
        "replace");
    if (py_unicode_binpath == NULL)
        goto error;

    // Get unicode username.
    py_unicode_username = PyUnicode_Decode(
        qsc->lpServiceStartName,
        _tcslen(qsc->lpServiceStartName),
        Py_FileSystemDefaultEncoding,
        "replace");
    if (py_unicode_username == NULL)
        goto error;

    // Construct result tuple.
    py_tuple = Py_BuildValue(
        "(OOOs)",
        py_unicode_display_name,
        py_unicode_binpath,
        py_unicode_username,
        get_startup_string(qsc->dwStartType)  // startup
    );
    if (py_tuple == NULL)
        goto error;

    // Free resources.
    Py_DECREF(py_unicode_display_name);
    Py_DECREF(py_unicode_binpath);
    Py_DECREF(py_unicode_username);
    free(qsc);
    CloseServiceHandle(hService);
    return py_tuple;

error:
    Py_XDECREF(py_unicode_display_name);
    Py_XDECREF(py_unicode_binpath);
    Py_XDECREF(py_unicode_username);
    Py_XDECREF(py_tuple);
    if (hService != NULL)
        CloseServiceHandle(hService);
    if (qsc != NULL)
        free(qsc);
    return NULL;
}