reactos/base/applications/mscutils/servman/query.c
Amine Khaldi c424146e2c Create a branch for cmake bringup.
svn path=/branches/cmake-bringup/; revision=48236
2010-07-24 18:52:44 +00:00

373 lines
11 KiB
C

/*
* PROJECT: ReactOS Services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/query.c
* PURPOSE: Query service information
* COPYRIGHT: Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org>
*
*/
#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;
}
LPQUERY_SERVICE_CONFIG
GetServiceConfig(LPTSTR lpServiceName)
{
LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
SC_HANDLE hSCManager;
SC_HANDLE hService;
DWORD dwBytesNeeded;
hSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_ALL_ACCESS);
if (hSCManager)
{
hService = OpenService(hSCManager,
lpServiceName,
SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
if (hService)
{
if (!QueryServiceConfig(hService,
NULL,
0,
&dwBytesNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
lpServiceConfig = (LPQUERY_SERVICE_CONFIG)HeapAlloc(GetProcessHeap(),
0,
dwBytesNeeded);
if (lpServiceConfig)
{
if (!QueryServiceConfig(hService,
lpServiceConfig,
dwBytesNeeded,
&dwBytesNeeded))
{
HeapFree(GetProcessHeap(),
0,
lpServiceConfig);
lpServiceConfig = NULL;
}
}
}
}
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
}
return lpServiceConfig;
}
BOOL
SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig,
LPTSTR lpServiceName,
LPTSTR lpPassword)
{
SC_HANDLE hSCManager;
SC_HANDLE hSc;
SC_LOCK scLock;
BOOL bRet = FALSE;
hSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_LOCK);
if (hSCManager)
{
scLock = LockServiceDatabase(hSCManager);
if (scLock)
{
hSc = OpenService(hSCManager,
lpServiceName,
SERVICE_CHANGE_CONFIG);
if (hSc)
{
if (ChangeServiceConfig(hSc,
pServiceConfig->dwServiceType,
pServiceConfig->dwStartType,
pServiceConfig->dwErrorControl,
pServiceConfig->lpBinaryPathName,
pServiceConfig->lpLoadOrderGroup,
pServiceConfig->dwTagId ? &pServiceConfig->dwTagId : NULL,
pServiceConfig->lpDependencies,
pServiceConfig->lpServiceStartName,
lpPassword,
pServiceConfig->lpDisplayName))
{
bRet = TRUE;
}
CloseServiceHandle(hSc);
}
UnlockServiceDatabase(scLock);
}
CloseServiceHandle(hSCManager);
}
if (!bRet)
GetError();
return bRet;
}
LPTSTR
GetServiceDescription(LPTSTR lpServiceName)
{
SC_HANDLE hSCManager = NULL;
SC_HANDLE hSc = NULL;
SERVICE_DESCRIPTION *pServiceDescription = NULL;
LPTSTR lpDescription = NULL;
DWORD BytesNeeded = 0;
DWORD dwSize;
hSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_ENUMERATE_SERVICE);
if (hSCManager == NULL)
{
GetError();
return NULL;
}
hSc = OpenService(hSCManager,
lpServiceName,
SERVICE_QUERY_CONFIG);
if (hSc)
{
if (!QueryServiceConfig2(hSc,
SERVICE_CONFIG_DESCRIPTION,
NULL,
0,
&BytesNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
pServiceDescription = (SERVICE_DESCRIPTION *) HeapAlloc(ProcessHeap,
0,
BytesNeeded);
if (pServiceDescription == NULL)
goto cleanup;
if (QueryServiceConfig2(hSc,
SERVICE_CONFIG_DESCRIPTION,
(LPBYTE)pServiceDescription,
BytesNeeded,
&BytesNeeded))
{
if (pServiceDescription->lpDescription)
{
dwSize = _tcslen(pServiceDescription->lpDescription) + 1;
lpDescription = HeapAlloc(ProcessHeap,
0,
dwSize * sizeof(TCHAR));
if (lpDescription)
{
_tcscpy_s(lpDescription,
dwSize,
pServiceDescription->lpDescription);
}
}
}
}
}
}
cleanup:
if (pServiceDescription)
HeapFree(ProcessHeap,
0,
pServiceDescription);
if (hSCManager != NULL)
CloseServiceHandle(hSCManager);
if (hSc != NULL)
CloseServiceHandle(hSc);
return lpDescription;
}
BOOL
SetServiceDescription(LPTSTR lpServiceName,
LPTSTR lpDescription)
{
SC_HANDLE hSCManager;
SC_HANDLE hSc;
SC_LOCK scLock;
SERVICE_DESCRIPTION ServiceDescription;
BOOL bRet = FALSE;
hSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_LOCK);
if (hSCManager)
{
scLock = LockServiceDatabase(hSCManager);
if (scLock)
{
hSc = OpenService(hSCManager,
lpServiceName,
SERVICE_CHANGE_CONFIG);
if (hSc)
{
ServiceDescription.lpDescription = lpDescription;
if (ChangeServiceConfig2(hSc,
SERVICE_CONFIG_DESCRIPTION,
&ServiceDescription))
{
bRet = TRUE;
}
CloseServiceHandle(hSc);
}
UnlockServiceDatabase(scLock);
}
CloseServiceHandle(hSCManager);
}
if (!bRet)
GetError();
return bRet;
}
BOOL
GetServiceList(PMAIN_WND_INFO Info,
DWORD *NumServices)
{
SC_HANDLE ScHandle;
BOOL bRet = FALSE;
DWORD BytesNeeded = 0;
DWORD ResumeHandle = 0;
*NumServices = 0;
if (Info->pAllServices != NULL)
{
HeapFree(ProcessHeap,
0,
Info->pAllServices);
}
ScHandle = OpenSCManager(NULL,
NULL,
SC_MANAGER_ENUMERATE_SERVICE);
if (ScHandle != INVALID_HANDLE_VALUE)
{
if (!EnumServicesStatusEx(ScHandle,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
SERVICE_STATE_ALL,
NULL,
0,
&BytesNeeded,
NumServices,
&ResumeHandle,
0))
{
/* Call function again if required size was returned */
if (GetLastError() == ERROR_MORE_DATA)
{
/* reserve memory for service info array */
Info->pAllServices = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(ProcessHeap,
0,
BytesNeeded);
if (Info->pAllServices)
{
/* fill array with service info */
if (EnumServicesStatusEx(ScHandle,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
SERVICE_STATE_ALL,
(LPBYTE)Info->pAllServices,
BytesNeeded,
&BytesNeeded,
NumServices,
&ResumeHandle,
0))
{
bRet = TRUE;
}
}
}
}
}
if (ScHandle)
CloseServiceHandle(ScHandle);
if (!bRet)
{
HeapFree(ProcessHeap,
0,
Info->pAllServices);
}
return bRet;
}
BOOL
UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService)
{
SC_HANDLE hScm;
BOOL bRet = FALSE;
hScm = OpenSCManager(NULL,
NULL,
SC_MANAGER_ENUMERATE_SERVICE);
if (hScm != INVALID_HANDLE_VALUE)
{
SC_HANDLE hService;
hService = OpenService(hScm,
pService->lpServiceName,
SERVICE_QUERY_STATUS);
if (hService)
{
DWORD size;
QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&pService->ServiceStatusProcess,
sizeof(SERVICE_STATUS_PROCESS),
&size);
CloseServiceHandle(hService);
bRet = TRUE;
}
CloseServiceHandle(hScm);
}
return bRet;
}