📄 warwin32ntservice.cpp
字号:
#include "StdAfx.h"#include "WarWin32NtService.h" // class implemented#include "tchar.h"#include "WarLog.h"#include "WarWin32NtServiceMsgs.h" // Event message ids/////////////////////////////// PUBLIC ///////////////////////////////////////WarWin32NtService* WarWin32NtService::mpThis = NULL;//============================= LIFECYCLE ====================================WarWin32NtService::WarWin32NtService(const TCHAR* szServiceName){ // copy the address of the current object so we can access it from // the static member callback functions. // WARNING: This limits the application to only one WarWin32NtService object. mpThis = this; // Set the default service name and version _tcsncpy(mszServiceName, szServiceName, (sizeof(mszServiceName) / sizeof(TCHAR))-1); miMajorVersion = 1; miMinorVersion = 0; // set up the initial service status mhServiceStatus = NULL; mStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; mStatus.dwCurrentState = SERVICE_STOPPED; mStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_PAUSE_CONTINUE|SERVICE_ACCEPT_SHUTDOWN; mStatus.dwWin32ExitCode = 0; mStatus.dwServiceSpecificExitCode = 0; mStatus.dwCheckPoint = 0; mStatus.dwWaitHint = 0; mbIsRunning = FALSE;}WarWin32NtService::~WarWin32NtService(){}//============================= OPERATORS ====================================//============================= OPERATIONS ===================================// Test if the service is currently installedBOOL WarWin32NtService::IsInstalled(){ BOOL result = FALSE; // Open the Service Control Manager SC_HANDLE hSCM = ::OpenSCManager(NULL, // local machine NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access if (hSCM) { // Try to open the service SC_HANDLE hService = ::OpenService(hSCM, mszServiceName, SERVICE_QUERY_CONFIG); if (hService) { result = TRUE; ::CloseServiceHandle(hService); } ::CloseServiceHandle(hSCM); } return result;}BOOL WarWin32NtService::Install(LPCTSTR szVisualName, LPCTSTR szCommandArgs, bool doAutostartWhenBoot, LPCTSTR szUserAccountName, LPCTSTR szAccountpassword){ WarLog err_log(WARLOG_ERROR, "WarWin32NtService::Install()"); // Map user-name to local user-name WarCollector<wchar_t> name_buf = ".\\"; name_buf << szUserAccountName; szUserAccountName = name_buf.GetValue().c_str(); // Open the Service Control Manager SC_HANDLE hSCM = ::OpenSCManager(NULL, // local machine NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access if (!hSCM) return FALSE; // Get the executable file path TCHAR szFilePath[_MAX_PATH]; szFilePath[0] = '\"'; ::GetModuleFileName(NULL, szFilePath +1, sizeof(szFilePath) -2); _tcscat(szFilePath, _T("\"")); if (szCommandArgs) { if ((_tcslen(szFilePath) + 4 + _tcslen(szCommandArgs)) >= sizeof(szFilePath)) return FALSE; _tcscat(szFilePath, _T(" ")); _tcscat(szFilePath, szCommandArgs); } // Create the service SC_HANDLE hService = ::CreateService(hSCM, mszServiceName, (szVisualName && *szVisualName) ? szVisualName : mszServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, doAutostartWhenBoot ? SERVICE_AUTO_START : SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szFilePath, NULL, NULL, NULL, (szUserAccountName && *szUserAccountName) ? szUserAccountName : NULL, (szAccountpassword && *szAccountpassword) ? szAccountpassword : NULL); if (!hService) { WarSystemError sys_err; err_log << "Failed to install as service.\n" << "The system call CreateService() failed.\n" << sys_err << war_endl; ::CloseServiceHandle(hSCM); return FALSE; } // make registry entries to support logging messages // Add the source name as a subkey under the Application // key in the EventLog service portion of the registry. TCHAR szKey[256]; HKEY hKey = NULL; _tcscpy(szKey, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\")); _tcscat(szKey, mszServiceName); if (::RegCreateKey(HKEY_LOCAL_MACHINE, szKey, &hKey) != ERROR_SUCCESS) { ::CloseServiceHandle(hService); ::CloseServiceHandle(hSCM); return FALSE; } // Add the Event ID message-file name to the 'EventMessageFile' subkey. ::RegSetValueEx(hKey, _T("EventMessageFile"), 0, REG_EXPAND_SZ, (CONST BYTE*)szFilePath, _tcsclen(szFilePath) + 1); // Set the supported types flags. DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; ::RegSetValueEx(hKey, _T("TypesSupported"), 0, REG_DWORD, (CONST BYTE*)&dwData, sizeof(DWORD)); ::RegCloseKey(hKey); // tidy up ::CloseServiceHandle(hService); ::CloseServiceHandle(hSCM); return TRUE;}BOOL WarWin32NtService::Uninstall(){ // Open the Service Control Manager SC_HANDLE hSCM = ::OpenSCManager(NULL, // local machine NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access if (!hSCM) return FALSE; BOOL result = FALSE; SC_HANDLE hService = ::OpenService(hSCM, mszServiceName, DELETE); if (hService) { if (::DeleteService(hService)) { result = TRUE; } else { } ::CloseServiceHandle(hService); } ::CloseServiceHandle(hSCM); return result;}//============================= ACCESS ===================================//============================= INQUIRY ===================================/////////////////////////////// PROTECTED ///////////////////////////////////void WarWin32NtService::SetStatus(DWORD dwState){ mStatus.dwCurrentState = dwState; ::SetServiceStatus(mhServiceStatus, &mStatus);}BOOL WarWin32NtService::Initialize(){ // Start the initialization SetStatus(SERVICE_START_PENDING); // Perform the actual initialization BOOL result = OnInit(); // Set final state mStatus.dwWin32ExitCode = GetLastError(); mStatus.dwCheckPoint = 0; mStatus.dwWaitHint = 0; if (!result) { SetStatus(SERVICE_STOPPED); return FALSE; } SetStatus(SERVICE_RUNNING); return TRUE;}// static member function (callback) to handle commands from the// service control managervoid WarWin32NtService::Handler(DWORD dwOpcode){ // Get a pointer to the object WarWin32NtService* pService = mpThis; switch (dwOpcode) { case SERVICE_CONTROL_STOP: // 1 pService->SetStatus(SERVICE_STOP_PENDING); pService->OnStop(); pService->mbIsRunning = FALSE; break; case SERVICE_CONTROL_PAUSE: // 2 pService->OnPause(); break; case SERVICE_CONTROL_CONTINUE: // 3 pService->OnContinue(); break; case SERVICE_CONTROL_INTERROGATE: // 4 pService->OnInterrogate(); break; case SERVICE_CONTROL_SHUTDOWN: // 5 pService->OnShutdown(); break; default: if (dwOpcode >= WAR_SERVICE_CONTROL_USER) { if (!pService->OnUserControl(dwOpcode)) { } } else { } break; } // Report current status ::SetServiceStatus(pService->mhServiceStatus, &pService->mStatus);}// Called when the service is first initializedBOOL WarWin32NtService::OnInit(){ return TRUE;}// Called when the service control manager wants to stop the servicevoid WarWin32NtService::OnStop(){}// called when the service is interrogatedvoid WarWin32NtService::OnInterrogate(){}// called when the service is pausedvoid WarWin32NtService::OnPause(){}// called when the service is continuedvoid WarWin32NtService::OnContinue(){}// called when the service is shut downvoid WarWin32NtService::OnShutdown(){}// called when the service gets a user control messageBOOL WarWin32NtService::OnUserControl(DWORD dwOpcode){ return FALSE; // say not handled}BOOL WarWin32NtService::StartService(){ SERVICE_TABLE_ENTRY st[] = { {mszServiceName, ServiceMain}, {NULL, NULL} }; BOOL b = ::StartServiceCtrlDispatcher(st); return b;}/////////////////////////////// PRIVATE ///////////////////////////////////// static member function (callback)void WarWin32NtService::ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv){ // Get a pointer to the C++ object WarWin32NtService* pService = mpThis; // Register the control request handler pService->mStatus.dwCurrentState = SERVICE_START_PENDING; pService->mhServiceStatus = RegisterServiceCtrlHandler(pService->mszServiceName, Handler); if (pService->mhServiceStatus == NULL) { return; } // Start the initialisation if (pService->Initialize()) { // Do the real work. // When the Run function returns, the service has stopped. pService->mbIsRunning = TRUE; pService->mStatus.dwWin32ExitCode = 0; pService->mStatus.dwCheckPoint = 0; pService->mStatus.dwWaitHint = 0; try { pService->Run(); } catch(...) { } } // Tell the service manager we are stopped pService->SetStatus(SERVICE_STOPPED); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -