BOOL Control(DWORD Control, LPCTSTR ServiceName, LPCTSTR *Args, INT ArgCount) { SC_HANDLE hSCManager = NULL; SC_HANDLE hSc = NULL; SERVICE_STATUS Status; DWORD dwDesiredAccess = 0; #ifdef SCDBG LPCTSTR *TmpArgs = Args; INT TmpCnt = ArgCount; _tprintf(_T("service to control - %s\n"), ServiceName); _tprintf(_T("command - %lu\n"), Control); _tprintf(_T("Arguments:\n")); while (TmpCnt) { _tprintf(_T(" %s\n"), *TmpArgs); TmpArgs++; TmpCnt--; } _tprintf(_T("\n")); #endif /* SCDBG */ switch (Control) { case SERVICE_CONTROL_STOP: dwDesiredAccess = SERVICE_STOP; break; case SERVICE_CONTROL_PAUSE: dwDesiredAccess = SERVICE_PAUSE_CONTINUE; break; case SERVICE_CONTROL_CONTINUE: dwDesiredAccess = SERVICE_PAUSE_CONTINUE; break; case SERVICE_CONTROL_INTERROGATE: dwDesiredAccess = SERVICE_INTERROGATE; break; case SERVICE_CONTROL_SHUTDOWN: dwDesiredAccess = 0; break; } hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (hSCManager != NULL) { hSc = OpenService(hSCManager, ServiceName, dwDesiredAccess); if (hSc != NULL) { if (ControlService(hSc, Control, &Status)) { SERVICE_STATUS_PROCESS StatusEx; /* FIXME: lazy hack ;) */ CopyMemory(&StatusEx, &Status, sizeof(Status)); StatusEx.dwProcessId = 0; StatusEx.dwServiceFlags = 0; PrintService(ServiceName, &StatusEx, FALSE); CloseServiceHandle(hSc); CloseServiceHandle(hSCManager); return TRUE; } } else _tprintf(_T("[SC] OpenService FAILED %lu:\n\n"), GetLastError()); } ReportLastError(); if (hSc) CloseServiceHandle(hSc); if (hSCManager) CloseServiceHandle(hSCManager); return FALSE; }
/** Install and Uninstall the service and write actions to the event log. If pszFullPath is given, it will be set as the path, otherwise the path will be retreived from the module name. The default command line processing calls this function with pszLogonAs and pszLogonPassword set to NULL. Override this function, and when bInstall is VTRUE, get the logon as and password if needed, and then call the base class function. pszLogonAs can be either a DomainName\UserName or just the UserName, in which case this function will prepend .\ which is required by the CreateService() API function. Returns VTRUE on success, VFALSE on failure.*/ virtual VBOOL Install( VBOOL bInstall = VTRUE, VDWORD nStartType = SERVICE_AUTO_START, VSTRING_CONST pszFullPath = NULL, VSTRING_CONST pszLogonAs = NULL, VSTRING_CONST pszLogonPassword = NULL, VBOOL bStartAfterInstall = VTRUE, VBOOL bSilentMode = VFALSE) { /* Service name should not be empty!*/ VASSERT(m_strServiceName.IsNotEmpty()) /* Assume failure.*/ VBOOL bSuccess = VFALSE; /* Open the Service Control Manager.*/ SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if ( hSCM ) { if ( bInstall ) { /* Verify un-installed, first (silent mode).*/ Install(VFALSE, 0, NULL, NULL, NULL, VFALSE, VTRUE); /* Get this executables file path (unless given in pszFullPath).*/ VString sPath; if ( !pszFullPath ) sPath.GetModulePath(VFALSE, VFALSE); else sPath = pszFullPath; if ( sPath.IsNotEmpty() ) { /* If pszLogonAs is not NULL, verify domain name is present, and if not, .\ is present. If neither is the case, we will modify the logon as to be correct.*/ VString strLogonAs; if ( pszLogonAs ) { /* If we find a \ assume correct DomainName\UserName string.*/ if ( !VSTRCHR(pszLogonAs, VTEXT('\\')) ) { /* Domain Name not given, so does the string already contain .\ sequence as the first chars?*/ if ( !(*pszLogonAs == VTEXT('.') && *(pszLogonAs + 1) == VTEXT('\\')) ) { strLogonAs = VTEXT(".\\"); strLogonAs += pszLogonAs; pszLogonAs = strLogonAs; } } } /* We want no error condition now.*/ SetLastError(0); /* Create the service.*/ SC_HANDLE hService = CreateService( hSCM, m_strServiceName, m_strServiceName, SERVICE_ALL_ACCESS, m_Status.dwServiceType, nStartType, SERVICE_ERROR_NORMAL, sPath, NULL, NULL, NULL, pszLogonAs, pszLogonPassword); if ( hService || GetLastError() == ERROR_SERVICE_EXISTS ) { /* Make or verify registry entries to support event logging.*/ bSuccess = (m_hEventSource) ? VTRUE : Register(m_strServiceName); if ( hService && bSuccess && bStartAfterInstall ) { bSuccess = StartService(hService, 0, NULL); /* If service fails to start now, un-install it.*/ if ( !bSuccess ) { /* Close handle first.*/ CloseServiceHandle(hService); hService = NULL; /* Un-Install in silent mode.*/ Install( VFALSE, 0, NULL, NULL, NULL, VFALSE, VTRUE); } } if ( hService ) CloseServiceHandle(hService); } } /* Log what happened if we can.*/ LogEvent( (bSuccess) ? EM_SERVICE_INSTALLED : EM_SERVICE_NOT_INSTALLED, (bSuccess) ? VFALSE : VTRUE); /* Notify via virtual function.*/ OnInstall(bSuccess, bSilentMode); } else { SC_HANDLE hService = OpenService( hSCM, m_strServiceName, SERVICE_QUERY_STATUS | DELETE); if ( hService ) { /* If the service is running, stop it.*/ SERVICE_STATUS ss; if ( QueryServiceStatus(hService, &ss) ) { if ( ss.dwCurrentState != SERVICE_STOPPED ) { /* Get a handle we can use to stop the service.*/ SC_HANDLE hStopService = OpenService( hSCM, m_strServiceName, SERVICE_STOP); if ( hStopService ) { SERVICE_STATUS ss; ControlService( hStopService, SERVICE_CONTROL_STOP, &ss); CloseServiceHandle(hStopService); } } } bSuccess = (hService && DeleteService(hService)) ? VTRUE : VFALSE; CloseServiceHandle(hService); } else bSuccess = VTRUE; /* Remove registry entries on success.*/ if ( bSuccess ) { VRegistry reg; if ( reg.CreateKey(GetRegistryKey(), HKEY_LOCAL_MACHINE) ) reg.DeleteSubKeyNT(m_strServiceName); } /* Log what happened if we can.*/ LogEvent( (bSuccess) ? EM_SERVICE_UNINSTALLED : EM_SERVICE_NOT_REMOVED, (bSuccess) ? VFALSE : VTRUE); /* Notify via virtual function.*/ OnUnInstall(bSuccess, bSilentMode); } CloseServiceHandle(hSCM); } return bSuccess; }
INT cmdStop(INT argc, WCHAR **argv) { SC_HANDLE hManager = NULL; SC_HANDLE hService = NULL; SERVICE_STATUS ServiceStatus; DWORD dwError = ERROR_SUCCESS; INT nError = 0; INT i; if (argc != 3) { ConResPuts(StdOut, IDS_GENERIC_SYNTAX); ConResPuts(StdOut, IDS_STOP_SYNTAX); return 1; } for (i = 2; i < argc; i++) { if (_wcsicmp(argv[i], L"/help") == 0) { ConResPuts(StdOut, IDS_GENERIC_SYNTAX); ConResPuts(StdOut, IDS_STOP_SYNTAX); ConResPuts(StdOut, IDS_STOP_HELP_1); ConResPuts(StdOut, IDS_STOP_HELP_2); ConResPuts(StdOut, IDS_STOP_HELP_3); return 1; } } hManager = OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE); if (hManager == NULL) { dwError = GetLastError(); nError = 1; goto done; } hService = OpenServiceW(hManager, argv[2], SERVICE_STOP); if (hService == NULL) { dwError = GetLastError(); nError = 1; goto done; } if (!ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus)) { dwError = GetLastError(); nError = 1; goto done; } done: if (hService != NULL) CloseServiceHandle(hService); if (hManager != NULL) CloseServiceHandle(hManager); if (dwError != ERROR_SUCCESS) { /* FIXME: Print proper error message */ ConPrintf(StdErr, L"Error: %lu\n", dwError); } return nError; }
int unregisterService() { #ifdef WIN32 Logging::LoggerRef logRef(ppg->getLogger(), "ServiceDeregistrator"); SC_HANDLE scManager = NULL; SC_HANDLE scService = NULL; SERVICE_STATUS ssSvcStatus = { }; int ret = 0; for (;;) { scManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (scManager == NULL) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "OpenSCManager failed with error: " << GetLastErrorMessage(GetLastError()); ret = 1; break; } scService = OpenService(scManager, SERVICE_NAME, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE); if (scService == NULL) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "OpenService failed with error: " << GetLastErrorMessage(GetLastError()); ret = 1; break; } if (ControlService(scService, SERVICE_CONTROL_STOP, &ssSvcStatus)) { logRef(Logging::INFO) << "Stopping " << SERVICE_NAME; Sleep(1000); while (QueryServiceStatus(scService, &ssSvcStatus)) { if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING) { logRef(Logging::INFO) << "Waiting..."; Sleep(1000); } else { break; } } std::cout << std::endl; if (ssSvcStatus.dwCurrentState == SERVICE_STOPPED) { logRef(Logging::INFO) << SERVICE_NAME << " is stopped"; } else { logRef(Logging::FATAL, Logging::BRIGHT_RED) << SERVICE_NAME << " failed to stop" << std::endl; } } if (!DeleteService(scService)) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "DeleteService failed with error: " << GetLastErrorMessage(GetLastError()); ret = 1; break; } logRef(Logging::INFO) << SERVICE_NAME << " is removed"; break; } if (scManager) { CloseServiceHandle(scManager); } if (scService) { CloseServiceHandle(scService); } return ret; #else return 0; #endif }