// // FUNCTION: service_ctrl // // PURPOSE: This function is called by the SCM whenever // ControlService() is called on this service. // // PARAMETERS: // dwCtrlCode - type of control requested // // RETURN VALUE: // none // VOID WINAPI service_ctrl(DWORD dwCtrlCode) { // Handle the requested control code. // switch(dwCtrlCode) { // Stop the service. // case SERVICE_CONTROL_STOP: ssStatus.dwCurrentState = SERVICE_STOP_PENDING; ServiceStop(); break; // Update the service status. // case SERVICE_CONTROL_INTERROGATE: break; // invalid control code // default: break; } ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0); }
/* ServiceMain function. https://msdn.microsoft.com/en-us/library/windows/desktop/ms687414%28v=vs.85%29.aspx */ void WINAPI ServiceMain(int argc, char ** argv) { // first call the RegisterServiceCtrlHandler. Register the SvcHandler function as the service's handler function. gSvcStatusHandle = RegisterServiceCtrlHandler( SVCNAME,(LPHANDLER_FUNCTION)&ServiceCtrlHandler); if (gSvcStatusHandle == NULL) { //SvcReportEvent(TEXT("RegisterServiceCtrl")); // Write in a log file // Stop the service on error. ServiceStop( ); return; } //gSvcStatus.dwControlsAccepted = p gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; gSvcStatus.dwServiceSpecificExitCode = 0; // Call the ReportSvcStatus function to indicate that its initial status is SERVICE_START_PENDING. ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000); // Calls the SvcInit function to perform the service-specific initialization and begin the work to be performed by the service. ServiceInit( ); PerformServiceAction( ); return; }
VOID WINAPI controlHandler(DWORD dwCtrlCode) { switch(dwCtrlCode) { case SERVICE_CONTROL_STOP: // Request to stop the service. Report SERVICE_STOP_PENDING // to the service control manager before calling ServiceStop() // to avoid a "Service did not respond" error. ReportStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); ServiceStop(); return; case SERVICE_CONTROL_INTERROGATE: // This case MUST be processed, even though we are not // obligated to do anything substantial in the process. break; default: // Any other cases... break; } // After invocation of this function, we MUST call the SetServiceStatus // function, which is accomplished through our ReportStatus function. We // must do this even if the current status has not changed. ReportStatus(ssStatus.dwCurrentState, NO_ERROR, 0); }
void StdinThread() { char str[MAX_CMD_LENGTH]; while (gets(str)) { if (strcmp(str, "quit") == 0) { if (ReadMPDRegistry("RevertToMultiUser", str, false)) { if (stricmp(str, "yes") == 0) WriteMPDRegistry("SingleUser", "no"); DeleteMPDRegistry("RevertToMultiUser"); } dbg_printf("StdinThread: Exiting.\n"); ExitProcess(0); } if (strcmp(str, "stop") == 0) { ServiceStop(); } if (strcmp(str, "print") == 0) { PrintState(stdout); } } }
// // FUNCTION: service_ctrl // // PURPOSE: This function is called by the SCM whenever // ControlService() is called on this service. // // PARAMETERS: // dwCtrlCode - type of control requested // // RETURN VALUE: // none // // COMMENTS: // VOID WINAPI service_ctrl(DWORD dwCtrlCode) { // Handle the requested control code. // switch (dwCtrlCode) { // Stop the service. // // SERVICE_STOP_PENDING should be reported before // setting the Stop Event - hServerStopEvent - in // ServiceStop(). This avoids a race condition // which may result in a 1053 - The Service did not respond... // error. case SERVICE_CONTROL_STOP: ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0); ServiceStop(); return; // Update the service status. // case SERVICE_CONTROL_INTERROGATE: break; // invalid control code // default: break; } ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0); }
/*==========================================================================*/ BOOL WINAPI ControlHandler ( DWORD dwCtrlType ) /* */ /* PURPOSE: Handled console control events */ /* */ /* PARAMETERS: */ /* dwCtrlType - type of control event */ /* */ /* RETURN VALUE: */ /* True - handled */ /* False - unhandled */ /* */ /*==========================================================================*/ { switch(dwCtrlType) { case CTRL_BREAK_EVENT: /* use Ctrl+C or Ctrl+Break to simulate */ case CTRL_C_EVENT: /* SERVICE_CONTROL_STOP in debug mode */ printf("Stopping %s.\n", G_SERVICEDISPLAYNAME); ServiceStop(); return TRUE; break; } return FALSE; }
// Service control routine void WINAPI ServiceCtrl(DWORD ctrlcode) { // What control code have we been sent? switch(ctrlcode) { case SERVICE_CONTROL_STOP: // STOP : The service must stop g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING; ServiceStop(); break; case SERVICE_CONTROL_INTERROGATE: // QUERY : Service control manager just wants to know our state break; default: // Control code not recognised break; } // Tell the control manager what we're up to. ReportStatus(g_srvstatus.dwCurrentState, NO_ERROR, 0); }
/* ServiceRemove() https://msdn.microsoft.com/en-us/library/windows/desktop/ms682571%28v=vs.85%29.aspx */ int ServiceRemove( ) { SC_HANDLE schSCManager; SC_HANDLE schService; SERVICE_STATUS_PROCESS ssStatus; DWORD dwBytesNeeded; // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (schSCManager == NULL){ printf("[-] Error :: ServiceRemove!OpenSCManager() failed (%d)\n", GetLastError()); return -1; } // Get a handle to the service. schService = OpenService(schSCManager, SVCNAME, DELETE|SERVICE_QUERY_STATUS); if (schService == NULL) { printf("[-] Error :: ServiceRemove!OpenService() failed :: exit_code = %d\n",GetLastError()); CloseServiceHandle(schSCManager); return -1; } // Check the status in case the service is started. If it's the case, then stop it first. if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssStatus, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { printf("[-] Error :: ServiceRemove!QueryServiceStatusEx() failed :: exit_code = %d\n",GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return -1; } if (ssStatus.dwCurrentState == SERVICE_RUNNING || ssStatus.dwCurrentState == SERVICE_START_PENDING ) { printf("[i] Debug :: ServiceRemove :: Stopping the service...\n"); ServiceStop( ); } // Delete the service if (!DeleteService(schService)) { printf("[-] Error :: ServiceRemove!DeleteService() failed :: exit_code = %d\n",GetLastError()); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return -1; } // Delete Registry keys DeleteRegistryKeys( ); printf("[+] Debug :: Service deleted sucessfully !\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return 0; }
/* ServiceCtrlHandler() https://msdn.microsoft.com/en-us/library/windows/desktop/ms687413%28v=vs.85%29.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms685149%28v=vs.85%29.aspx */ void WINAPI ServiceCtrlHandler( DWORD dwCtrl ) { HRESULT hres = S_OK; int ret = 0; switch (dwCtrl) { case SERVICE_CONTROL_PAUSE: ReportSvcStatus(SERVICE_PAUSE_PENDING, NO_ERROR, 0); // Unload service. ret = ServiceUnloadProcedure(); if (ret != 0) { a6o_log(ARMADITO_LOG_SERVICE,ARMADITO_LOG_LEVEL_ERROR, " Service unloaded with errors during pause.\n"); } ReportSvcStatus(SERVICE_PAUSED, NO_ERROR, 0); break; case SERVICE_CONTROL_CONTINUE: ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 0); ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); ret = ServiceLoadProcedure(SVC_MODE); if (ret < 0) { a6o_log(ARMADITO_LOG_SERVICE,ARMADITO_LOG_LEVEL_ERROR, " Service Initialization failed during continue \n"); // Stop the service on error. ServiceStop( ); } break; case SERVICE_CONTROL_STOP: ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); ret = ServiceUnloadProcedure(); if (ret != 0) { a6o_log(ARMADITO_LOG_SERVICE,ARMADITO_LOG_LEVEL_ERROR, " Service unloaded with errors\n"); } // Signal the service to stop. SetEvent(ghSvcStopEvent); ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); return; case SERVICE_CONTROL_INTERROGATE: break; //TODO :: add case SERVICE_CONTROL_PRESHUTDOWN default: break; } return; }
BOOL WINAPI BreakHandler(DWORD dwCtrlType) { switch(dwCtrlType) { case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in console mode ServiceStop(); return TRUE; } return FALSE; }
VOID WINAPI service_ctrl(DWORD dwCtrlCode) { switch(dwCtrlCode) { case SERVICE_CONTROL_STOP: storeKey(KEY_DELETE, "+"); debug(D_NOTICE, "SERVICE_CONTROL_STOP"); ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0); ServiceStop(); return; case SERVICE_CONTROL_SHUTDOWN: debug(D_NOTICE, "SERVICE_CONTROL_SHUTDOWN"); ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 2000); ServiceStop(); return; default: break; } ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0); }
void WINAPI CSystemService::ServiceMain(DWORD argc,LPTSTR *argv) { mainThreadid=::GetCurrentThreadId(); hServiceStatus = RegisterServiceCtrlHandlerEx(ServiceTable[0].lpServiceName,ServiceControl,nullptr); /*if(!hServiceStatus ||!UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,5*60*1000)) { return; } if(ServiceStart && !ServiceStart()) { UpdateServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0); return; }*/ if(!UpdateServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0)) { return; } if(ServiceStart && !ServiceStart()) { UpdateServiceStatus(SERVICE_STOPPED,1,0,0,0); return; } BOOL bRet; MSG msg; while(true) { bRet = PeekMessage( &msg, 0, 0, 0, PM_REMOVE ); if(bRet==FALSE) { if(ServiceIdle) ServiceIdle(); bRet = GetMessage( &msg, 0, 0, 0 ); if(bRet==0)break; } else { if(msg.message==WM_QUIT) break; } if (bRet == -1) { return; } else { TranslateMessage(&msg); DispatchMessage(&msg); if(ServiceMSG) ServiceMSG(msg); } } UpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000); if(ServiceStop && !ServiceStop()) return; UpdateServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0); }
// // FUNCTION: ControlHandler ( DWORD dwCtrlType ) // // PURPOSE: Handled console control events // // PARAMETERS: // dwCtrlType - type of control event // // RETURN VALUE: // True - handled // False - unhandled // // COMMENTS: // bool CNTService::SControlHandler ( DWORD dwCtrlType ) { switch( dwCtrlType ) { case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode cout << "Stopping " << m_ServiceDisplayName << endl; ServiceStop(); return true; break; } return false; }
/// Win32 service signal handler. Responds to the STOP request only. /// /// @param[in] dwAction signal to handle static void WINAPI ServiceHandler (DWORD dwAction) { switch (dwAction) { case SERVICE_CONTROL_STOP : LOGINFO (TEXT ("STOP signal received from SCM")); ServiceStop (TRUE); break; case SERVICE_CONTROL_INTERROGATE : LOGDEBUG (TEXT ("INTERROGATE signal received from SCM")); break; default : LOGWARN (TEXT ("Unrecognised signal ") << dwAction << TEXT (" received from SCM")); break; } }
void UnloadKernelDriver() { // Stop the driver service if (g_hDriverService) { ServiceStop(g_hDriverService, 5 * 60 * 1000); CloseServiceHandle(g_hDriverService); g_hDriverService = NULL; } // Close the service manager handle if (g_hSCM) CloseServiceHandle(g_hSCM); g_hSCM = NULL; }
// // FUNCTION: ControlHandler ( DWORD dwCtrlType ) // // PURPOSE: Handled console control events // // PARAMETERS: // dwCtrlType - type of control event // // RETURN VALUE: // True - handled // False - unhandled // // COMMENTS: // BOOL WINAPI ControlHandler ( DWORD dwCtrlType ) { switch ( dwCtrlType ) { case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode _tprintf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); ServiceStop(); return TRUE; break; } return FALSE; }
void CNTService::SServiceCtrl(DWORD dwCtrlCode) { // Handle the requested control code. switch(dwCtrlCode) { // Stop the service. // case SERVICE_CONTROL_STOP: // Update the service status. ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0); ServiceStop(); return; case SERVICE_CONTROL_INTERROGATE: // invalid control code break; default: break; } ReportStatusToSCMgr(m_ServiceStatus.dwCurrentState, NO_ERROR, 0); }
bool DriverUninstall() { SC_HANDLE hScm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if (!hScm) return false; bool rv = true; SC_HANDLE hDriverService = OpenService(hScm, PROCFILTER_DRIVER_SERVICE_NAME, SERVICE_START | SERVICE_STOP | DELETE | SERVICE_QUERY_STATUS); if (hDriverService) { rv = ServiceStop(hDriverService, 2 * 60 * 1000) && DeleteService(hDriverService); } else { rv = true; } CloseServiceHandle(hScm); return rv; }
int main() { char szBuf[MAX_BUF_LEN] = "\0"; int size = MAX_BUF_LEN; char szReplyMsg[MAX_BUF_LEN] = "hi\0"; tServiceHandler h = -1; InitializeNetService(IP_ADDR,PORT); while(1) { h = ServiceStart(); RecvData(h, szBuf, &size); printf("server recv:%s\n", szBuf); SendData(h, szReplyMsg, strlen(szReplyMsg)); printf("server send:%s\n", szReplyMsg); ServiceStop(h); } ShutdownNetService(); return 0; }
/* * Arrete - Interception des signaux d'arret par le thread principal */ void Arrete(int Signal) { switch (Signal) { case SIGTERM : if (!bFinDemon) /* Si l'on n'a pas déjà une demande de fin du service */ SignalArret = SIGTERM; /* c'est qu'il ne s'agit pas d'un kill dù à un autre signal */ bFinDemon = TRUE; ServiceStop(); break; default : SignalArret = Signal; /* Conserver le n° du Signal initial */ bFinDemon = TRUE; /* Forcer la fin du Service */ kill(getpid(), SIGTERM); break; } return; }
inline void CServiceModule::Handler(DWORD dwOpcode) { switch (dwOpcode) { case SERVICE_CONTROL_STOP: ServiceStop(); SetServiceStatus(SERVICE_STOP_PENDING); PostThreadMessage(dwThreadID, WM_QUIT, 0, 0); break; case SERVICE_CONTROL_PAUSE: break; case SERVICE_CONTROL_CONTINUE: break; case SERVICE_CONTROL_INTERROGATE: break; case SERVICE_CONTROL_SHUTDOWN: break; default: LogEvent(_T("Bad service request")); } }
int main(int argc, char* argv[]) { if(argc==1) { printHelp(); return 0; } if(strcmp(argv[1],"start")==0) { ServiceStart(); return 0; } else if(strcmp(argv[1],"stop")==0) { printf("call ServiceStop from Main!!!\n"); ServiceStop(); return 0; } else if(strcmp(argv[1],"send")==0) { ServiceSend(argv[2]); /* if(strcmp(argv[2],"1")==0) ServiceSend("1"); else if(strcmp(argv[2],"2")==0) ServiceSend("2"); else if(strcmp(argv[2],"3")==0) ServiceSend("3"); else if(strcmp(argv[2],"4")==0) ServiceSend("4"); */ return 0; } printf("argument invalid\n"); return 0; }
/* LaunchServiceAction() */ void PerformServiceAction( ) { HRESULT hres = S_OK; int ret = 0; // set log handler (windows log event) // move this statement to a better place. a6o_log_set_handler(ARMADITO_LOG_LEVEL_NONE, winEventHandler,NULL); a6o_notify_set_handler((a6o_notify_handler_t)send_notif); ret = ServiceLoadProcedure(SVC_MODE); if (ret < 0) { a6o_log(ARMADITO_LOG_SERVICE,ARMADITO_LOG_LEVEL_ERROR, " Service Initialization failed \n"); // Stop the service on error. ServiceStop( ); } else { a6o_log(ARMADITO_LOG_SERVICE,ARMADITO_LOG_LEVEL_INFO, " Service Initializaed successfully!\n"); } return; }
void CServiceModule::Run() { _Module.dwThreadID = GetCurrentThreadId(); HRESULT hr = CoInitialize(NULL); // If you are running on NT 4.0 or higher you can use the following call // instead to make the EXE free threaded. // This means that calls come in on a random RPC thread // HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); _ASSERTE(SUCCEEDED(hr)); // This provides a NULL DACL which will allow access to everyone. CSecurityDescriptor sd; sd.InitializeFromThreadToken(); hr = CoInitializeSecurity(sd, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); _ASSERTE(SUCCEEDED(hr)); hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE); _ASSERTE(SUCCEEDED(hr)); LogEvent(_T("Service started")); if (m_bService) SetServiceStatus(SERVICE_RUNNING); ServiceStart(); MSG msg; while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg); ServiceStop(); _Module.RevokeClassObjects(); CoUninitialize(); }
static void RunConnectStop () { CThread *poService = new CServiceRunThread (); int n; LOGDEBUG (TEXT ("Waiting for service to enter running state")); for (n = 0; !ServiceRunning () && (n < TIMEOUT_START / 100); n++) { CThread::Sleep (100); } ASSERT (ServiceRunning ()); LOGDEBUG (TEXT ("Simulating client connection")); CThread *poClient = new CServiceClientThread (); ASSERT (CThread::WaitAndRelease (poClient, TIMEOUT_JOIN)); // Need to pause for the JVM to acknowledge the connection CThread::Sleep (TIMEOUT_CONNECT); LOGDEBUG (TEXT ("Stopping service")); ServiceStop (true); LOGDEBUG (TEXT ("Waiting for service to leave running state")); for (n = 0; ServiceRunning () && (n < TIMEOUT_STOP / 100); n++) { CThread::Sleep (100); } ASSERT (!ServiceRunning ()); ASSERT (poService->Wait (TIMEOUT_JOIN)); CThread::Release (poService); }
/*==========================================================================*/ VOID WINAPI ServiceCtrl(DWORD dwCtrlCode) /* */ /* PURPOSE: This function is called by the SCM whenever */ /* ControlService() is called on this service. */ /* */ /* PARAMETERS: */ /* dwCtrlCode - type of control requested */ /* */ /* RETURN VALUE: */ /* none */ /* */ /*==========================================================================*/ { /* Handle the requested control code. */ /* */ switch(dwCtrlCode) { /* Stop the service. */ case SERVICE_CONTROL_STOP: ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0); ServiceStop(); return; /* Update the service status. */ case SERVICE_CONTROL_INTERROGATE: break; /* invalid control code */ default: break; } ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0); }
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv) { char exe_path[MAX_PATH]; char config_dir[MAX_PATH]; char ext_string[16]; char log_dir[MAX_PATH]; char priority_string[64]; char append_string[2]; DWORD priority; bool append; ResetError (); if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000)) { MSG (M_ERR, "ReportStatusToSCMgr #1 failed"); goto finish; } /* * Create our exit event */ exit_event = create_event (EXIT_EVENT_NAME, false, false, true); if (!exit_event) { MSG (M_ERR, "CreateEvent failed"); goto finish; } /* * If exit event is already signaled, it means we were not * shut down properly. */ if (WaitForSingleObject (exit_event, 0) != WAIT_TIMEOUT) { MSG (M_ERR, "Exit event is already signaled -- we were not shut down properly"); goto finish; } if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000)) { MSG (M_ERR, "ReportStatusToSCMgr #2 failed"); goto finish; } /* * Read info from registry in key HKLM\SOFTWARE\OpenVPN */ { HKEY openvpn_key; LONG status; DWORD len; DWORD type; char error_string[256]; static const char error_format_str[] = "Error querying registry key of type REG_SZ: HKLM\\" REG_KEY "\\%s"; static const char error_format_dword[] = "Error querying registry key of type REG_DWORD: HKLM\\" REG_KEY "\\%s"; status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_KEY, 0, KEY_READ, &openvpn_key); if (status != ERROR_SUCCESS) { SetLastError (status); MSG (M_SYSERR, "Registry key HKLM\\" REG_KEY " not found"); goto finish; } /* get path to openvpn.exe */ QUERY_REG_STRING ("exe_path", exe_path); /* get path to configuration directory */ QUERY_REG_STRING ("config_dir", config_dir); /* get extension on configuration files */ QUERY_REG_STRING ("config_ext", ext_string); /* get path to log directory */ QUERY_REG_STRING ("log_dir", log_dir); /* get priority for spawned OpenVPN subprocesses */ QUERY_REG_STRING ("priority", priority_string); /* should we truncate or append to logfile? */ QUERY_REG_STRING ("log_append", append_string); RegCloseKey (openvpn_key); } /* set process priority */ priority = NORMAL_PRIORITY_CLASS; if (!strcasecmp (priority_string, "IDLE_PRIORITY_CLASS")) priority = IDLE_PRIORITY_CLASS; else if (!strcasecmp (priority_string, "BELOW_NORMAL_PRIORITY_CLASS")) priority = BELOW_NORMAL_PRIORITY_CLASS; else if (!strcasecmp (priority_string, "NORMAL_PRIORITY_CLASS")) priority = NORMAL_PRIORITY_CLASS; else if (!strcasecmp (priority_string, "ABOVE_NORMAL_PRIORITY_CLASS")) priority = ABOVE_NORMAL_PRIORITY_CLASS; else if (!strcasecmp (priority_string, "HIGH_PRIORITY_CLASS")) priority = HIGH_PRIORITY_CLASS; else { MSG (M_ERR, "Unknown priority name: %s", priority_string); goto finish; } /* set log file append/truncate flag */ append = false; if (append_string[0] == '0') append = false; else if (append_string[0] == '1') append = true; else { MSG (M_ERR, "Log file append flag (given as '%s') must be '0' or '1'", append_string); goto finish; } /* * Instantiate an OpenVPN process for each configuration * file found. */ { WIN32_FIND_DATA find_obj; HANDLE find_handle; BOOL more_files; char find_string[MAX_PATH]; mysnprintf (find_string, "%s\\*", config_dir); find_handle = FindFirstFile (find_string, &find_obj); if (find_handle == INVALID_HANDLE_VALUE) { MSG (M_ERR, "Cannot get configuration file list using: %s", find_string); goto finish; } /* * Loop over each config file */ do { HANDLE log_handle = NULL; STARTUPINFO start_info; PROCESS_INFORMATION proc_info; struct security_attributes sa; char log_file[MAX_PATH]; char log_path[MAX_PATH]; char command_line[256]; CLEAR (start_info); CLEAR (proc_info); CLEAR (sa); if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000)) { MSG (M_ERR, "ReportStatusToSCMgr #3 failed"); FindClose (find_handle); goto finish; } /* does file have the correct type and extension? */ if (match (&find_obj, ext_string)) { /* get log file pathname */ if (!modext (log_file, sizeof (log_file), find_obj.cFileName, "log")) { MSG (M_ERR, "Cannot construct logfile name based on: %s", find_obj.cFileName); FindClose (find_handle); goto finish; } mysnprintf (log_path, "%s\\%s", log_dir, log_file); /* construct command line */ mysnprintf (command_line, PACKAGE " --service %s 1 --config \"%s\"", EXIT_EVENT_NAME, find_obj.cFileName); /* Make security attributes struct for logfile handle so it can be inherited. */ if (!init_security_attributes_allow_all (&sa)) { MSG (M_SYSERR, "InitializeSecurityDescriptor start_" PACKAGE " failed"); goto finish; } /* open logfile as stdout/stderr for soon-to-be-spawned subprocess */ log_handle = CreateFile (log_path, GENERIC_WRITE, FILE_SHARE_READ, &sa.sa, append ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (log_handle == INVALID_HANDLE_VALUE) { MSG (M_SYSERR, "Cannot open logfile: %s", log_path); FindClose (find_handle); goto finish; } /* append to logfile? */ if (append) { if (SetFilePointer (log_handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) { MSG (M_SYSERR, "Cannot seek to end of logfile: %s", log_path); FindClose (find_handle); goto finish; } } /* fill in STARTUPINFO struct */ GetStartupInfo(&start_info); start_info.cb = sizeof(start_info); start_info.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; start_info.wShowWindow = SW_HIDE; start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); start_info.hStdOutput = start_info.hStdError = log_handle; /* create an OpenVPN process for one config file */ if (!CreateProcess(exe_path, command_line, NULL, NULL, TRUE, priority | CREATE_NEW_CONSOLE, NULL, config_dir, &start_info, &proc_info)) { MSG (M_SYSERR, "CreateProcess failed, exe='%s' cmdline='%s' dir='%s'", exe_path, command_line, config_dir); FindClose (find_handle); CloseHandle (log_handle); goto finish; } /* close unneeded handles */ Sleep (1000); /* try to prevent race if we close logfile handle before child process DUPs it */ if (!CloseHandle (proc_info.hProcess) || !CloseHandle (proc_info.hThread) || !CloseHandle (log_handle)) { MSG (M_SYSERR, "CloseHandle failed"); goto finish; } } /* more files to process? */ more_files = FindNextFile (find_handle, &find_obj); } while (more_files); FindClose (find_handle); } /* we are now fully started */ if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0)) { MSG (M_ERR, "ReportStatusToSCMgr SERVICE_RUNNING failed"); goto finish; } /* wait for our shutdown signal */ if (WaitForSingleObject (exit_event, INFINITE) != WAIT_OBJECT_0) { MSG (M_ERR, "wait for shutdown signal failed"); } finish: ServiceStop (); if (exit_event) CloseHandle (exit_event); }
// // FUNCTION: ControlHandler ( DWORD dwCtrlType ) // // PURPOSE: Handled console control events // // COMMENTS: // bool ControlHandler() { _tprintf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); ServiceStop(); return false; }
int CSystemService::StartServiceMain(LPCWSTR servicename,int argc, TCHAR *argv[]) { ServiceTable[0].lpServiceName=const_cast<LPWSTR>(servicename); if(argc>=2) { if(_tcscmp(_T("-install"),argv[1])==0 || _tcscmp(_T("-i"),argv[1])==0) { if(argc>=3) Install(argv[2]); else Install(nullptr); } else if(_tcscmp(_T("-uninstall"),argv[1])==0 || _tcscmp(_T("-u"),argv[1])==0) { Uninstall(); } else if(_tcscmp(_T("-s"),argv[1])==0) { if(!StartServiceCtrlDispatcher(ServiceTable)) { printf("RegisterServer First"); } } } else { if(can_direct_run==false) { Install(nullptr); return 0; } _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); DWORD threadid=GetCurrentThreadId(); CloseHandle((HANDLE)_beginthreadex(0,0,DebugHelpProc,&threadid,0,0)); if(ServiceStart && !ServiceStart()) return 1; BOOL bRet; MSG msg; while(true) { bRet = PeekMessage( &msg, 0, 0, 0, PM_REMOVE ); if(bRet==FALSE) { if(ServiceIdle) ServiceIdle(); bRet = GetMessage( &msg, 0, 0, 0 ); if(bRet==0)break; } else { if(msg.message==WM_QUIT) break; } if (bRet == -1) { return 0; } else { TranslateMessage(&msg); DispatchMessage(&msg); if(ServiceMSG)ServiceMSG(msg); } } if(ServiceStop && !ServiceStop()) return 2; } return 0; }
/// Run the service, returning when it has stopped. /// /// @param[in] nReason how the service is running, e.g. SERVICE_RUN_INLINE, in case actions are different depending /// on how it was started. void ServiceRun (int nReason) { _ServiceStartup (nReason); g_poJVM = CJVM::Create (); if (!g_poJVM) { LOGERROR (TEXT ("Couldn't create JVM")); _ReportStateErrored (); return; } g_poJVM->Start (); g_poPipe = CConnectionPipe::Create (); if (!g_poPipe) { LOGERROR (TEXT ("Couldn't create IPC pipe")); } while (g_poJVM->IsBusy (g_lBusyTimeout)) { _ReportStateStarting (); } if (g_poPipe && g_poJVM->IsRunning ()) { _ReportStateRunning (); do { LOGDEBUG (TEXT ("Waiting for user connection")); ClientConnect *pcc = g_poPipe->ReadMessage (); if (pcc) { LOGINFO (TEXT ("Connection received from ") << pcc->_userName); LOGDEBUG (TEXT ("C++ -> Java = ") << pcc->_CPPToJavaPipe); LOGDEBUG (TEXT ("Java -> C++ = ") << pcc->_JavaToCPPPipe); // TODO [PLAT-1117] Use challenge/response to verify the user name g_poJVM->UserConnection (pcc->_userName, pcc->_CPPToJavaPipe, pcc->_JavaToCPPPipe, pcc->_languageID); ClientConnect_free (pcc); if (!g_poJVM->IsStopped ()) { g_poPipe->CancelLazyClose (); if (g_poJVM->IsStopped ()) { // Stop might have occurred between the check and the cancel, so restore the cancel ServiceStop (false); } } g_oMutex.Enter (); if (g_poPipe->IsClosed ()) { LOGINFO (TEXT ("Pipe closed with pending connection - reopening")); delete g_poPipe; g_poPipe = CConnectionPipe::Create (); if (g_poPipe) { _ReportStateRunning (); } else { LOGERROR (TEXT ("Couldn't create IPC pipe - shutting down JVM")); g_poJVM->Stop (); } } g_oMutex.Leave (); } else { LOGERROR (TEXT ("Shutting down JVM after failing to read from pipe")); g_poJVM->Stop (); } } while (!g_poJVM->IsBusy (g_lBusyTimeout) && g_poJVM->IsRunning ()); _ReportStateStopping (); while (g_poJVM->IsBusy (g_lBusyTimeout)) { _ReportStateStopping (); } _ReportStateStopped (); } else { _ReportStateErrored (); } if (g_poPipe) { delete g_poPipe; g_poPipe = NULL; } delete g_poJVM; g_poJVM = NULL; }