From 68bce7fd5af40eef2a45fbcc7f788f50156a8233 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Sun, 6 Mar 2016 17:41:38 -0800 Subject: [PATCH] #795 / win services: add description --- psutil/_psutil_windows.c | 2 + psutil/_pswindows.py | 3 ++ psutil/arch/windows/services.c | 71 +++++++++++++++++++++++++++++++++- psutil/arch/windows/services.h | 1 + 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index 93984435d..d4e309da3 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -3353,6 +3353,8 @@ PsutilMethods[] = { // --- windows services {"winservice_enumerate", psutil_winservice_enumerate, METH_VARARGS, "List all services"}, + {"winservice_get_srv_descr", psutil_winservice_get_srv_descr, METH_VARARGS, + "Return the description of a service"}, // --- windows API bindings {"win32_QueryDosDevice", psutil_win32_QueryDosDevice, METH_VARARGS, diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index a43860709..131f0409e 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -359,6 +359,9 @@ def username(self): def start_type(self): return self._info['startup'] + def description(self): + return cext.winservice_get_srv_descr(self.name()) + def as_dict(self): return self._info diff --git a/psutil/arch/windows/services.c b/psutil/arch/windows/services.c index 1f3bed7ce..dc72a253d 100644 --- a/psutil/arch/windows/services.c +++ b/psutil/arch/windows/services.c @@ -115,7 +115,7 @@ psutil_winservice_enumerate(PyObject *self, PyObject *args) { // TODO: handle encoding errs qsc->lpBinaryPathName, // binpath qsc->lpServiceStartName, // username - get_startup_string(qsc->dwStartType), // startup + get_startup_string(qsc->dwStartType) // startup ); if (py_tuple == NULL) goto error; @@ -145,3 +145,72 @@ psutil_winservice_enumerate(PyObject *self, PyObject *args) { free(lpService); return NULL; } + + +/* + * Get service description. + */ +PyObject * +psutil_winservice_get_srv_descr(PyObject *self, PyObject *args) { + ENUM_SERVICE_STATUS_PROCESS *lpService = NULL; + SC_HANDLE sc = NULL; + BOOL ok; + DWORD bytesNeeded = 0; + DWORD resumeHandle = 0; + DWORD dwBytes = 0; + SC_HANDLE hService = NULL; + SERVICE_DESCRIPTION *scd = NULL; + char *service_name; + PyObject *py_retstr = NULL; + + if (!PyArg_ParseTuple(args, "s", &service_name)) + return NULL; + + sc = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); + if (sc == NULL) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + + hService = OpenService(sc, service_name, SERVICE_QUERY_CONFIG); + if (hService == NULL) { + PyErr_SetFromWindowsErr(0); + goto error; + } + + // This first call to QueryServiceConfig2() is necessary in order + // to get the right size. + bytesNeeded = 0; + QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, NULL, 0, + &bytesNeeded); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + PyErr_SetFromWindowsErr(0); + goto error; + } + + scd = (SERVICE_DESCRIPTION *)malloc(bytesNeeded); + ok = QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, + (LPBYTE)scd, bytesNeeded, &bytesNeeded); + if (ok == 0) { + PyErr_SetFromWindowsErr(0); + goto error; + } + + // TODO: handle encoding errors. + py_retstr = Py_BuildValue("s", scd->lpDescription); + if (!py_retstr) + goto error; + + CloseServiceHandle(sc); + free(scd); + return py_retstr; + +error: + if (hService != NULL) + CloseServiceHandle(hService); + if (sc != NULL) + CloseServiceHandle(sc); + if (lpService != NULL) + free(lpService); + return NULL; +} diff --git a/psutil/arch/windows/services.h b/psutil/arch/windows/services.h index bee7e43e7..145b18218 100644 --- a/psutil/arch/windows/services.h +++ b/psutil/arch/windows/services.h @@ -7,3 +7,4 @@ #include PyObject *psutil_winservice_enumerate(); +PyObject *psutil_winservice_get_srv_descr();