| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594 |
- #include "stdafx2.h"
- #include "SrvManager.h"
- CRITICAL_SECTION s_cs;
- CSvcManager* CSvcManager::m_pInstance = new CSvcManager();
- CSvcManager::CSvcManager(void)
- :m_schSCManager(NULL),
- m_bInit(FALSE)
- {
- memset(m_LastErrInfo.szErrMsg, '\0', sizeof(CHAR)*MAX_ERR_MSG_SIZE);
- m_LastErrInfo.dwErrMsgLen = 0;
- m_LastErrInfo.dwLastErrCode = 0;
- Init();
- }
- CSvcManager::~CSvcManager(void)
- {
- Release();
- }
- BOOLEAN CSvcManager::Init()
- {
- if(m_bInit == TRUE)
- return TRUE;
- BOOLEAN bCode = TRUE;
- m_schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if (!m_schSCManager)
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("Open SC Manager failed with status %d ", dwErrCode);
- return m_bInit = FALSE;
- }
- CoverLastErrMsg();
- return m_bInit = TRUE;
- }
- BOOLEAN CSvcManager::InstallService(LPCTSTR szSrvName, LPCTSTR szServiceExe)
- {
- SC_HANDLE schService;
- DWORD err;
- //Create a new service object.
- schService = CreateServiceA(m_schSCManager, // handle of service control manager database
- szSrvName, // address of name of service to start
- szSrvName, // address of display name
- SERVICE_ALL_ACCESS, // type of access to service
- SERVICE_KERNEL_DRIVER, // type of service
- SERVICE_DEMAND_START, // when to start service
- SERVICE_ERROR_NORMAL, // severity if service fails to start
- szServiceExe, // address of name of binary file
- NULL, // service does not belong to a group
- NULL, // no tag requested
- NULL, // no dependency names
- NULL, // use LocalSystem account
- NULL // no password for service account
- );
- if (schService == NULL)
- {
- err = GetLastError();
- if (err == ERROR_SERVICE_EXISTS)
- {
- m_LastErrInfo.dwLastErrCode = err;
- SaveLastErrMsg("Warning: Previous instance of the service is existed");
- return TRUE;
- }
- else if (err == ERROR_SERVICE_MARKED_FOR_DELETE)
- {
- SaveLastErrMsg("Previous instance of the service is not fully deleted. Try again...");
- return FALSE;
- }
- else
- {
- m_LastErrInfo.dwLastErrCode = err;
- SaveLastErrMsg("Create Service failed with status ", err);
- return FALSE;
- }
- }
- if (schService)
- {
- CloseServiceHandle(schService);
- }
- CoverLastErrMsg();
- return TRUE;
- }
- BOOLEAN CSvcManager::StartServiceWith(LPCTSTR szSrvName)
- {
- SC_HANDLE schService;
- DWORD errCode;
- schService = OpenServiceA(m_schSCManager, szSrvName, SERVICE_ALL_ACCESS);
- if (schService == NULL)
- {
- errCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = errCode;
- SaveLastErrMsg("Open Service failed with status %d", errCode);
- return FALSE;
- }
- if (!StartServiceA(schService, 0, NULL))
- {
- errCode = GetLastError();
- if (errCode == ERROR_SERVICE_ALREADY_RUNNING)
- {
- SaveLastErrMsg("Service is already running.");
- return TRUE;
- }
- else
- {
- SaveLastErrMsg("Start Service failed with status %d", errCode);
- m_LastErrInfo.dwLastErrCode = errCode;
- return FALSE;
- }
- }
- if (schService)
- {
- CloseServiceHandle(schService);
- }
- CoverLastErrMsg();
- return TRUE;
- }
- BOOLEAN CSvcManager::QueryServiceStatus(LPCTSTR szSrvName, ServiceStatus& status)
- {
- BOOLEAN bCode = TRUE;
- SC_HANDLE schService;
- SERVICE_STATUS_PROCESS ssp;
- DWORD dwStartTime = GetTickCount();
- DWORD dwBytesNeeded;
- DWORD dwTimeout = 30000; // 30-second time-out
- DWORD dwWaitTime;
- status = SERVICE_STATUS_UNKNOWN;
- schService = OpenServiceA(m_schSCManager, szSrvName, SERVICE_QUERY_STATUS);
- if (schService == NULL)
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("Open Service failed with status %d", dwErrCode);
- return FALSE;
- }
- if(!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("QueryServiceStatusEx failed (%d)", dwErrCode);
- CloseServiceHandle(schService);
- return FALSE;
- }
- while(ssp.dwCurrentState == SERVICE_STOP_PENDING
- || ssp.dwCurrentState == SERVICE_CONTINUE_PENDING
- || ssp.dwCurrentState == SERVICE_START_PENDING
- || ssp.dwCurrentState == SERVICE_PAUSE_PENDING)
- {
- SaveLastErrMsg("Service current status is pending...");
- //dwWaitTime = ssp.dwWaitHint / 10;
- //if(dwWaitTime < 1000)
- // dwWaitTime = 1000;
- //else if(dwWaitTime > 10000)
- // dwWaitTime = 10000;
- dwWaitTime = 1500;
- Sleep(dwWaitTime);
- if(!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("QueryServiceStatusEx failed (%d)", dwErrCode);
- CloseServiceHandle(schService);
- return FALSE;
- }
- if(GetTickCount() - dwStartTime > dwTimeout)
- {
- SaveLastErrMsg("Query Service timed out.");
- CloseServiceHandle(schService);
- return FALSE;
- }
- }
-
- if(ssp.dwCurrentState == SERVICE_STOPPED)
- {
- status = SERVICE_STATUS_STOPPED;
- }
- else if(ssp.dwCurrentState == SERVICE_RUNNING)
- {
- status = SERVICE_STATUS_RUNNING;
- }
- else if(ssp.dwCurrentState == SERVICE_PAUSED)
- {
- status = SERVICE_STATUS_PASUSED;
- }
- CloseServiceHandle(schService);
- return TRUE;
- }
- BOOLEAN CSvcManager::RemoveService(LPCTSTR szSrvName)
- {
- SC_HANDLE schService;
- BOOLEAN bCode = TRUE;
- StopService(szSrvName);
- schService = OpenServiceA(m_schSCManager, szSrvName, SERVICE_ALL_ACCESS);
- if (schService == NULL)
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("Open Service failed with status %d", dwErrCode);
- return FALSE;
- }
- if (DeleteService(schService))
- {
- CoverLastErrMsg();
- bCode = TRUE;
- }
- else
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("Delete Service failed with status %d.", dwErrCode);
- bCode = FALSE;
- }
- if (schService)
- {
- CloseServiceHandle(schService);
- }
- return bCode;
- }
- BOOLEAN CSvcManager::Release()
- {
- if(m_bInit)
- {
- CloseServiceHandle(m_schSCManager);
- m_bInit = FALSE;
- m_schSCManager = NULL;
- }
- return m_bInit;
- }
- void CSvcManager::GetLastErrMsg(LastErrorInfo& lastInfo)
- {
- lastInfo.dwLastErrCode = m_LastErrInfo.dwLastErrCode;
- lastInfo.dwErrMsgLen = m_LastErrInfo.dwErrMsgLen;
- memcpy_s(lastInfo.szErrMsg, MAX_ERR_MSG_SIZE,
- m_LastErrInfo.szErrMsg, m_LastErrInfo.dwErrMsgLen+1);
- }
- void CSvcManager::SaveLastErrMsg(LPCTSTR fmt, ...)
- {
- va_list arg;
- va_start(arg, fmt);
- int n = _vscprintf(fmt, arg);
- if(n > 0)
- {
- memset(m_LastErrInfo.szErrMsg, 0, sizeof(CHAR)*MAX_ERR_MSG_SIZE);
- vsprintf_s(m_LastErrInfo.szErrMsg, MAX_ERR_MSG_SIZE, fmt, arg);
- m_LastErrInfo.dwErrMsgLen = n;
- }
- va_end(arg);
- }
- CSvcManager* CSvcManager::GetInstance()
- {
- return m_pInstance;
- }
- BOOLEAN CSvcManager::StopService(LPCTSTR szSrvName)
- {
- SC_HANDLE schService;
- BOOLEAN bCode = TRUE;
- SERVICE_STATUS_PROCESS ssp;
- DWORD dwStartTime = GetTickCount();
- DWORD dwBytesNeeded;
- DWORD dwTimeout = 30000; // 30-second time-out
- DWORD dwWaitTime;
- schService = OpenServiceA(m_schSCManager, szSrvName,
- SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
- if (schService == NULL)
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("Open Service failed with status %d", dwErrCode);
- return FALSE;
- }
- if(!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("QueryServiceStatusEx failed (%d)", dwErrCode);
- bCode = FALSE;
- }
- else
- {
- if(ssp.dwCurrentState == SERVICE_STOPPED)
- {
- m_LastErrInfo.dwLastErrCode = SERVICE_STOPPED;
- SaveLastErrMsg("Service is already stopped.");
- }
- else
- {
- while (ssp.dwCurrentState == SERVICE_STOP_PENDING)
- {
- SaveLastErrMsg("Service stop pending...");
- // Do not wait longer than the wait hint. A good interval is
- // one-tenth of the wait hint but not less than 1 second
- // and not more than 10 seconds.
- //dwWaitTime = ssp.dwWaitHint / 10;
- //if(dwWaitTime < 1000)
- // dwWaitTime = 1000;
- //else if(dwWaitTime > 10000)
- // dwWaitTime = 10000;
-
- dwWaitTime = 1500;
- Sleep(dwWaitTime);
-
- if(!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("QueryServiceStatusEx failed (%d)", dwErrCode);
- CloseServiceHandle(schService);
- return FALSE;
- }
- else
- {
- if(ssp.dwCurrentState == SERVICE_STOPPED)
- {
- m_LastErrInfo.dwLastErrCode = SERVICE_STOPPED;
- SaveLastErrMsg("Service stopped successfully.");
- CloseServiceHandle(schService);
- return TRUE;
- }
- else
- {
- if(GetTickCount() - dwStartTime > dwTimeout)
- {
- SaveLastErrMsg("Service stop timed out.");
- bCode = FALSE;
- break;
- }
- }
- }
- }
- StopDependentServices(szSrvName);
- if(!ControlService(schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp))
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("ControlService failed (%d).", dwErrCode);
- CloseServiceHandle(schService);
- return FALSE;
- }
- else
- {
- while (ssp.dwCurrentState != SERVICE_STOPPED)
- {
- //dwWaitTime = ssp.dwWaitHint / 10;
- //if(dwWaitTime < 1000)
- // dwWaitTime = 1000;
- //else if(dwWaitTime > 10000)
- // dwWaitTime = 10000;
- dwWaitTime = 1500;
- Sleep(dwWaitTime);
- if(!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("QueryServiceStatusEx failed (%d)", dwErrCode);
- CloseServiceHandle(schService);
- return FALSE;
- }
- if(ssp.dwCurrentState == SERVICE_STOPPED)
- {
- break;
- }
- if(GetTickCount() - dwStartTime > dwTimeout)
- {
- SaveLastErrMsg("Wait timed out.");
- bCode = FALSE;
- break;
- }
- }
- if(ssp.dwCurrentState == SERVICE_STOPPED)
- {
- m_LastErrInfo.dwLastErrCode = 0;
- SaveLastErrMsg("Service stopped successfully.");
- bCode = TRUE;
- }
- }
- }
- }
- if (schService)
- {
- CloseServiceHandle(schService);
- }
- return bCode;
- }
- BOOLEAN CSvcManager::StopDependentServices(LPCTSTR szSrvName)
- {
- SC_HANDLE schService;
- DWORD dwBytesNeeded;
- DWORD dwCount;
- DWORD dwWaitTime;
- LPENUM_SERVICE_STATUS lpDependencies = NULL;
- ENUM_SERVICE_STATUS ess;
- SC_HANDLE hDepService;
- SERVICE_STATUS_PROCESS ssp;
- DWORD dwStartTime = GetTickCount();
- DWORD dwTimeout = 30000; // 30-second time-out
- BOOLEAN bCode = TRUE;
- schService = OpenServiceA(m_schSCManager, szSrvName,
- SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
- if (schService == NULL)
- {
- DWORD dwErrCode = GetLastError();
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("Open Service failed with status %d", dwErrCode);
- return FALSE;
- }
- if(EnumDependentServicesA(schService, SERVICE_ACTIVE, lpDependencies, 0, &dwBytesNeeded, &dwCount))
- {
- SaveLastErrMsg("No dependent services.");
- CloseServiceHandle(schService);
- return TRUE;
- }
- DWORD dwErrCode = GetLastError();
- if(dwErrCode != ERROR_MORE_DATA)
- {
- m_LastErrInfo.dwLastErrCode = dwErrCode;
- SaveLastErrMsg("Unexpected error.");
- CloseServiceHandle(schService);
- return FALSE;
- }
- lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded);
- if(!lpDependencies)
- {
- m_LastErrInfo.dwLastErrCode = GetLastError();
- SaveLastErrMsg("HeapAlloc failed.");
- CloseServiceHandle(schService);
- return FALSE;
- }
- __try {
- if(!EnumDependentServicesA(schService, SERVICE_ACTIVE,
- lpDependencies, dwBytesNeeded, &dwBytesNeeded, &dwCount))
- {
- m_LastErrInfo.dwLastErrCode = GetLastError();
- SaveLastErrMsg("EnumDependentServicesA failed.");
- return FALSE;
- }
- for(int idx=0; idx<dwCount; idx++)
- {
- ess = *(lpDependencies + idx);
- hDepService = OpenServiceA(m_schSCManager, ess.lpServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS);
- if(!hDepService)
- {
- m_LastErrInfo.dwLastErrCode = GetLastError();
- SaveLastErrMsg("OpenServiceA about %s failed.", ess.lpDisplayName);
- return FALSE;
- }
- __try {
- if(!ControlService(hDepService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp))
- {
- m_LastErrInfo.dwLastErrCode = GetLastError();
- SaveLastErrMsg("Stop Service %s failed.", ess.lpDisplayName);
- CloseServiceHandle(hDepService);
- CloseServiceHandle(schService);
- return FALSE;
- }
- while(ssp.dwCurrentState != SERVICE_STOPPED)
- {
- //dwWaitTime = ssp.dwWaitHint / 10;
- //if(dwWaitTime < 1000)
- // dwWaitTime = 1000;
- //else if(dwWaitTime > 10000)
- // dwWaitTime = 10000;
- dwWaitTime = 1500;
- Sleep(dwWaitTime);
- if(!QueryServiceStatusEx(hDepService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
- {
- m_LastErrInfo.dwLastErrCode = GetLastError();
- SaveLastErrMsg("Query status of Service %s failed.", ess.lpDisplayName);
- return FALSE;
- }
- if(ssp.dwCurrentState == SERVICE_STOPPED)
- {
- SaveLastErrMsg("Service %s is stopped.", ess.lpDisplayName);
- break;
- }
- if(GetTickCount() - dwStartTime > dwTimeout)
- {
- SaveLastErrMsg("Stop Service %s time out.", ess.lpDisplayName);
- return FALSE;
- }
- }
- }
- __finally
- {
- CloseServiceHandle(hDepService);
- }
- }
- }
- __finally
- {
- HeapFree(GetProcessHeap(), 0, lpDependencies);
- CloseServiceHandle(schService);
- }
- return TRUE;
- }
- BOOLEAN CSvcManager::RaiseUpPrivileges()
- {
- SaveLastErrMsg("RaiseUpPrivileges function is unImplemented.");
- return FALSE;
- }
- BOOLEAN CSvcManager::SetPrivilege(HANDLE hToken, // access token handle
- LPCTSTR lpszPrivilege, // name of privilege to enable/disable
- BOOL bEnablePrivilege // to enable or disable privilege
- )
- {
- TOKEN_PRIVILEGES tp;
- LUID luid;
- if ( !LookupPrivilegeValue(
- NULL, // lookup privilege on local system
- lpszPrivilege, // privilege to lookup
- &luid ) ) // receives LUID of privilege
- {
- SaveLastErrMsg("LookupPrivilegeValue error: %u", GetLastError() );
- return FALSE;
- }
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- if (bEnablePrivilege)
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- else
- tp.Privileges[0].Attributes = 0;
- // Enable the privilege or disable all privileges.
- if ( !AdjustTokenPrivileges(
- hToken,
- FALSE,
- &tp,
- sizeof(TOKEN_PRIVILEGES),
- (PTOKEN_PRIVILEGES) NULL,
- (PDWORD) NULL) )
- {
- SaveLastErrMsg("AdjustTokenPrivileges error: %u.", GetLastError() );
- return FALSE;
- }
- if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
- {
- SaveLastErrMsg("The token does not have the specified privilege.");
- return FALSE;
- }
- return TRUE;
- }
|