host/common/win32/service.cpp (871 lines of code) (raw):
#include "service.h"
#ifndef _WINDOWS_
#include <Windows.h>
#endif
#include <winbase.h>
#include <winsvc.h>
#include <tchar.h>
#include <sstream>
#include "portable.h"
#include "portablehelpers.h"
SVERROR isServiceInstalled(const std::string& serviceName, InmServiceStatus& status)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
status = INM_SVCSTAT_NONE ;
SVERROR bRet = SVS_FALSE ;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM != NULL)
{
SC_HANDLE hService = ::OpenService(hSCM, serviceName.c_str(),SERVICE_ALL_ACCESS);
bRet = SVS_OK ;
if (hService != NULL)
{
DebugPrintf(SV_LOG_DEBUG, "Service %s is installed on the machine\n", serviceName.c_str()) ;
status = INM_SVCSTAT_INSTALLED ;
::CloseServiceHandle(hService);
}
else
{
status = INM_SVCSTAT_NOTINSTALLED ;
DebugPrintf(SV_LOG_DEBUG, "Service %s is not installed on the machine\n", serviceName.c_str()) ;
}
::CloseServiceHandle(hSCM);
}
else
{
DebugPrintf(SV_LOG_ERROR, "::OpenSCManager Failed %d\n", GetLastError()) ;
throw "::OpenSCManager Failed\n" ;
}
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet ;
}
SVERROR getServiceStatus(const std::string& serviceName, InmServiceStatus& status)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SVERROR bRet = SVS_FALSE ;
DWORD dwBytesNeeded = 0 ;
status = INM_SVCSTAT_NONE ;
SERVICE_STATUS_PROCESS ssStatus;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM != NULL)
{
SC_HANDLE hService = ::OpenService(hSCM, serviceName.c_str(),SERVICE_ALL_ACCESS);
if (hService != NULL)
{
status = INM_SVCSTAT_INSTALLED ;
DebugPrintf(SV_LOG_DEBUG, "Service %s is installed on the machine\n", serviceName.c_str()) ;
if (!QueryServiceStatusEx(hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE) &ssStatus,
sizeof(SERVICE_STATUS_PROCESS),
&dwBytesNeeded ) )
{
DebugPrintf(SV_LOG_ERROR, "QueryServiceStatusEx failed %d\n", GetLastError());
}
else
{
bRet = SVS_OK ;
switch(ssStatus.dwCurrentState)
{
case SERVICE_STOPPED :
DebugPrintf(SV_LOG_DEBUG, "Service %s is stopped on the machine\n", serviceName.c_str()) ;
status = INM_SVCSTAT_STOPPED ;
break ;
case SERVICE_START_PENDING :
DebugPrintf(SV_LOG_DEBUG, "Service %s is start pending on the machine\n", serviceName.c_str()) ;
status = INM_SVCSTAT_START_PENDING ;
break ;
case SERVICE_STOP_PENDING :
DebugPrintf(SV_LOG_DEBUG, "Service %s is stop pending on the machine\n", serviceName.c_str()) ;
status = INM_SVCSTAT_STOP_PENDING ;
break ;
case SERVICE_RUNNING :
DebugPrintf(SV_LOG_DEBUG, "Service %s is running on the machine\n", serviceName.c_str()) ;
status = INM_SVCSTAT_RUNNING ;
break ;
case SERVICE_CONTINUE_PENDING :
DebugPrintf(SV_LOG_DEBUG, "Service %s is continue pending on the machine\n", serviceName.c_str()) ;
status = INM_SVCSTAT_CONTINUE_PENDING ;
break ;
case SERVICE_PAUSE_PENDING :
DebugPrintf(SV_LOG_DEBUG, "Service %s is pause pending on the machine\n", serviceName.c_str()) ;
status = INM_SVCSTAT_PAUSE_PENDING ;
break ;
case SERVICE_PAUSED :
DebugPrintf(SV_LOG_DEBUG, "Service %s is paused on the machine\n", serviceName.c_str()) ;
status = INM_SVCSTAT_PAUSED ;
break ;
default:
status = INM_SVCSTAT_NONE ;
}
}
::CloseServiceHandle(hService);
}
else
{
DebugPrintf(SV_LOG_DEBUG, "Service %s is not installed on the machine\n", serviceName.c_str()) ;
status = INM_SVCSTAT_NOTINSTALLED ;
}
::CloseServiceHandle(hSCM);
}
else
{
DebugPrintf(SV_LOG_ERROR, "::OpenSCManager Failed %d\n", GetLastError()) ;
}
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet ;
}
SVERROR StopSvc(const std::string& svcName)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SVERROR bRet = SVS_FALSE ;
SC_HANDLE schService;
SERVICE_STATUS_PROCESS serviceStatusProcess;
DWORD actualSize = 0;
SERVICE_STATUS serviceStatus ;
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager)
{
schService = OpenService(schSCManager, svcName.c_str(), SERVICE_ALL_ACCESS);
if (NULL != schService)
{
if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&serviceStatusProcess, sizeof(serviceStatusProcess), &actualSize) && SERVICE_RUNNING == serviceStatusProcess.dwCurrentState)
{
if (ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus))
{
do
{
Sleep(1000);
} while (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&serviceStatusProcess, sizeof(serviceStatusProcess), &actualSize) && SERVICE_STOPPED != serviceStatusProcess.dwCurrentState);
bRet = SVS_OK ;
}
else
{
DebugPrintf(SV_LOG_ERROR, "Unable to stop the service %s. Error %ld\n", svcName.c_str(), GetLastError()) ;
bRet = SVS_FALSE ;
}
}
else
{
DebugPrintf(SV_LOG_INFO,"\n Service %s is not running ",svcName.c_str());
bRet = SVS_OK;
}
CloseServiceHandle(schService);
}
}
CloseServiceHandle(schSCManager);
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet ;
}
SVERROR StartSvc(const std::string& svcName)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SC_HANDLE schService;
SVERROR bRet = SVS_FALSE ;
SERVICE_STATUS_PROCESS serviceStatusProcess;
DWORD actualSize = 0;
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager)
{
schService = OpenService(schSCManager, svcName.c_str(), SERVICE_ALL_ACCESS);
if (NULL != schService)
{
if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&serviceStatusProcess, sizeof(serviceStatusProcess), &actualSize) && SERVICE_RUNNING != serviceStatusProcess.dwCurrentState)
{
if( !StartService(schService, 0, NULL) )
{
DebugPrintf(SV_LOG_ERROR, "Unable to start the service %s. Error %ld\n", svcName.c_str(), GetLastError()) ;
bRet = SVS_FALSE ;
}
else
{
DebugPrintf(SV_LOG_INFO, "Waiting for the service %s to start ...\n", svcName.c_str()) ;
int nSec = 0;
bRet = SVS_OK;
do
{
if(120 == nSec)
{
DebugPrintf(SV_LOG_ERROR, "Service %s is not responding.\n", svcName.c_str()) ;
bRet = SVS_FALSE;
break;
}
Sleep(1000);
nSec++;
} while (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&serviceStatusProcess, sizeof(serviceStatusProcess), &actualSize) && SERVICE_RUNNING != serviceStatusProcess.dwCurrentState);
}
}
else
{
if(SERVICE_RUNNING == serviceStatusProcess.dwCurrentState)
{
DebugPrintf(SV_LOG_INFO, "%s is already in running state\n", svcName.c_str());
bRet = SVS_OK;
}
else
{
DebugPrintf(SV_LOG_ERROR, "Failed in QueryServiceStatusEx, Unable to start the service %s. Error %ld\n", svcName.c_str(), GetLastError());
}
}
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet ;
}
SVERROR StrService(const std::string& svcName)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SVERROR bRet = SVS_OK;
DebugPrintf(SV_LOG_INFO, "Going to Start the Service %s\n", svcName.c_str());
if( StartSvc(svcName) == SVS_FALSE)
{
DebugPrintf(SV_LOG_ERROR, "Failed to start the service %s.\n", svcName.c_str()) ;
bRet = SVS_FALSE ;
}
else if(FindDependentServicesAndStart(svcName.c_str()) == SVS_FALSE)
{
DebugPrintf(SV_LOG_ERROR, "Failed while starting the dependent service of the service %s.\n", svcName.c_str()) ;
}
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet;
}
SVERROR StpService(const std::string& svcName)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SVERROR bRet = SVS_OK;
DebugPrintf(SV_LOG_INFO, "Going to stop the service %s\n", svcName.c_str());
std::vector<std::string> vecDependentSvcNames;
if( FindDependentServicesAndStop(svcName.c_str(), vecDependentSvcNames) == SVS_FALSE )
{
DebugPrintf(SV_LOG_ERROR, "Failed while stopping the dependent service of the service %s.\n", svcName.c_str()) ;
}
if( StopSvc(svcName) == SVS_FALSE)
{
DebugPrintf(SV_LOG_ERROR, "Failed to stop the service %s.\n", svcName.c_str()) ;
bRet = SVS_FALSE;
}
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet;
}
SVERROR ReStartSvc(const std::string& svcName)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SC_HANDLE schService;
SVERROR bRet = SVS_FALSE ;
SERVICE_STATUS_PROCESS serviceStatusProcess;
DWORD actualSize = 0;
std::vector<std::string> vecDependentSvcNames;
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager)
{
schService = OpenService(schSCManager, svcName.c_str(), SERVICE_ALL_ACCESS);
if (NULL != schService)
{
if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&serviceStatusProcess, sizeof(serviceStatusProcess), &actualSize) && SERVICE_RUNNING != serviceStatusProcess.dwCurrentState)
{
DebugPrintf(SV_LOG_INFO, "%s is in stopped state, Going to Start the Service\n", svcName.c_str());
if( StartSvc(svcName) == SVS_FALSE)
{
DebugPrintf(SV_LOG_ERROR, "Failed to start the service %s.\n", svcName.c_str()) ;
bRet = SVS_FALSE ;
}
else
{
bRet = SVS_OK;
}
if(FindDependentServicesAndStart(svcName.c_str()) == SVS_FALSE)
{
DebugPrintf(SV_LOG_ERROR, "Failed while starting the dependent service of the service %s.\n", svcName.c_str()) ;
}
}
else
{
if(SERVICE_RUNNING == serviceStatusProcess.dwCurrentState)
{
DebugPrintf(SV_LOG_INFO, "%s is in running state, Going to Re-Start the Server\n", svcName.c_str());
if( FindDependentServicesAndStop(svcName.c_str(), vecDependentSvcNames) == SVS_FALSE )
{
DebugPrintf(SV_LOG_ERROR, "Failed while stopping the dependent service of the service %s.\n", svcName.c_str()) ;
}
if( StopSvc(svcName) == SVS_FALSE)
{
DebugPrintf(SV_LOG_ERROR, "Failed to stop the service %s.\n", svcName.c_str()) ;
bRet = SVS_FALSE;
}
if( StartSvc(svcName) == SVS_OK)
{
//Start all the dependent services which are stopped during Restart
if(!vecDependentSvcNames.empty())
{
std::reverse(vecDependentSvcNames.begin(),vecDependentSvcNames.end());
std::vector<std::string>::iterator iter = vecDependentSvcNames.begin();
while(iter != vecDependentSvcNames.end())
{
if( StartSvc(*iter) == SVS_FALSE)
{
DebugPrintf(SV_LOG_ERROR, "Failed to start the service %s.\n", (*iter).c_str()) ;
}
iter++;
}
}
bRet = SVS_OK;
}
else
{
DebugPrintf(SV_LOG_ERROR, "Failed to start the service %s.\n", svcName.c_str()) ;
bRet = SVS_FALSE;
}
}
else
{
DebugPrintf(SV_LOG_ERROR, "Failed in QueryServiceStatusEx, Unable to start the service %s. Error %ld\n", svcName.c_str(), GetLastError());
bRet = SVS_FALSE ;
}
}
}
else
{
DebugPrintf(SV_LOG_ERROR, "Failed in getting the handle on the service %s. Error %ld\n", svcName.c_str(), GetLastError());
bRet = SVS_FALSE ;
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet ;
}
SVERROR FindDependentServicesAndStop(const std::string& svcName, std::vector<std::string>& vecDependentSvcNames)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SC_HANDLE schService = NULL;
LPENUM_SERVICE_STATUS serviceStatus = NULL;
BOOL bFlag = TRUE;
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if (schSCManager)
{
DWORD bufferSize;
schService = OpenService(schSCManager, svcName.c_str(), SERVICE_STOP|SERVICE_QUERY_STATUS |SERVICE_ENUMERATE_DEPENDENTS);
if(schService)
{
DWORD dwRequriedBuffer;
DWORD dwServicesReturned = NULL;
//Enumerate dependent services.
EnumDependentServices( schService, SERVICE_STATE_ALL, serviceStatus, 0, &dwRequriedBuffer, &dwServicesReturned);
if(GetLastError() == ERROR_MORE_DATA)
{
serviceStatus = (LPENUM_SERVICE_STATUS)new BYTE[1024+1];
bufferSize = dwRequriedBuffer;
if(EnumDependentServices( schService, SERVICE_STATE_ALL, (LPENUM_SERVICE_STATUS)serviceStatus, bufferSize , &dwRequriedBuffer, &dwServicesReturned))
{
for(DWORD dwCount = 0; dwCount < dwServicesReturned; dwCount++)
{
if((serviceStatus[dwCount].ServiceStatus.dwCurrentState) == SERVICE_STOPPED)
{
DebugPrintf(SV_LOG_DEBUG, " %s Service is in stopped state\n", serviceStatus[dwCount].lpServiceName);
continue;
}
FindDependentServicesAndStop(serviceStatus[dwCount].lpServiceName, vecDependentSvcNames);
//push the already stopped dependent service into vector(vecStoppedServicesNames).
vecDependentSvcNames.push_back(serviceStatus[dwCount].lpServiceName);
if(StopSvc(serviceStatus[dwCount].lpServiceName) == SVS_FALSE)
{
bFlag = FALSE;
break;
}
}
}
else
{
DebugPrintf(SV_LOG_ERROR, "Failed to enumerate dependent services Error:[%d]\n",GetLastError());
bFlag = FALSE;
}
}
if(serviceStatus)
{
delete []serviceStatus;
}
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
if(FALSE == bFlag)
return SVS_FALSE;
return SVS_OK;
}
SVERROR FindDependentServicesAndStart(const std::string& svcName)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SC_HANDLE schService = NULL;
LPENUM_SERVICE_STATUS serviceStatus = NULL;
BOOL bFlag = TRUE;
SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if (schSCManager)
{
DWORD bufferSize;
schService = OpenService(schSCManager, svcName.c_str(), SERVICE_START |SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
if(schService)
{
DWORD dwRequriedBuffer;
DWORD dwServicesReturned = NULL;
//Enumerate dependent services.
EnumDependentServices( schService, SERVICE_STATE_ALL, serviceStatus, 0, &dwRequriedBuffer, &dwServicesReturned);
if(GetLastError() == ERROR_MORE_DATA)
{
serviceStatus = (LPENUM_SERVICE_STATUS)new BYTE[1024+1];
bufferSize = dwRequriedBuffer;
if(EnumDependentServices( schService, SERVICE_STATE_ALL, (LPENUM_SERVICE_STATUS)serviceStatus, bufferSize , &dwRequriedBuffer, &dwServicesReturned))
{
for(DWORD dwCount = 0; dwCount < dwServicesReturned; dwCount++)
{
FindDependentServicesAndStart(serviceStatus[dwCount].lpServiceName);
if((serviceStatus[dwCount].ServiceStatus.dwCurrentState) == SERVICE_RUNNING)
{
DebugPrintf(SV_LOG_DEBUG, " %s Service is in running state\n", serviceStatus[dwCount].lpServiceName);
continue;
}
if(StartSvc(serviceStatus[dwCount].lpServiceName) == SVS_FALSE)
{
bFlag = FALSE;
break;
}
}
}
else
{
DebugPrintf(SV_LOG_ERROR, "Failed to enumerate dependent services Error:[%d]\n",GetLastError());
bFlag = FALSE;
}
}
if(serviceStatus)
{
delete []serviceStatus;
}
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
if(FALSE == bFlag)
return SVS_FALSE;
return SVS_OK;
}
SVERROR StopService(const std::string& svcName, SV_UINT timeout)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SVERROR bRet = SVS_FALSE ;
SC_HANDLE schService;
SERVICE_STATUS_PROCESS serviceStatusProcess;
DWORD actualSize = 0;
SERVICE_STATUS serviceStatus ;
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager)
{
schService = OpenService(schSCManager, svcName.c_str(), SERVICE_ALL_ACCESS);
if (NULL != schService) {
if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&serviceStatusProcess, sizeof(serviceStatusProcess), &actualSize) && SERVICE_RUNNING == serviceStatusProcess.dwCurrentState) {
if (ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus))
{
SV_UINT waitTime = 0 ;
do
{ if( timeout != 0 )
{
waitTime++ ;
if( waitTime > timeout )
{
break ;
}
}
Sleep(1000);
} while (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&serviceStatusProcess, sizeof(serviceStatusProcess), &actualSize) && SERVICE_STOPPED != serviceStatusProcess.dwCurrentState);
if( QueryServiceStatusEx(schService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&serviceStatusProcess,
sizeof(serviceStatusProcess), &actualSize) &&
SERVICE_STOPPED == serviceStatusProcess.dwCurrentState)
{
bRet = SVS_OK ;
}
}
}
else
{
DebugPrintf(SV_LOG_INFO,"\n Service %s is not running ",svcName.c_str());
bRet = SVS_OK;
}
CloseServiceHandle(schService);
}
}
CloseServiceHandle(schSCManager);
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet ;
}
bool getStartServiceType(const std::string& svcName, InmServiceStartType &serviceType , std::string &serviceStartUpType)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SC_HANDLE schSCManager;
SC_HANDLE schService;
bool bRet = false ;
LPQUERY_SERVICE_CONFIG lpqscBuf;
char szStartType[255];
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if(schSCManager)
{
schService = OpenService(
schSCManager, // SCM database
svcName.c_str(), // name of service
SERVICE_ALL_ACCESS);
if (NULL != schService )
{
lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 4096);
DWORD dwBytesNeeded;
if (! QueryServiceConfig( schService, lpqscBuf, 4096, &dwBytesNeeded) )
{
DebugPrintf(SV_LOG_ERROR,"QueryServiceConfig() failed with Error code :%d \n",GetLastError());
}
else
{
//Get the current services startup type
switch(lpqscBuf->dwStartType)
{
case SERVICE_AUTO_START:
serviceType = INM_SVCTYPE_AUTO ;
serviceStartUpType = "Automatic";
bRet = true;
break;
case SERVICE_DEMAND_START:
serviceType = INM_SVCTYPE_MANUAL ;
serviceStartUpType = "Manual";
bRet = true;
break;
case SERVICE_DISABLED :
serviceType = INM_SVCTYPE_DISABLED ;
serviceStartUpType = "Disabled";
bRet = true;
break;
}
}
if ( lpqscBuf != NULL )
{
LocalFree (lpqscBuf);
}
CloseServiceHandle(schService);
}
else
{
DebugPrintf(SV_LOG_ERROR,"OpenService() failed with Error code :%d \n ",GetLastError());
}
CloseServiceHandle(schSCManager);
}
else
{
DebugPrintf(SV_LOG_ERROR,"OpenSCManager() failed with Error code :%d \n ",GetLastError());
}
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet ;
}
SVERROR changeServiceType(const std::string& svcName, InmServiceStartType serviceType)
{
DebugPrintf(SV_LOG_DEBUG, "ENTERED %s\n", FUNCTION_NAME) ;
SC_HANDLE schSCManager;
SC_HANDLE schService;
SVERROR bRet = SVS_FALSE ;
DWORD dwServiceType ;
bool isProperType = true ;
switch( serviceType )
{
case INM_SVCTYPE_MANUAL :
dwServiceType = SERVICE_DEMAND_START ;
break ;
case INM_SVCTYPE_DISABLED :
dwServiceType = SERVICE_DISABLED ;
break ;
case INM_SVCTYPE_AUTO :
dwServiceType = SERVICE_AUTO_START ;
break ;
default :
isProperType = false ;
}
if( isProperType )
{
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if(schSCManager)
{
schService = OpenService(
schSCManager, // SCM database
svcName.c_str(), // name of service
SERVICE_CHANGE_CONFIG); // need change config access
if (NULL != schService )
{
// Change the service start type.
if (! ChangeServiceConfig(
schService, // handle of service
SERVICE_NO_CHANGE, // service type: no change
dwServiceType, // service start type
SERVICE_NO_CHANGE, // error control: no change
NULL, // binary path: no change
NULL, // load order group: no change
NULL, // tag ID: no change
NULL, // dependencies: no change
NULL, // account name: no change
NULL, // password: no change
NULL) ) // display name: no change
{
DebugPrintf(SV_LOG_ERROR, "ChangeServiceConfig failed (%d)\n", GetLastError());
}
else
{
DebugPrintf(SV_LOG_ERROR, "ChangeServiceConfig succeeded\n");
bRet = SVS_OK;
}
}
else
{
DebugPrintf(SV_LOG_ERROR,"openservice() failed with Error code :%d\n",GetLastError());
}
}
else
{
DebugPrintf(SV_LOG_DEBUG,"OpenSCManager() failed with Error code :%d\n",GetLastError());
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
DebugPrintf(SV_LOG_DEBUG, "EXITED %s\n", FUNCTION_NAME) ;
return bRet ;
}
void TestServiceFunctions()
{
InmServiceStatus status_;
isServiceInstalled("AGT", status_);
isServiceInstalled("AppMgmt", status_);
getServiceStatus("AppMgmt", status_) ;
}
SVERROR QuerySvcConfig(InmService& svc)
{
SC_HANDLE schSCManager = NULL ;
SC_HANDLE schService = NULL ;
LPQUERY_SERVICE_CONFIG lpsc = NULL ;
LPSERVICE_DESCRIPTION lpsd = NULL ;
DWORD dwBytesNeeded = 0 ;
DWORD cbBufSize = 0 ;
DWORD dwError = 0 ;
SVERROR bRet = SVS_FALSE ;
svc.m_svcStartType = INM_SVCTYPE_NONE ;
svc.m_svcStatus = INM_SVCSTAT_NONE ;
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL != schSCManager)
{
DebugPrintf(SV_LOG_DEBUG, "Opened scmanager\n");
schService = OpenService(
schSCManager, // SCM database
svc.m_serviceName.c_str(), // name of service
SERVICE_QUERY_CONFIG); // need query config access
if (schService != NULL)
{
DebugPrintf(SV_LOG_DEBUG, "Opened handle to service %s\n", svc.m_serviceName.c_str());
if( !QueryServiceConfig(
schService,
NULL,
0,
&dwBytesNeeded))
{
dwError = GetLastError();
if( ERROR_INSUFFICIENT_BUFFER == dwError )
{
cbBufSize = dwBytesNeeded;
lpsc = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LMEM_FIXED, cbBufSize);
}
if( QueryServiceConfig(
schService,
lpsc,
cbBufSize,
&dwBytesNeeded) )
{
if( !QueryServiceConfig2(
schService,
SERVICE_CONFIG_DESCRIPTION,
NULL,
0,
&dwBytesNeeded))
{
dwError = GetLastError();
if( ERROR_INSUFFICIENT_BUFFER == dwError )
{
cbBufSize = dwBytesNeeded;
lpsd = (LPSERVICE_DESCRIPTION) LocalAlloc(LMEM_FIXED, cbBufSize);
}
if (QueryServiceConfig2(
schService,
SERVICE_CONFIG_DESCRIPTION,
(LPBYTE) lpsd,
cbBufSize,
&dwBytesNeeded) )
{
switch( lpsc->dwStartType )
{
case SERVICE_AUTO_START :
svc.m_svcStartType = INM_SVCTYPE_AUTO ;
break ;
case SERVICE_BOOT_START :
svc.m_svcStartType = INM_SVCTYPE_AUTO ;
break ;
case SERVICE_DEMAND_START :
svc.m_svcStartType = INM_SVCTYPE_MANUAL ;
break ;
case SERVICE_DISABLED :
svc.m_svcStartType = INM_SVCTYPE_DISABLED ;
break ;
case SERVICE_SYSTEM_START :
svc.m_svcStartType = INM_SVCTYPE_AUTO ;
break ;
default :
svc.m_svcStartType = INM_SVCTYPE_NONE ;
break ;
}
svc.m_binPathName = lpsc->lpBinaryPathName ;
svc.m_logonUser = lpsc->lpServiceStartName ;
svc.m_displayName = lpsc->lpDisplayName ;
if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0)
{
svc.m_discription = lpsd->lpDescription ;
}
if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0)
{
svc.m_dependencies = lpsc->lpDependencies ;
}
getServiceStatus(svc.m_serviceName, svc.m_svcStatus) ;
DebugPrintf(SV_LOG_DEBUG, "SvcName : %s\n", svc.m_serviceName.c_str()) ;
DebugPrintf(SV_LOG_DEBUG, "svcStartUpType : %s\n", svc.typeAsStr().c_str()) ;
DebugPrintf(SV_LOG_DEBUG, "SvcStatus : %s\n", svc.statusAsStr().c_str()) ;
DebugPrintf(SV_LOG_DEBUG, "SvcDescription : %s\n", svc.m_discription.c_str()) ;
DebugPrintf(SV_LOG_DEBUG, "SvcLogonUser : %s\n", svc.m_logonUser.c_str()) ;
DebugPrintf(SV_LOG_DEBUG, "SvcBinPath : %s\n", svc.m_binPathName.c_str()) ;
DebugPrintf(SV_LOG_DEBUG, "SvcDepedencies : %s\n", svc.m_dependencies.c_str()) ;
bRet = SVS_OK ;
}
}
}
}
CloseServiceHandle(schService);
}
else
{
DWORD err = GetLastError();
std::stringstream sserr;
sserr << err;
DebugPrintf(SV_LOG_DEBUG, "Failed to open handle to service %s with error %s\n", svc.m_serviceName.c_str(), sserr.str().c_str());
svc.m_svcStatus = INM_SVCSTAT_NOTINSTALLED ;
}
CloseServiceHandle(schSCManager);
}
else
{
DWORD err = GetLastError();
std::stringstream sserr;
sserr << err;
DebugPrintf(SV_LOG_ERROR, "Failed to open scmanager with error %s\n", sserr.str().c_str());
}
if( lpsc != NULL )
{
LocalFree(lpsc);
}
if( lpsd != NULL )
{
LocalFree(lpsd);
}
return bRet ;
}
InmService::InmService(const std::string& servicename)
{
m_serviceName = servicename ;
}
InmService::InmService(const InmServiceStatus &status)
{
m_svcStatus = status;
}
std::string InmService::statusAsStr() const
{
switch( m_svcStatus )
{
case INM_SVCSTAT_NONE :
return "Unknown" ;
break ;
case INM_SVCSTAT_NOTINSTALLED :
return "Not Installed" ;
break ;
case INM_SVCSTAT_INSTALLED :
return "Installed" ;
break ;
case INM_SVCSTAT_STOPPED :
return "Not Running" ;
break ;
case INM_SVCSTAT_START_PENDING :
return "Start Pending" ;
break ;
case INM_SVCSTAT_STOP_PENDING :
return "Stop Pending" ;
break ;
case INM_SVCSTAT_RUNNING :
return "Running" ;
break ;
case INM_SVCSTAT_CONTINUE_PENDING :
return "Continue Pending" ;
break ;
case INM_SVCSTAT_PAUSE_PENDING :
return "Pause Pending" ;
break ;
case INM_SVCSTAT_PAUSED :
return "Paused" ;
break ;
default :
return "Unknown" ;
break ;
}
}
std::string InmService::typeAsStr() const
{
switch( m_svcStartType )
{
case INM_SVCTYPE_NONE :
return "Unknown" ;
break ;
case INM_SVCTYPE_MANUAL :
return "Manual" ;
break ;
case INM_SVCTYPE_DISABLED :
return "Disabled" ;
break ;
case INM_SVCTYPE_AUTO :
return "Automatic" ;
break ;
default:
return "Unknown" ;
break ;
}
}
std::list<std::pair<std::string, std::string> > InmService::getProperties()
{
std::list<std::pair<std::string, std::string> > properties ;
properties.push_back(std::make_pair("Name", this->m_serviceName)) ;
properties.push_back(std::make_pair("Status", this->statusAsStr())) ;
if( !(this->m_svcStatus == INM_SVCSTAT_NOTINSTALLED ||
this->m_svcStatus == INM_SVCSTAT_ACCESSDENIED ||
this->m_svcStatus == INM_SVCSTAT_NONE) )
{
properties.push_back(std::make_pair("Display Name", this->m_displayName)) ;
properties.push_back(std::make_pair("Discription", this->m_discription)) ;
properties.push_back(std::make_pair("Startup Type", this->typeAsStr())) ;
properties.push_back(std::make_pair("Log On User", this->m_logonUser)) ;
if( ! this->m_dependencies.empty() )
{
properties.push_back(std::make_pair("Dependencies", this->m_dependencies)) ;
}
}
return properties ;
}