2006-11-08 11:47:44 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Services
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2007-08-24 18:27:12 +00:00
|
|
|
* FILE: base/applications/mscutils/servman/query.c
|
2006-11-08 11:47:44 +00:00
|
|
|
* PURPOSE: Query service information
|
2007-08-24 18:27:12 +00:00
|
|
|
* COPYRIGHT: Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org>
|
2006-11-08 11:47:44 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
|
|
ENUM_SERVICE_STATUS_PROCESS*
|
|
|
|
GetSelectedService(PMAIN_WND_INFO Info)
|
|
|
|
{
|
|
|
|
LVITEM lvItem;
|
|
|
|
|
|
|
|
lvItem.mask = LVIF_PARAM;
|
|
|
|
lvItem.iItem = Info->SelectedItem;
|
|
|
|
SendMessage(Info->hListView,
|
|
|
|
LVM_GETITEM,
|
|
|
|
0,
|
|
|
|
(LPARAM)&lvItem);
|
|
|
|
|
|
|
|
/* return pointer to selected service */
|
|
|
|
return (ENUM_SERVICE_STATUS_PROCESS *)lvItem.lParam;
|
|
|
|
}
|
|
|
|
|
2007-08-28 14:49:47 +00:00
|
|
|
LPQUERY_SERVICE_CONFIG
|
2015-04-08 17:30:38 +00:00
|
|
|
GetServiceConfig(LPWSTR lpServiceName)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
LPQUERY_SERVICE_CONFIGW lpServiceConfig = NULL;
|
2009-12-21 11:57:58 +00:00
|
|
|
SC_HANDLE hSCManager;
|
|
|
|
SC_HANDLE hService;
|
|
|
|
DWORD dwBytesNeeded;
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2015-04-08 17:30:38 +00:00
|
|
|
hSCManager = OpenSCManagerW(NULL,
|
|
|
|
NULL,
|
2016-05-26 15:48:46 +00:00
|
|
|
SC_MANAGER_CONNECT);
|
2009-12-21 11:57:58 +00:00
|
|
|
if (hSCManager)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
hService = OpenServiceW(hSCManager,
|
|
|
|
lpServiceName,
|
2016-05-26 15:48:46 +00:00
|
|
|
SERVICE_QUERY_CONFIG);
|
2009-12-21 11:57:58 +00:00
|
|
|
if (hService)
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
if (!QueryServiceConfigW(hService,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
&dwBytesNeeded))
|
2006-11-08 11:47:44 +00:00
|
|
|
{
|
2009-12-21 11:57:58 +00:00
|
|
|
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
|
|
{
|
|
|
|
lpServiceConfig = (LPQUERY_SERVICE_CONFIG)HeapAlloc(GetProcessHeap(),
|
|
|
|
0,
|
|
|
|
dwBytesNeeded);
|
|
|
|
if (lpServiceConfig)
|
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
if (!QueryServiceConfigW(hService,
|
2009-12-21 11:57:58 +00:00
|
|
|
lpServiceConfig,
|
|
|
|
dwBytesNeeded,
|
|
|
|
&dwBytesNeeded))
|
|
|
|
{
|
|
|
|
HeapFree(GetProcessHeap(),
|
|
|
|
0,
|
|
|
|
lpServiceConfig);
|
|
|
|
lpServiceConfig = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
2009-12-21 11:57:58 +00:00
|
|
|
|
|
|
|
CloseServiceHandle(hService);
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
2007-08-28 14:49:47 +00:00
|
|
|
CloseServiceHandle(hSCManager);
|
2009-12-21 11:57:58 +00:00
|
|
|
}
|
2007-08-28 14:49:47 +00:00
|
|
|
|
2009-12-21 11:57:58 +00:00
|
|
|
return lpServiceConfig;
|
2007-08-28 14:49:47 +00:00
|
|
|
}
|
|
|
|
|
2007-08-29 09:42:31 +00:00
|
|
|
BOOL
|
|
|
|
SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig,
|
2015-04-08 17:30:38 +00:00
|
|
|
LPWSTR lpServiceName,
|
|
|
|
LPWSTR lpPassword)
|
2007-08-28 19:54:25 +00:00
|
|
|
{
|
2007-08-29 09:42:31 +00:00
|
|
|
SC_HANDLE hSCManager;
|
|
|
|
SC_HANDLE hSc;
|
|
|
|
SC_LOCK scLock;
|
|
|
|
BOOL bRet = FALSE;
|
2007-08-28 19:54:25 +00:00
|
|
|
|
2015-04-08 17:30:38 +00:00
|
|
|
hSCManager = OpenSCManagerW(NULL,
|
|
|
|
NULL,
|
|
|
|
SC_MANAGER_LOCK);
|
2007-08-29 09:42:31 +00:00
|
|
|
if (hSCManager)
|
|
|
|
{
|
|
|
|
scLock = LockServiceDatabase(hSCManager);
|
|
|
|
if (scLock)
|
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
hSc = OpenServiceW(hSCManager,
|
|
|
|
lpServiceName,
|
|
|
|
SERVICE_CHANGE_CONFIG);
|
2007-08-29 09:42:31 +00:00
|
|
|
if (hSc)
|
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
if (ChangeServiceConfigW(hSc,
|
|
|
|
pServiceConfig->dwServiceType,
|
|
|
|
pServiceConfig->dwStartType,
|
|
|
|
pServiceConfig->dwErrorControl,
|
|
|
|
pServiceConfig->lpBinaryPathName,
|
|
|
|
pServiceConfig->lpLoadOrderGroup,
|
|
|
|
pServiceConfig->dwTagId ? &pServiceConfig->dwTagId : NULL,
|
|
|
|
pServiceConfig->lpDependencies,
|
|
|
|
pServiceConfig->lpServiceStartName,
|
|
|
|
lpPassword,
|
|
|
|
pServiceConfig->lpDisplayName))
|
2007-08-29 09:42:31 +00:00
|
|
|
{
|
|
|
|
bRet = TRUE;
|
|
|
|
}
|
2008-10-18 11:49:25 +00:00
|
|
|
|
|
|
|
CloseServiceHandle(hSc);
|
2007-08-29 09:42:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UnlockServiceDatabase(scLock);
|
|
|
|
}
|
2008-10-18 11:49:25 +00:00
|
|
|
|
|
|
|
CloseServiceHandle(hSCManager);
|
2007-08-29 09:42:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!bRet)
|
|
|
|
GetError();
|
|
|
|
|
|
|
|
return bRet;
|
2007-08-28 19:54:25 +00:00
|
|
|
}
|
|
|
|
|
2015-04-08 17:30:38 +00:00
|
|
|
LPWSTR
|
|
|
|
GetServiceDescription(LPWSTR lpServiceName)
|
2007-08-28 14:49:47 +00:00
|
|
|
{
|
|
|
|
SC_HANDLE hSCManager = NULL;
|
|
|
|
SC_HANDLE hSc = NULL;
|
2015-04-08 17:30:38 +00:00
|
|
|
SERVICE_DESCRIPTIONW *pServiceDescription = NULL;
|
|
|
|
LPWSTR lpDescription = NULL;
|
2007-08-28 14:49:47 +00:00
|
|
|
DWORD BytesNeeded = 0;
|
2010-01-05 18:39:47 +00:00
|
|
|
DWORD dwSize;
|
2007-08-28 14:49:47 +00:00
|
|
|
|
2015-04-08 17:30:38 +00:00
|
|
|
hSCManager = OpenSCManagerW(NULL,
|
|
|
|
NULL,
|
|
|
|
SC_MANAGER_ENUMERATE_SERVICE);
|
2007-08-28 14:49:47 +00:00
|
|
|
if (hSCManager == NULL)
|
|
|
|
{
|
|
|
|
GetError();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-04-08 17:30:38 +00:00
|
|
|
hSc = OpenServiceW(hSCManager,
|
|
|
|
lpServiceName,
|
|
|
|
SERVICE_QUERY_CONFIG);
|
2007-08-28 14:49:47 +00:00
|
|
|
if (hSc)
|
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
if (!QueryServiceConfig2W(hSc,
|
|
|
|
SERVICE_CONFIG_DESCRIPTION,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
&BytesNeeded))
|
2007-08-28 14:49:47 +00:00
|
|
|
{
|
|
|
|
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
|
|
{
|
|
|
|
pServiceDescription = (SERVICE_DESCRIPTION *) HeapAlloc(ProcessHeap,
|
|
|
|
0,
|
|
|
|
BytesNeeded);
|
|
|
|
if (pServiceDescription == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-04-08 17:30:38 +00:00
|
|
|
if (QueryServiceConfig2W(hSc,
|
|
|
|
SERVICE_CONFIG_DESCRIPTION,
|
|
|
|
(LPBYTE)pServiceDescription,
|
|
|
|
BytesNeeded,
|
|
|
|
&BytesNeeded))
|
2007-08-28 14:49:47 +00:00
|
|
|
{
|
|
|
|
if (pServiceDescription->lpDescription)
|
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
dwSize = wcslen(pServiceDescription->lpDescription) + 1;
|
2007-08-28 14:49:47 +00:00
|
|
|
lpDescription = HeapAlloc(ProcessHeap,
|
|
|
|
0,
|
2015-04-08 17:30:38 +00:00
|
|
|
dwSize * sizeof(WCHAR));
|
2007-08-28 14:49:47 +00:00
|
|
|
if (lpDescription)
|
2010-01-05 18:39:47 +00:00
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
StringCchCopyW(lpDescription,
|
|
|
|
dwSize,
|
|
|
|
pServiceDescription->lpDescription);
|
2010-01-05 18:39:47 +00:00
|
|
|
}
|
2007-08-28 14:49:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
if (pServiceDescription)
|
2007-08-23 14:57:44 +00:00
|
|
|
HeapFree(ProcessHeap,
|
|
|
|
0,
|
2007-08-28 14:49:47 +00:00
|
|
|
pServiceDescription);
|
2006-11-08 11:47:44 +00:00
|
|
|
if (hSCManager != NULL)
|
|
|
|
CloseServiceHandle(hSCManager);
|
|
|
|
if (hSc != NULL)
|
|
|
|
CloseServiceHandle(hSc);
|
|
|
|
|
2007-08-28 14:49:47 +00:00
|
|
|
return lpDescription;
|
2006-11-08 11:47:44 +00:00
|
|
|
}
|
|
|
|
|
2007-08-30 12:27:11 +00:00
|
|
|
BOOL
|
2015-04-08 17:30:38 +00:00
|
|
|
SetServiceDescription(LPWSTR lpServiceName,
|
|
|
|
LPWSTR lpDescription)
|
2007-08-30 12:27:11 +00:00
|
|
|
{
|
|
|
|
SC_HANDLE hSCManager;
|
|
|
|
SC_HANDLE hSc;
|
|
|
|
SC_LOCK scLock;
|
|
|
|
SERVICE_DESCRIPTION ServiceDescription;
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
|
2015-04-08 17:30:38 +00:00
|
|
|
hSCManager = OpenSCManagerW(NULL,
|
|
|
|
NULL,
|
|
|
|
SC_MANAGER_LOCK);
|
2007-08-30 12:27:11 +00:00
|
|
|
if (hSCManager)
|
|
|
|
{
|
|
|
|
scLock = LockServiceDatabase(hSCManager);
|
|
|
|
if (scLock)
|
|
|
|
{
|
2015-04-08 17:30:38 +00:00
|
|
|
hSc = OpenServiceW(hSCManager,
|
|
|
|
lpServiceName,
|
|
|
|
SERVICE_CHANGE_CONFIG);
|
2007-08-30 12:27:11 +00:00
|
|
|
if (hSc)
|
|
|
|
{
|
|
|
|
ServiceDescription.lpDescription = lpDescription;
|
|
|
|
|
2015-04-08 17:30:38 +00:00
|
|
|
if (ChangeServiceConfig2W(hSc,
|
|
|
|
SERVICE_CONFIG_DESCRIPTION,
|
|
|
|
&ServiceDescription))
|
2007-08-30 12:27:11 +00:00
|
|
|
{
|
|
|
|
bRet = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
CloseServiceHandle(hSc);
|
|
|
|
}
|
|
|
|
|
|
|
|
UnlockServiceDatabase(scLock);
|
|
|
|
}
|
|
|
|
|
|
|
|
CloseServiceHandle(hSCManager);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bRet)
|
|
|
|
GetError();
|
|
|
|
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
2017-04-23 17:39:26 +00:00
|
|
|
VOID
|
|
|
|
FreeServiceList(PMAIN_WND_INFO Info)
|
|
|
|
{
|
|
|
|
DWORD i;
|
|
|
|
|
|
|
|
if (Info->pAllServices != NULL)
|
|
|
|
{
|
|
|
|
for (i = 0; i < Info->NumServices; i++)
|
|
|
|
{
|
|
|
|
if (Info->pAllServices[i].lpServiceName)
|
|
|
|
HeapFree(ProcessHeap, 0, Info->pAllServices[i].lpServiceName);
|
|
|
|
|
|
|
|
if (Info->pAllServices[i].lpDisplayName)
|
|
|
|
HeapFree(ProcessHeap, 0, Info->pAllServices[i].lpDisplayName);
|
|
|
|
}
|
|
|
|
|
|
|
|
HeapFree(ProcessHeap, 0, Info->pAllServices);
|
|
|
|
Info->pAllServices = NULL;
|
|
|
|
Info->NumServices = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-29 18:10:58 +00:00
|
|
|
BOOL
|
2017-04-23 17:39:26 +00:00
|
|
|
GetServiceList(PMAIN_WND_INFO Info)
|
2007-08-25 13:41:44 +00:00
|
|
|
{
|
2017-04-23 17:39:26 +00:00
|
|
|
ENUM_SERVICE_STATUS_PROCESS *pServices = NULL;
|
2007-08-25 13:41:44 +00:00
|
|
|
SC_HANDLE ScHandle;
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
|
|
|
|
DWORD BytesNeeded = 0;
|
|
|
|
DWORD ResumeHandle = 0;
|
2017-04-23 17:39:26 +00:00
|
|
|
DWORD NumServices = 0;
|
|
|
|
DWORD i;
|
2007-08-25 13:41:44 +00:00
|
|
|
|
2017-04-23 17:39:26 +00:00
|
|
|
FreeServiceList(Info);
|
2007-10-07 00:21:58 +00:00
|
|
|
|
2015-10-26 23:15:40 +00:00
|
|
|
ScHandle = OpenSCManagerW(NULL,
|
|
|
|
NULL,
|
|
|
|
SC_MANAGER_ENUMERATE_SERVICE);
|
|
|
|
if (ScHandle != NULL)
|
2007-08-25 13:41:44 +00:00
|
|
|
{
|
|
|
|
if (!EnumServicesStatusEx(ScHandle,
|
|
|
|
SC_ENUM_PROCESS_INFO,
|
|
|
|
SERVICE_WIN32,
|
|
|
|
SERVICE_STATE_ALL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
&BytesNeeded,
|
2017-04-23 17:39:26 +00:00
|
|
|
&NumServices,
|
2007-08-25 13:41:44 +00:00
|
|
|
&ResumeHandle,
|
|
|
|
0))
|
|
|
|
{
|
|
|
|
/* Call function again if required size was returned */
|
|
|
|
if (GetLastError() == ERROR_MORE_DATA)
|
|
|
|
{
|
|
|
|
/* reserve memory for service info array */
|
2017-04-23 17:39:26 +00:00
|
|
|
pServices = (ENUM_SERVICE_STATUS_PROCESS *)HeapAlloc(ProcessHeap,
|
|
|
|
0,
|
|
|
|
BytesNeeded);
|
|
|
|
if (pServices)
|
2007-08-25 13:41:44 +00:00
|
|
|
{
|
|
|
|
/* fill array with service info */
|
|
|
|
if (EnumServicesStatusEx(ScHandle,
|
|
|
|
SC_ENUM_PROCESS_INFO,
|
|
|
|
SERVICE_WIN32,
|
|
|
|
SERVICE_STATE_ALL,
|
2017-04-23 17:39:26 +00:00
|
|
|
(LPBYTE)pServices,
|
2007-08-25 13:41:44 +00:00
|
|
|
BytesNeeded,
|
|
|
|
&BytesNeeded,
|
2017-04-23 17:39:26 +00:00
|
|
|
&NumServices,
|
2007-08-25 13:41:44 +00:00
|
|
|
&ResumeHandle,
|
|
|
|
0))
|
|
|
|
{
|
|
|
|
bRet = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ScHandle)
|
|
|
|
CloseServiceHandle(ScHandle);
|
|
|
|
|
2017-04-23 17:39:26 +00:00
|
|
|
Info->pAllServices = (ENUM_SERVICE_STATUS_PROCESS *)HeapAlloc(ProcessHeap,
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
NumServices * sizeof(ENUM_SERVICE_STATUS_PROCESS));
|
|
|
|
if (Info->pAllServices != NULL)
|
2007-08-25 13:41:44 +00:00
|
|
|
{
|
2017-04-23 17:39:26 +00:00
|
|
|
Info->NumServices = NumServices;
|
|
|
|
|
|
|
|
for (i = 0; i < NumServices; i++)
|
|
|
|
{
|
|
|
|
Info->pAllServices[i].lpServiceName = HeapAlloc(ProcessHeap,
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
(wcslen(pServices[i].lpServiceName) + 1) * sizeof(WCHAR));
|
|
|
|
if (Info->pAllServices[i].lpServiceName)
|
|
|
|
wcscpy(Info->pAllServices[i].lpServiceName, pServices[i].lpServiceName);
|
|
|
|
|
|
|
|
Info->pAllServices[i].lpDisplayName = HeapAlloc(ProcessHeap,
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
(wcslen(pServices[i].lpDisplayName) + 1) * sizeof(WCHAR));
|
|
|
|
if (Info->pAllServices[i].lpDisplayName)
|
|
|
|
wcscpy(Info->pAllServices[i].lpDisplayName, pServices[i].lpDisplayName);
|
|
|
|
|
|
|
|
CopyMemory(&Info->pAllServices[i].ServiceStatusProcess,
|
|
|
|
&pServices[i].ServiceStatusProcess,
|
|
|
|
sizeof(SERVICE_STATUS_PROCESS));
|
|
|
|
}
|
2007-08-25 13:41:44 +00:00
|
|
|
}
|
|
|
|
|
2017-04-23 17:39:26 +00:00
|
|
|
if (pServices)
|
|
|
|
HeapFree(ProcessHeap, 0, pServices);
|
|
|
|
|
2007-08-25 13:41:44 +00:00
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
2007-08-27 19:31:09 +00:00
|
|
|
BOOL
|
|
|
|
UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService)
|
|
|
|
{
|
|
|
|
SC_HANDLE hScm;
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
|
2015-10-26 23:15:40 +00:00
|
|
|
hScm = OpenSCManagerW(NULL,
|
|
|
|
NULL,
|
|
|
|
SC_MANAGER_ENUMERATE_SERVICE);
|
|
|
|
if (hScm != NULL)
|
2007-08-27 19:31:09 +00:00
|
|
|
{
|
|
|
|
SC_HANDLE hService;
|
|
|
|
|
2015-10-26 23:15:40 +00:00
|
|
|
hService = OpenServiceW(hScm,
|
|
|
|
pService->lpServiceName,
|
|
|
|
SERVICE_QUERY_STATUS);
|
2007-08-27 19:31:09 +00:00
|
|
|
if (hService)
|
|
|
|
{
|
|
|
|
DWORD size;
|
|
|
|
|
|
|
|
QueryServiceStatusEx(hService,
|
|
|
|
SC_STATUS_PROCESS_INFO,
|
|
|
|
(LPBYTE)&pService->ServiceStatusProcess,
|
2008-10-18 11:49:25 +00:00
|
|
|
sizeof(SERVICE_STATUS_PROCESS),
|
2007-08-27 19:31:09 +00:00
|
|
|
&size);
|
|
|
|
|
2008-10-18 11:49:25 +00:00
|
|
|
CloseServiceHandle(hService);
|
2007-08-27 19:31:09 +00:00
|
|
|
bRet = TRUE;
|
|
|
|
}
|
2008-10-18 11:49:25 +00:00
|
|
|
|
|
|
|
CloseServiceHandle(hScm);
|
2007-08-27 19:31:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return bRet;
|
|
|
|
}
|