bool ControlSSDPService(bool start) { bool result = false; SC_HANDLE hscm = NULL; hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if(hscm == NULL) return result; SC_HANDLE hsrv = NULL; hsrv = OpenService(hscm, _T("ssdpsrv"), SERVICE_ALL_ACCESS); if(hsrv) { SERVICE_STATUS srvstatus; if(QueryServiceStatus(hsrv, &srvstatus)) { HANDLE hevent = CreateEvent(0, true, false, _T("dummyevent")); // if service_*_pending then wait for complete operation switch(srvstatus.dwCurrentState) { case SERVICE_START_PENDING : case SERVICE_STOP_PENDING : for(int i = 0; i < 10; ++i) { if(!QueryServiceStatus(hsrv, &srvstatus)) break; if(srvstatus.dwCurrentState == SERVICE_RUNNING || srvstatus.dwCurrentState == SERVICE_STOPPED) break; WaitForSingleObject(hevent, 1000); } break; } // operation completed, so change current state if(QueryServiceStatus(hsrv, &srvstatus)) { switch(srvstatus.dwCurrentState) { case SERVICE_RUNNING : // stop it if(!start && ControlService(hsrv, SERVICE_CONTROL_STOP, &srvstatus)) result = true; break; case SERVICE_STOPPED : // start it if(start && StartService(hsrv, 0, NULL)) result = true; break; } // wait for complete operation if(result) { for(int i = 0; i < 10; ++i) { if(!QueryServiceStatus(hsrv, &srvstatus)) break; if(srvstatus.dwCurrentState == SERVICE_RUNNING || srvstatus.dwCurrentState == SERVICE_STOPPED) { // notify scm //ControlService(hsrv, SERVICE_CONTROL_INTERROGATE, &srvstatus); break; } WaitForSingleObject(hevent, 1000); } } } } CloseServiceHandle(hsrv); } CloseServiceHandle(hscm); return result; }
int remove_service(TCHAR *installdir, int check_only) { HKEY hKey; int done = 0; if(wcslen(installdir) < 3) { WcaLog(LOGMSG_STANDARD, "INSTALLDIR is suspiciously short, better not do anything."); return 0; } if(check_only == 0) { WcaLog(LOGMSG_STANDARD, "Determining number of matching services..."); int servicecount = remove_service(installdir, 1); if(servicecount <= 0) { WcaLog(LOGMSG_STANDARD, "No services found, not removing anything."); return 0; } else if(servicecount == 1) { TCHAR buf[256]; swprintf_s(buf, sizeof(buf), TEXT("There is a service called '%ls' set up to run from this installation. Do you wish me to stop and remove that service?"), last_service_name); int rc = MessageBox(NULL, buf, TEXT("Removing MySQL Server"), MB_ICONQUESTION|MB_YESNOCANCEL|MB_SYSTEMMODAL); if(rc == IDCANCEL) return -1; if(rc != IDYES) return 0; } else if(servicecount > 0) { TCHAR buf[256]; swprintf_s(buf, sizeof(buf), TEXT("There appear to be %d services set up to run from this installation. Do you wish me to stop and remove those services?"), servicecount); int rc = MessageBox(NULL, buf, TEXT("Removing MySQL Server"), MB_ICONQUESTION|MB_YESNOCANCEL|MB_SYSTEMMODAL); if(rc == IDCANCEL) return -1; if(rc != IDYES) return 0; } } if(check_only == -1) check_only = 0; WcaLog(LOGMSG_STANDARD, "Looking for service..."); WcaLog(LOGMSG_STANDARD, "INSTALLDIR = %ls", installdir); if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\services"), 0, KEY_READ, &hKey)==ERROR_SUCCESS) { DWORD index = 0; TCHAR keyname[1024]; DWORD keylen = sizeof(keyname); FILETIME t; /* Go through all services in the registry */ while(RegEnumKeyExW(hKey, index, keyname, &keylen, NULL, NULL, NULL, &t) == ERROR_SUCCESS) { HKEY hServiceKey = 0; TCHAR path[1024]; DWORD pathlen = sizeof(path)-1; if (RegOpenKeyExW(hKey, keyname, NULL, KEY_READ, &hServiceKey) == ERROR_SUCCESS) { /* Look at the ImagePath value of each service */ if (RegQueryValueExW(hServiceKey, TEXT("ImagePath"), NULL, NULL, (LPBYTE)path, &pathlen) == ERROR_SUCCESS) { path[pathlen] = 0; TCHAR *p = path; if(p[0] == '"') p += 1; /* See if it is similar to our install directory */ if(wcsncmp(p, installdir, wcslen(installdir)) == 0) { WcaLog(LOGMSG_STANDARD, "Found service '%ls' with ImagePath '%ls'.", keyname, path); swprintf_s(last_service_name, sizeof(last_service_name), TEXT("%ls"), keyname); /* If we are supposed to stop and remove the service... */ if(!check_only) { WcaLog(LOGMSG_STANDARD, "Trying to stop the service."); SC_HANDLE hSCM = NULL; hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if(hSCM != NULL) { SC_HANDLE hService = NULL; hService = OpenService(hSCM, keyname, SERVICE_STOP|SERVICE_QUERY_STATUS|DELETE); if(hService != NULL) { WcaLog(LOGMSG_STANDARD, "Waiting for the service to stop..."); SERVICE_STATUS status; /* Attempt to stop the service */ if(ControlService(hService, SERVICE_CONTROL_STOP, &status)) { /* Now wait until it's stopped */ while("it's one big, mean and cruel world out there") { if(!QueryServiceStatus(hService, &status)) break; if(status.dwCurrentState == SERVICE_STOPPED) break; Sleep(1000); } WcaLog(LOGMSG_STANDARD, "Stopped the service."); } /* Mark the service for deletion */ DeleteService(hService); CloseServiceHandle(hService); } CloseServiceHandle(hSCM); } } done++; } } RegCloseKey(hServiceKey); } index++; keylen = sizeof(keyname)-1; } RegCloseKey(hKey); } else { WcaLog(LOGMSG_STANDARD, "Can't seem to go through the list of installed services in the registry."); } return done; }
THREAD_ENTRY_DECLARE start_and_watch_server(THREAD_ENTRY_PARAM) { /************************************** * * s t a r t _ a n d _ w a t c h _ s e r v e r * ************************************** * * Functional description * * This function is where the server process is created and * the thread waits for this process to exit. * **************************************/ Firebird::ContextPoolHolder threadContext(getDefaultMemoryPool()); HANDLE procHandle = NULL; bool done = true; const UINT error_mode = SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT; SC_HANDLE hScManager = 0, hService = 0; // get the guardian startup information const short option = Config::getGuardianOption(); char prefix_buffer[MAXPATHLEN]; GetModuleFileName(NULL, prefix_buffer, sizeof(prefix_buffer)); Firebird::PathName path = prefix_buffer; path = path.substr(0, path.rfind(PathUtils::dir_sep) + 1) + FBSERVER; path = "\"" + path + "\""; Firebird::PathName prog_name = path + " -a -n"; // if the guardian is set to FOREVER then set the error mode UINT old_error_mode = 0; if (option == START_FOREVER) old_error_mode = SetErrorMode(error_mode); // Spawn the new process do { SERVICE_STATUS ServiceStatus; char out_buf[1024]; BOOL success; int error = 0; if (service_flag) { if (hService) { while ((QueryServiceStatus(hService, &ServiceStatus) == TRUE) && (ServiceStatus.dwCurrentState != SERVICE_STOPPED)) { Sleep(500); } } procHandle = CreateMutex(NULL, FALSE, mutex_name->c_str()); // start as a service. If the service can not be found or // fails to start, close the handle to the mutex and set // success = FALSE if (!hScManager) hScManager = OpenSCManager(NULL, NULL, GENERIC_READ); if (!hService) { hService = OpenService(hScManager, remote_name->c_str(), GENERIC_READ | GENERIC_EXECUTE); } success = StartService(hService, 0, NULL); if (success != TRUE) error = GetLastError(); // if the server is already running, then inform it that it should // open the guardian mutex so that it may be governed. if (!error || error == ERROR_SERVICE_ALREADY_RUNNING) { // Make sure that it is actually ready to receive commands. // If we were the one who started it, then it will need a few // seconds to get ready. while ((QueryServiceStatus(hService, &ServiceStatus) == TRUE) && (ServiceStatus.dwCurrentState != SERVICE_RUNNING)) { Sleep(500); } ControlService(hService, SERVICE_CREATE_GUARDIAN_MUTEX, &ServiceStatus); success = TRUE; } } else { HWND hTmpWnd = FindWindow(szClassName, szWindowName); if (hTmpWnd == NULL) { STARTUPINFO si; SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; success = CreateProcess(NULL, const_cast<char*>(prog_name.c_str()), &sa, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (success != TRUE) error = GetLastError(); procHandle = pi.hProcess; // TMN: 04 Aug 2000 - closed the handle that previously leaked. CloseHandle(pi.hThread); } else { SendMessage(hTmpWnd, WM_COMMAND, (WPARAM) IDM_GUARDED, 0); DWORD server_pid; GetWindowThreadProcessId(hTmpWnd, &server_pid); procHandle = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, server_pid); if (procHandle == NULL) { error = GetLastError(); success = FALSE; } else { success = TRUE; } } } if (success != TRUE) { // error creating new process char szMsgString[256]; LoadString(hInstance_gbl, IDS_CANT_START_THREAD, szMsgString, 256); sprintf(out_buf, "%s : %s errno : %d", path.c_str(), szMsgString, error); write_log(IDS_CANT_START_THREAD, out_buf); if (service_flag) { SERVICE_STATUS status_info; // wait a second to get the mutex handle (just in case) and // then close it WaitForSingleObject(procHandle, 1000); CloseHandle(procHandle); hService = OpenService(hScManager, remote_name->c_str(), GENERIC_READ | GENERIC_EXECUTE); ControlService(hService, SERVICE_CONTROL_STOP, &status_info); CloseServiceHandle(hScManager); CloseServiceHandle(hService); CNTL_stop_service(); //service_name->c_str()); } else { MessageBox(NULL, out_buf, NULL, MB_OK | MB_ICONSTOP); PostMessage(hWndGbl, WM_CLOSE, 0, 0); } return 0; } else { char szMsgString[256]; LoadString(hInstance_gbl, IDS_STARTING_GUARD, szMsgString, 256); sprintf(out_buf, "%s: %s\n", szMsgString, path.c_str()); write_log(IDS_LOG_START, out_buf); } // wait for process to terminate DWORD exit_status; if (service_flag) { while (WaitForSingleObject(procHandle, 500) == WAIT_OBJECT_0) { ReleaseMutex(procHandle); Sleep(100); } const int ret_val = WaitForSingleObject(procHandle, INFINITE); if (ret_val == WAIT_ABANDONED) exit_status = CRASHED; else if (ret_val == WAIT_OBJECT_0) exit_status = NORMAL_EXIT; CloseHandle(procHandle); } else { while (WaitForSingleObject(procHandle, INFINITE) == WAIT_FAILED) ; GetExitCodeProcess(procHandle, &exit_status); CloseHandle(procHandle); } if (exit_status != NORMAL_EXIT) { // check for startup error if (exit_status == STARTUP_ERROR) { char szMsgString[256]; LoadString(hInstance_gbl, IDS_STARTUP_ERROR, szMsgString, 256); sprintf(out_buf, "%s: %s (%lu)\n", path.c_str(), szMsgString, exit_status); write_log(IDS_STARTUP_ERROR, out_buf); done = true; } else { char szMsgString[256]; LoadString(hInstance_gbl, IDS_ABNORMAL_TERM, szMsgString, 256); sprintf(out_buf, "%s: %s (%lu)\n", path.c_str(), szMsgString, exit_status); write_log(IDS_LOG_TERM, out_buf); // switch the icons if the server restarted if (!service_flag) PostMessage(hWndGbl, WM_SWITCHICONS, 0, 0); if (option == START_FOREVER) done = false; } } else { // Normal shutdown - ie: via ibmgr - don't restart the server char szMsgString[256]; LoadString(hInstance_gbl, IDS_NORMAL_TERM, szMsgString, 256); sprintf(out_buf, "%s: %s\n", path.c_str(), szMsgString); write_log(IDS_LOG_STOP, out_buf); done = true; } if (option == START_ONCE) done = true; } while (!done); // If on WINNT if (service_flag) { CloseServiceHandle(hScManager); CloseServiceHandle(hService); CNTL_stop_service(); //(service_name->c_str()); } else PostMessage(hWndGbl, WM_CLOSE, 0, 0); return 0; }
int send_signal_to_service(char *display_name, char *sig, int argc, char **argv) { DWORD service_pid; HANDLE hwnd; SC_HANDLE schService; SC_HANDLE schSCManager; char *service_name; int success = FALSE; enum { start, restart, stop, unknown } action; static char *param[] = { "start", "restart", "shutdown" }; static char *participle[] = { "starting", "restarting", "stopping" }; static char *past[] = { "started", "restarted", "stopped" }; for (action = start; action < unknown; action++) if (!strcasecmp(sig, param[action])) break; if (action == unknown) { printf("signal must be start, restart, or shutdown\n"); return FALSE; } service_name = get_service_name(display_name); if (isWindowsNT()) { schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if (!schSCManager) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "OpenSCManager failed"); return FALSE; } schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS); if (schService == NULL) { /* Could not open the service */ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "OpenService failed"); CloseServiceHandle(schSCManager); return FALSE; } if (!QueryServiceStatus(schService, &globdat.ssStatus)) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "QueryService failed"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } } else /* !isWindowsNT() */ { /* Locate the window named service_name of class ApacheWin95ServiceMonitor * from the active top level windows */ hwnd = FindWindow("ApacheWin95ServiceMonitor", service_name); if (hwnd && GetWindowThreadProcessId(hwnd, &service_pid)) globdat.ssStatus.dwCurrentState = SERVICE_RUNNING; else globdat.ssStatus.dwCurrentState = SERVICE_STOPPED; } if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED && action == stop) { printf("The %s service is not started.\n", display_name); return FALSE; } else if (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING && action == start) { printf("The %s service has already been started.\n", display_name); strcpy(sig, ""); return FALSE; } else { printf("The %s service is %s.\n", display_name, participle[action]); if (isWindowsNT()) { if (action == stop) success = ap_stop_service(schService); else if ((action == start) || ((action == restart) && (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED))) { /* start NT service needs service args */ char **args = malloc(argc * sizeof(char*)); int i, j; for (i = 1, j = 0; i < argc; i++) { if ((argv[i][0] == '-') && ((argv[i][1] == 'k') || (argv[i][1] == 'n'))) ++i; else args[j++] = argv[i]; } success = ap_start_service(schService, j, args); } else if (action == restart) success = ap_restart_service(schService); } else /* !isWindowsNT()) */ { char prefix[20]; ap_snprintf(prefix, sizeof(prefix), "ap%ld", (long)service_pid); setup_signal_names(prefix); if (action == stop) { int ticks = 60; ap_start_shutdown(); while (--ticks) { if (!IsWindow(hwnd)) { success = TRUE; break; } Sleep(1000); } } else if (action == restart) { /* This gets a bit tricky... start and restart (of stopped service) * will simply fall through and *THIS* process will fade into an * invisible 'service' process, detaching from the user's console. * We need to change the restart signal to "start", however, * if the service was not -yet- running, and we do return FALSE * to assure main() that we haven't done anything yet. */ if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) { printf("The %s service has %s.\n", display_name, past[action]); strcpy(sig, "start"); return FALSE; } ap_start_restart(1); success = TRUE; } else /* action == start */ { printf("The %s service is %s.\n", display_name, past[action]); return FALSE; } } if( success ) printf("The %s service has %s.\n", display_name, past[action]); else printf("Failed to %s the %s service.\n", sig, display_name); } if (isWindowsNT()) { CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } return success; }
/* ** Name: PCexec_suid - Execute a command as the ingres user. ** ** Description: ** This procedure works with the Ingres service to run the given ** command as the ingres user. It mimicks the "setuid" bit in UNIX. ** ** Inputs: ** cmdbuf - command to execute as the ingres user ** ** Outputs: ** none ** ** Returns: ** OK ** FAIL ** ** Side Effects: ** none ** ** History: ** 08-jan-1998 (somsa01) ** Created. ** 19-feb-1998 (somsa01) ** We need to pass to the service the current working directory ** as well. (Bug #89006) ** 25-feb-1998 (somsa01) ** We now have an input file for the process' stdin which ** runs through the OpenIngres service. ** 19-jun-1998 (somsa01) ** Use SYSTEM_PRODUCT_NAME for the name of the service. ** 10-jul-1998 (kitch01) ** Bug 91362. If user is 'system' run through OpenIngres service ** despite having access to server shared memory 'system' does not ** have required privilege to access semaphores/mutexes. ** 11-jun-1999 (somsa01) ** If the command is a startup command, then it is always run through ** the Ingres service. ** 03-nov-1999 (somsa01) ** A failure from ControlService() should be treated as a severe ** error which should not let us continue. ** 22-jan-2000 (somsa01) ** Return the exit code of the spawned process. Also, if the ** files exist, truncate them. The service name is now keyed off ** of II_INSTALLATION. ** 05-jun-2000 (somsa01) ** The Ingres installation may be started as the SYSTEM account, ** in which the 'ingres' user will not automatically have access ** to the shared memory segments. Therefore, even if the real ** user is 'ingres', check to see if he has access. ** 24-oct-2000 (somsa01) ** Removed the check on shared memory access. Access to the shared ** memory segment does not necessarily mean that the user running ** the process does not need to run the specified process as the ** Ingres owner. Also, generalized the check of the user with ** IDname_service(). ** 18-dec-2000 (somsa01) ** Modified the cases to run the command "as is" without the Ingres ** service. ** 20-mar-2002 (somsa01) ** If all is well, return the exit code of the child process that ** was executed. ** 29-mar-2002 (somsa01) ** Properly return the child process exit code. ** 11-apr-2003 (somsa01) ** While waiting for "pending" to not be set, give some CPU back ** to the OS. ** 29-Jul-2005 (drivi01) ** Allow user to run the command if he/she owns a shared ** segment and ingres is not running as a service. ** 06-Dec-2006 (drivi01) ** Adding support for Vista, Vista requires "Global\" prefix for ** shared objects as well. Replacing calls to GVosvers with ** GVshobj which returns the prefix to shared objects. ** Added PCadjust_SeDebugPrivilege to allow quering of ** System processes. ** 25-Jul-2007 (drivi01) ** On Vista, PCexec_suid is unable to use SE_DEBUG Privilege ** to query process status and retireve its exit code. ** The routine for monitoring a process and retrieving ** its exit code has been moved to Ingres Service. ** 05-Nov-2009 (wanfr01) b122847 ** Don't do a PCsleep unless you are waiting for more input */ STATUS PCexec_suid(char *cmdbuf) { EX_CONTEXT context; SERVICE_STATUS ssServiceStatus; LPSERVICE_STATUS lpssServiceStatus = &ssServiceStatus; struct SETUID setuid; DWORD ProcID; HANDLE SaveStdout; SECURITY_ATTRIBUTES sa; CHAR szRealUserID[25] = ""; CHAR *pszRealUserID = szRealUserID; CHAR szServiceUserID[25] = ""; CHAR *pszServiceUserID = szServiceUserID; DWORD BytesWritten, BytesRead = 0; CHAR *inst_id; CHAR SetuidShmName[64]; CHAR *temp_loc; CHAR InBuf[256], OutBuf[256]; static CHAR SetuidPipeName[32]; CL_ERR_DESC err_code; CHAR ServiceName[255]; DWORD ExitCode = 0; CHAR tchII_INSTALLATION[3]; BOOL SetuidDbCmd = FALSE, ServiceCommand = FALSE; int i, cmdlen; char *ObjectPrefix; u_i4 drType; SC_HANDLE schSCManager, OpIngSvcHandle; BOOL bServiceStarted = FALSE; if (EXdeclare(ex_handler, &context) != OK) { EXdelete(); PCexit(FAIL); } NMgtAt("II_INSTALLATION", &inst_id); STcopy(inst_id, tchII_INSTALLATION); /* ** See if this is a command that MUST be run through the Ingres ** service. */ cmdlen = (i4)STlength(cmdbuf); for (i = 0; ServiceCommands[i] ; i++) { if (STbcompare( cmdbuf, cmdlen, ServiceCommands[i], (i4)STlength(ServiceCommands[i]), FALSE ) == 0) { ServiceCommand = TRUE; break; } } /* ** If the user is the same as the user who started the Ingres ** service, just spawn the command. */ if (!ServiceCommand) { IDname(&pszRealUserID); if (!IDname_service(&pszServiceUserID) && STcompare(pszServiceUserID, pszRealUserID) == 0 && PCisAdmin()) { /* ** Attempt to just execute the command. */ return( PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT, (LOCATION *) NULL, &err_code) ); } else { /* ** If current user is not the same as service user and ingres is not ** running as a service, check if shared memory segment is owned ** by current user, if user has access to shared segment allow him ** to run the command. */ PTR shmem; SIZE_TYPE allocated_pages=0; STATUS status; if((status = MEget_pages(ME_MSHARED_MASK, 1, "lglkdata.mem", &shmem, &allocated_pages, &err_code)) == OK) { STprintf(ServiceName, "%s_Database_%s", SYSTEM_SERVICE_NAME, tchII_INSTALLATION); if ((schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) != NULL) { if ((OpIngSvcHandle = OpenService(schSCManager, ServiceName, SERVICE_QUERY_STATUS)) != NULL) { if (QueryServiceStatus(OpIngSvcHandle,lpssServiceStatus)) { if (ssServiceStatus.dwCurrentState != SERVICE_STOPPED) bServiceStarted = TRUE; } } } if (!bServiceStarted) return(PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT, (LOCATION *) NULL, &err_code) ); } } /* ** See if this command is an Ingres command which needs to interact ** with at least one database. */ for (i = 0; validSetuidDbCmds[i] ; i++) { if (STbcompare( cmdbuf, cmdlen, validSetuidDbCmds[i], (i4)STlength(validSetuidDbCmds[i]), FALSE ) == 0) { SetuidDbCmd = TRUE; break; } } /* ** If the user has access to the Ingres shared memory segment, ** just spawn the command provided that it is not in the ** validSetuidDbCmds list. */ if (!SetuidDbCmd) { PTR shmem; SIZE_TYPE allocated_pages=0; STATUS status; if (((status = MEget_pages(ME_MSHARED_MASK, 1, "lglkdata.mem", &shmem, &allocated_pages, &err_code)) == OK) || (status == ME_NO_SUCH_SEGMENT)) { if (status != ME_NO_SUCH_SEGMENT) MEfree_pages(shmem, allocated_pages, &err_code); return( PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT, (LOCATION *) NULL, &err_code) ); } } } /* ** We must run the command through the Ingres service. */ if ( STstrindex(cmdbuf, "-silent", 0, FALSE ) ) SilentMode = TRUE; iimksec(&sa); GVshobj(&ObjectPrefix); STprintf(SetuidShmName, "%s%sSetuidShm", ObjectPrefix, tchII_INSTALLATION); if ( (SetuidShmHandle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, SetuidShmName)) == NULL ) { error_exit(GetLastError()); return(FAIL); } if ( (SetuidShmPtr = MapViewOfFile(SetuidShmHandle, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, sizeof(struct SETUID_SHM))) == NULL ) { error_exit(GetLastError()); return(FAIL); } /* Set up the information to send to the service. */ STcopy(cmdbuf, setuid.cmdline); GetCurrentDirectory(sizeof(setuid.WorkingDirectory), setuid.WorkingDirectory); NMgtAt("II_TEMPORARY", &temp_loc); drType = GetDriveType(NULL); if (drType == DRIVE_REMOTE) { STcopy(temp_loc, setuid.WorkingDirectory); } SaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); CVla(GetCurrentProcessId(), setuid.ClientProcID); STprintf(SetuidPipeName, "\\\\.\\PIPE\\INGRES\\%s\\SETUID", inst_id); /* Set up the stdout file for the command. */ STprintf(OutfileName, "%s\\%sstdout.tmp", temp_loc, setuid.ClientProcID); if ( (OutFile = CreateFile(OutfileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ) { error_exit(GetLastError()); return(FAIL); } /* Set up the stdin file for the command. */ STprintf(InfileName, "%s\\%sstdin.tmp", temp_loc, setuid.ClientProcID); if ( (InFile = CreateFile(InfileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL)) == INVALID_HANDLE_VALUE ) { error_exit(GetLastError()); return(FAIL); } /* Wait until the service is ready to process our request. */ while (SetuidShmPtr->pending == TRUE) PCsleep(100); SetuidShmPtr->pending = TRUE; /* Trigger the "setuid" event of the service. */ if ( (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) == NULL) { error_exit(GetLastError()); return(FAIL); } STprintf(ServiceName, "%s_Database_%s", SYSTEM_SERVICE_NAME, tchII_INSTALLATION ); OpIngSvcHandle = OpenService(schSCManager, ServiceName, SERVICE_USER_DEFINED_CONTROL); if (OpIngSvcHandle == NULL) { STprintf(ServiceName, "%s_DBATools_%s", SYSTEM_SERVICE_NAME, tchII_INSTALLATION ); OpIngSvcHandle = OpenService(schSCManager, ServiceName, SERVICE_USER_DEFINED_CONTROL); } if ( OpIngSvcHandle == NULL) { error_exit(GetLastError()); return(FAIL); } if (!ControlService(OpIngSvcHandle, RUN_COMMAND_AS_INGRES, lpssServiceStatus)) { error_exit(GetLastError()); CloseServiceHandle(schSCManager); return(FAIL); } WaitNamedPipe(SetuidPipeName, NMPWAIT_WAIT_FOREVER); /* Send the information to the service. */ if ( (Setuid_Handle = CreateFile(SetuidPipeName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ) { error_exit(GetLastError()); return(FAIL); } if (!WriteFile(Setuid_Handle, &setuid, sizeof(struct SETUID), &BytesWritten, NULL)) { error_exit(GetLastError()); return(FAIL); } /* ** Retrieve information back from the service, and then ** disconnect from the pipe. */ if (!ReadFile(Setuid_Handle, &setuid, sizeof(struct SETUID), &BytesRead, NULL)) { error_exit(GetLastError()); return(FAIL); } ProcID = setuid.CreatedProcID; SetuidShmPtr->pending = FALSE; UnmapViewOfFile(SetuidShmPtr); SetuidShmPtr = NULL; CloseHandle(SetuidShmHandle); if ( (ProcID != -1) && (ProcID != -2) ) { /* ** Wait for the "spawned" process to exit, reading its output ** from the stdout file. */ for (;;) { if ( ((!ReadFile(OutFile, OutBuf, sizeof(OutBuf), &BytesRead, NULL) || (BytesRead == 0)) && setuid.ExitCode != STILL_ACTIVE )) break; if ( BytesRead && (!WriteFile(SaveStdout, OutBuf, BytesRead, &BytesWritten, NULL)) && setuid.ExitCode != STILL_ACTIVE) break; else if (BytesRead < sizeof(OutBuf)) PCsleep(200); /* ** Currently, the only DBA program which can require ** user input is verifydb. Therefore, when it spits out ** the appropriate messages asking for user input, get ** it from the end user and pass it along to the spawned ** process. */ if ( (STrstrindex(OutBuf, "S_DU04FF_CONTINUE_PROMPT", 0, FALSE) != NULL) || (STrstrindex(OutBuf, "S_DU0300_PROMPT", 0, FALSE) != NULL) ) { SIflush(stdout); MEfill(sizeof(OutBuf), ' ', &OutBuf); MEfill(sizeof(InBuf), ' ', &InBuf); SIgetrec(InBuf, 255, 0); WriteFile(InFile, InBuf, sizeof(OutBuf), &BytesWritten, NULL); } } ExitCode = setuid.ExitCode; CloseHandle(Setuid_Handle); CloseHandle(InFile); DeleteFile(InfileName); CloseHandle(OutFile); DeleteFile(OutfileName); CloseServiceHandle(OpIngSvcHandle); CloseServiceHandle(schSCManager); return(ExitCode); } else { error_exit(GetLastError()); return(FAIL); } }
void Diagnostics::run() { QString info; QTextStream s( &info ); s << "<b>" << tr("Locale (time-, number format / codepage):") << "</b> "; QLocale::Language language = QLocale::system().language(); QString locale = (language == QLocale::C ? "English/United States" : QLocale::languageToString( language ) ); CPINFOEX CPInfoEx; if( GetCPInfoEx( GetConsoleCP(), 0, &CPInfoEx ) != 0 ) locale.append( " / " ).append( QString( (QChar*)CPInfoEx.CodePageName ) ); s << locale << "<br />"; emit update( info ); info.clear(); s << "<b>" << tr("User rights: ") << "</b>" << getUserRights() << "<br />"; emit update( info ); info.clear(); QStringList base = Common::packages( QStringList() << "Eesti ID-kaardi tarkvara", false ); if( !base.isEmpty() ) s << "<b>" << tr("Base version:") << "</b> " << base.join( "<br />" ) << "<br />"; s << "<b>" << tr("Application version:") << "</b> "<< QCoreApplication::applicationVersion() #ifdef INTERNATIONAL << " INTERNATIONAL" #endif << "<br />"; emit update( info ); info.clear(); s << "<b>" << tr("OS:") << "</b> " << Common::applicationOs() << "<br />"; SYSTEM_INFO sysinfo; GetSystemInfo( &sysinfo ); s << "<b>" << tr("CPU:") << "</b> " << QString::number( sysinfo.dwProcessorType ) << "<br /><br />"; emit update( info ); info.clear(); s << "<b>" << tr("URLs:") << "</b>"; const QHash<QString,QString> urls = qApp->urls(); for(auto i = urls.constBegin(); i != urls.constEnd(); ++i) s << "<br />" << i.key() << ": " << i.value(); s << "<br /><br />"; s << "<b>" << tr("Arguments:") << "</b> " << qApp->arguments().join(" ") << "<br />"; s << "<b>" << tr("Library paths:") << "</b> " << QCoreApplication::libraryPaths().join( ";" ) << "<br />"; s << "<b>" << tr("Libraries") << ":</b><br />" << "QT (" << qVersion() << ")<br />"; Q_FOREACH( const QString &lib, QStringList() << "digidoc" << "digidocpp" << "qdigidocclient.exe" << "qesteidutil.exe" << "id-updater.exe" << "esteidcsp" << "esteidcm" << "EsteidShellExtension" << "esteid-plugin-ie" << "npesteid-firefox-plugin" << "opensc-pkcs11" << "esteid-pkcs11" << "libeay32" << "ssleay32" << "advapi32" << "crypt32" << "winscard" ) { DWORD infoHandle = 0; LONG sz = GetFileVersionInfoSize( LPCWSTR(lib.utf16()), &infoHandle ); if( !sz ) continue; QByteArray data( sz * 2, 0 ); if( !GetFileVersionInfoW( LPCWSTR(lib.utf16()), 0, sz, data.data() ) ) continue; VS_FIXEDFILEINFO *info = 0; UINT len = 0; if( !VerQueryValueW( data.constData(), L"\\", (LPVOID*)&info, &len ) ) continue; s << QString( "%1 (%2.%3.%4.%5)" ).arg( lib ) .arg( HIWORD(info->dwFileVersionMS) ) .arg( LOWORD(info->dwFileVersionMS) ) .arg( HIWORD(info->dwFileVersionLS) ) .arg( LOWORD(info->dwFileVersionLS) ) << "<br />"; } s << "<br />"; emit update( info ); info.clear(); enum { Running, Stopped, NotFound } atrfiltr = NotFound, certprop = NotFound; if( SC_HANDLE h = OpenSCManager( 0, 0, SC_MANAGER_CONNECT ) ) { if( SC_HANDLE s = OpenService( h, L"atrfiltr", SERVICE_QUERY_STATUS ) ) { SERVICE_STATUS status; QueryServiceStatus( s, &status ); atrfiltr = (status.dwCurrentState == SERVICE_RUNNING) ? Running : Stopped; CloseServiceHandle( s ); } if( SC_HANDLE s = OpenService( h, L"CertPropSvc", SERVICE_QUERY_STATUS )) { SERVICE_STATUS status; QueryServiceStatus( s, &status ); certprop = (status.dwCurrentState == SERVICE_RUNNING) ? Running : Stopped; CloseServiceHandle( s ); } CloseServiceHandle( h ); } s << "<br /><b>" << tr("ATRfiltr service status: ") << "</b>" << " "; switch( atrfiltr ) { case NotFound: s << tr("Not found"); break; case Stopped: s << tr("Not running"); break; case Running: s << tr("Running"); break; } s << "<br /><b>" << tr("Certificate Propagation service status: ") << "</b>" << " "; switch( certprop ) { case NotFound: s << tr("Not found"); break; case Stopped: s << tr("Not running"); break; case Running: s << tr("Running"); break; } s << "<br />"; getReaderInfo( s ); emit update( info ); info.clear(); QStringList browsers = Common::packages( QStringList() << "Firefox" << "Google Chrome" ); QSettings reg( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Internet Explorer", QSettings::NativeFormat ); browsers << QString( "Internet Explorer (%1)" ).arg( reg.value("svcVersion", reg.value( "Version" ) ).toString() ); s << "<br /><br /><b>" << tr("Browsers:") << "</b><br />" << browsers.join( "<br />" ) << "<br /><br />"; emit update( info ); info.clear(); }
/**************************************************************************** * * FUNCTION: StartDriver( IN SC_HANDLE, IN LPCTSTR) * * PURPOSE: Starts the driver service. * ****************************************************************************/ BOOL StartDriver( IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName ) { SC_HANDLE schService; BOOL ret; SERVICE_STATUS ServiceStatus; char LogZeile[128]; DWORD Service_Error ; schService = OpenService( SchSCManager, DriverName, SERVICE_ALL_ACCESS ); if ( schService == NULL ) { Service_Error = GetLastError(); sprintf(LogZeile,"OpenService %s Fail ( Return %x ",DriverName,Service_Error); if ( Service_Error == ERROR_ACCESS_DENIED ) strcat(LogZeile,"ACCESS_DENIED"); else if ( Service_Error == ERROR_INVALID_HANDLE ) strcat(LogZeile,"INVALID_HANDLE"); else if ( Service_Error == ERROR_INVALID_NAME ) strcat(LogZeile,"INVALID_NAME"); else if ( Service_Error == ERROR_SERVICE_DOES_NOT_EXIST ) strcat(LogZeile,"SERVICE_DOES_NOT_EXIST"); strcat(LogZeile,")"); Write_Log(LogZeile); return(FALSE); }; if ( QueryServiceStatus(schService,&ServiceStatus ) == FALSE ) { Service_Error = GetLastError(); sprintf(LogZeile,"QueryServiceStatus %s Fail ( Return %x ",DriverName,Service_Error); if ( Service_Error == ERROR_ACCESS_DENIED ) strcat(LogZeile,"ACCESS_DENIED"); else if ( Service_Error == ERROR_INVALID_HANDLE ) strcat(LogZeile,"INVALID_HANDLE"); strcat(LogZeile,")"); Write_Log(LogZeile); CloseServiceHandle( schService ); return(FALSE); }; if ( ServiceStatus.dwCurrentState == SERVICE_RUNNING ) return(TRUE); ret = StartService( schService, 0, NULL ); if ( ret == FALSE ) { Service_Error = GetLastError(); if( Service_Error == ERROR_SERVICE_ALREADY_RUNNING) { CloseServiceHandle( schService ); return(TRUE); } else { sprintf(LogZeile,"StartService %s Fail ( Return %x ",DriverName,Service_Error); if ( Service_Error == ERROR_ACCESS_DENIED ) strcat(LogZeile,"ACCESS_DENIED"); else if ( Service_Error == ERROR_INVALID_HANDLE ) strcat(LogZeile,"INVALID_HANDLE"); else if ( Service_Error == ERROR_PATH_NOT_FOUND ) strcat(LogZeile,"PATH_NOT_FOUND"); else if ( Service_Error == ERROR_SERVICE_DATABASE_LOCKED ) strcat(LogZeile,"SERVICE_DATABASE_LOCKED"); else if ( Service_Error == ERROR_SERVICE_DEPENDENCY_DELETED ) strcat(LogZeile,"DEPENDENCY_DELETED"); else if ( Service_Error == ERROR_SERVICE_DEPENDENCY_FAIL ) strcat(LogZeile,"DEPENDENCY_FAIL"); else if ( Service_Error == ERROR_SERVICE_DISABLED ) strcat(LogZeile,"SERVICE_DISABLED"); else if ( Service_Error == ERROR_SERVICE_LOGON_FAILED ) strcat(LogZeile,"SERVICE_LOGON_FAILED"); else if ( Service_Error == ERROR_SERVICE_MARKED_FOR_DELETE ) strcat(LogZeile,"SERVICE_MARKED_FOR_DELETE"); else if ( Service_Error == ERROR_SERVICE_NO_THREAD ) strcat(LogZeile,"SERVICE_NO_THREAD"); else if ( Service_Error == ERROR_SERVICE_REQUEST_TIMEOUT ) strcat(LogZeile,"SERVICE_REQUEST_TIMEOUT"); strcat(LogZeile,")"); Write_Log(LogZeile); RemoveDriver(SchSCManager, DriverName); return(FALSE); } } CloseServiceHandle( schService ); return ret; }
void driver::load(const std::wstring &name, const std::wstring &file, const std::wstring &devfile) { if(m_loaded) throw std::exception("driver already loaded", 0); m_name = name; m_file = file; m_devfile = devfile; SC_HANDLE manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(!manager) throw win32_error("OpenSCManager"); SC_HANDLE service = CreateService(manager, m_name.c_str(), m_name.c_str(), SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, m_file.c_str(), NULL, NULL, NULL, NULL, NULL); if(!service) { service = OpenService(manager, m_name.c_str(), SERVICE_ALL_ACCESS); if(!service) { DWORD err = GetLastError(); CloseServiceHandle(manager); throw win32_error("OpenService", err); } // make sure it has the same path as m_file. DWORD bytes; BOOL ret = QueryServiceConfig(service, NULL, 0, &bytes); DWORD err; if(ret || (err = GetLastError()) != ERROR_INSUFFICIENT_BUFFER) { CloseServiceHandle(service); CloseServiceHandle(manager); throw win32_error("QueryServiceConfig"); } QUERY_SERVICE_CONFIG *qsc = (QUERY_SERVICE_CONFIG*)malloc(bytes); if(!qsc) { CloseServiceHandle(service); CloseServiceHandle(manager); throw std::bad_alloc("unable to allocate memory for QueryServiceConfig"); } ret = QueryServiceConfig(service, qsc, bytes, &bytes); if(!ret) { CloseServiceHandle(service); CloseServiceHandle(manager); throw win32_error("QueryServiceConfig"); } bool del = _wcsicmp(qsc->lpBinaryPathName, m_file.c_str()) != 0; free(qsc); // paths don't match, remove service and recreate. if(del) { // if it's not removable, bail out. if(!this->removable) { CloseServiceHandle(service); CloseServiceHandle(manager); throw std::exception("unremovable service mismatch", 0); } // check if its running SERVICE_STATUS status; ret = QueryServiceStatus(service, &status); if(!ret) { DWORD err = GetLastError(); CloseServiceHandle(service); CloseServiceHandle(manager); throw win32_error("QueryServiceStatus", err); } // and stop it if it is. if(status.dwCurrentState != SERVICE_STOPPED && status.dwCurrentState != SERVICE_STOP_PENDING) { ret = ControlService(service, SERVICE_CONTROL_STOP, &status); if(!ret) { DWORD err = GetLastError(); CloseServiceHandle(service); CloseServiceHandle(manager); throw win32_error("ControlService", err); } } // now delete the service. ret = DeleteService(service); CloseServiceHandle(service); if(!ret && (err = GetLastError()) != ERROR_SERVICE_MARKED_FOR_DELETE) { CloseServiceHandle(manager); throw win32_error("DeleteService", err); } // finally recreate it. service = CreateService(manager, m_name.c_str(), m_name.c_str(), SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, m_file.c_str(), NULL, NULL, NULL, NULL, NULL); if(!service) { CloseServiceHandle(manager); throw win32_error("CreateService", err); } } } SERVICE_STATUS status; if(QueryServiceStatus(service, &status)) { m_started = (status.dwCurrentState == SERVICE_RUNNING); } CloseServiceHandle(service); CloseServiceHandle(manager); m_loaded = true; }
static BOOL DokanServiceControl(LPCWSTR ServiceName, ULONG Type) { SC_HANDLE controlHandle; SC_HANDLE serviceHandle; SERVICE_STATUS ss; BOOL result = TRUE; controlHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (controlHandle == NULL) { DokanDbgPrint("DokanServiceControl: Failed to open Service Control " "Manager. error = %d\n", GetLastError()); return FALSE; } serviceHandle = OpenService(controlHandle, ServiceName, SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE); if (serviceHandle == NULL) { DokanDbgPrintW( L"DokanServiceControl: Failed to open Service (%s). error = %d\n", ServiceName, GetLastError()); CloseServiceHandle(controlHandle); return FALSE; } QueryServiceStatus(serviceHandle, &ss); if (Type == DOKAN_SERVICE_DELETE) { if (DeleteService(serviceHandle)) { DokanDbgPrintW(L"DokanServiceControl: Service (%s) deleted\n", ServiceName); result = TRUE; } else { DokanDbgPrintW( L"DokanServiceControl: Failed to delete service (%s). error = %d\n", ServiceName, GetLastError()); result = FALSE; } } else if (ss.dwCurrentState == SERVICE_STOPPED && Type == DOKAN_SERVICE_START) { if (StartService(serviceHandle, 0, NULL)) { DokanDbgPrintW(L"DokanServiceControl: Service (%s) started\n", ServiceName); result = TRUE; } else { DokanDbgPrintW( L"DokanServiceControl: Failed to start service (%s). error = %d\n", ServiceName, GetLastError()); result = FALSE; } } else if (ss.dwCurrentState == SERVICE_RUNNING && Type == DOKAN_SERVICE_STOP) { if (ControlService(serviceHandle, SERVICE_CONTROL_STOP, &ss)) { DokanDbgPrintW(L"DokanServiceControl: Service (%s) stopped\n", ServiceName); result = TRUE; } else { DokanDbgPrintW( L"DokanServiceControl: Failed to stop service (%s). error = %d\n", ServiceName, GetLastError()); result = FALSE; } } CloseServiceHandle(serviceHandle); CloseServiceHandle(controlHandle); Sleep(100); return result; }
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { if( lpCmdLine[0] == _T('-') || lpCmdLine[0] == _T('/') ){ if( lstrcmpi(_T("install"), lpCmdLine + 1) == 0 ){ bool installed = false; TCHAR exePath[512]; if( GetModuleFileName(NULL, exePath, _countof(exePath)) != 0 ){ SC_HANDLE hScm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE); if( hScm != NULL ){ SC_HANDLE hSrv = CreateService( hScm, SERVICE_NAME, SERVICE_NAME, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, exePath, NULL, NULL, NULL, NULL, NULL); if( hSrv != NULL ){ installed = true; CloseServiceHandle(hSrv); } CloseServiceHandle(hScm); } } if( installed == false ){ //コンソールがないのでメッセージボックスで伝える MessageBox(NULL, L"Failed to install/remove " SERVICE_NAME L".\r\nRun as Administrator on Vista and later.", NULL, MB_ICONERROR); } return 0; }else if( lstrcmpi(_T("remove"), lpCmdLine + 1) == 0 ){ bool removed = false; SC_HANDLE hScm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if( hScm != NULL ){ SC_HANDLE hSrv = OpenService(hScm, SERVICE_NAME, DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS); if( hSrv != NULL ){ SERVICE_STATUS srvStatus; if( QueryServiceStatus(hSrv, &srvStatus) != FALSE ){ if( srvStatus.dwCurrentState == SERVICE_STOPPED || ControlService(hSrv, SERVICE_CONTROL_STOP, &srvStatus) != FALSE ){ removed = DeleteService(hSrv) != FALSE; } } CloseServiceHandle(hSrv); } CloseServiceHandle(hScm); } if( removed == false ){ MessageBox(NULL, L"Failed to install/remove " SERVICE_NAME L".\r\nRun as Administrator on Vista and later.", NULL, MB_ICONERROR); } return 0; } } if( IsInstallService(SERVICE_NAME) == FALSE ){ //普通にexeとして起動を行う HANDLE hMutex = CreateMutex(NULL, TRUE, EPG_TIMER_BON_SRV_MUTEX); if( hMutex != NULL ){ if( GetLastError() != ERROR_ALREADY_EXISTS ){ StartDebugLog(); //メインスレッドに対するCOMの初期化 CoInitialize(NULL); CEpgTimerSrvMain* pMain = new CEpgTimerSrvMain; if( pMain->Main(false) == false ){ OutputDebugString(_T("_tWinMain(): Failed to start\r\n")); } delete pMain; CoUninitialize(); StopDebugLog(); } ReleaseMutex(hMutex); CloseHandle(hMutex); } }else if( IsStopService(SERVICE_NAME) == FALSE ){ //サービスとして実行 HANDLE hMutex = CreateMutex(NULL, TRUE, EPG_TIMER_BON_SRV_MUTEX); if( hMutex != NULL ){ if( GetLastError() != ERROR_ALREADY_EXISTS ){ StartDebugLog(); SERVICE_TABLE_ENTRY dispatchTable[] = { { SERVICE_NAME, service_main }, { NULL, NULL } }; if( StartServiceCtrlDispatcher(dispatchTable) == FALSE ){ OutputDebugString(_T("_tWinMain(): StartServiceCtrlDispatcher failed\r\n")); } StopDebugLog(); } ReleaseMutex(hMutex); CloseHandle(hMutex); } }else{ //Stop状態なのでサービスの開始を要求 bool started = false; SC_HANDLE hScm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if( hScm != NULL ){ SC_HANDLE hSrv = OpenService(hScm, SERVICE_NAME, SERVICE_START); if( hSrv != NULL ){ started = StartService(hSrv, 0, NULL) != FALSE; CloseServiceHandle(hSrv); } CloseServiceHandle(hScm); } if( started == false ){ OutputDebugString(_T("_tWinMain(): Failed to start\r\n")); } } return 0; }
// // FUNCTION: UninstallService // // PURPOSE: Stop and remove the service from the local service control // manager database. // // PARAMETERS: // * pszServiceName - the name of the service to be removed. // // NOTE: If the function fails to uninstall the service, it prints the // error in the standard output stream for users to diagnose the problem. // void UninstallService(PWSTR pszServiceName) { SC_HANDLE schSCManager = NULL; SC_HANDLE schService = NULL; SERVICE_STATUS ssSvcStatus = {}; // Open the local default service control manager database schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (schSCManager == NULL) { wprintf(L"OpenSCManager failed w/err 0x%08lx\n", GetLastError()); goto Cleanup; } // Open the service with delete, stop, and query status permissions schService = OpenService(schSCManager, pszServiceName, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE); if (schService == NULL) { wprintf(L"OpenService failed w/err 0x%08lx\n", GetLastError()); goto Cleanup; } // Try to stop the service if (ControlService(schService, SERVICE_CONTROL_STOP, &ssSvcStatus)) { wprintf(L"Stopping %s.", pszServiceName); Sleep(1000); while (QueryServiceStatus(schService, &ssSvcStatus)) { if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING) { wprintf(L"."); Sleep(1000); } else break; } if (ssSvcStatus.dwCurrentState == SERVICE_STOPPED) { wprintf(L"\n%s is stopped.\n", pszServiceName); } else { wprintf(L"\n%s failed to stop.\n", pszServiceName); } } // Now remove the service by calling DeleteService. if (!DeleteService(schService)) { wprintf(L"DeleteService failed w/err 0x%08lx\n", GetLastError()); goto Cleanup; } wprintf(L"%s is removed.\n", pszServiceName); Cleanup: // Centralized cleanup for all allocated resources. if (schSCManager) { CloseServiceHandle(schSCManager); schSCManager = NULL; } if (schService) { CloseServiceHandle(schService); schService = NULL; } }
int SERVICE_STATE(AGENT_REQUEST *request, AGENT_RESULT *result) { SC_HANDLE mgr, service; char *name; wchar_t *wname; wchar_t service_name[MAX_STRING_LEN]; DWORD max_len_name = MAX_STRING_LEN; int i; SERVICE_STATUS status; if (1 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } name = get_rparam(request, 0); if (NULL == name || '\0' == *name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } if (NULL == (mgr = OpenSCManager(NULL, NULL, GENERIC_READ))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information.")); return SYSINFO_RET_FAIL; } wname = zbx_utf8_to_unicode(name); service = OpenService(mgr, wname, SERVICE_QUERY_STATUS); if (NULL == service && 0 != GetServiceKeyName(mgr, wname, service_name, &max_len_name)) service = OpenService(mgr, service_name, SERVICE_QUERY_STATUS); zbx_free(wname); if (NULL == service) { SET_UI64_RESULT(result, 255); } else { if (0 != QueryServiceStatus(service, &status)) { for (i = 0; i < ARRSIZE(service_states) && status.dwCurrentState != service_states[i]; i++) ; SET_UI64_RESULT(result, i); } else SET_UI64_RESULT(result, 7); CloseServiceHandle(service); } CloseServiceHandle(mgr); return SYSINFO_RET_OK; }
int SERVICE_INFO(AGENT_REQUEST *request, AGENT_RESULT *result) { QUERY_SERVICE_CONFIG *qsc = NULL; SERVICE_DESCRIPTION *scd = NULL; SERVICE_STATUS status; SC_HANDLE h_mgr, h_srv; DWORD sz = 0; int param_type, i; char *name, *param; wchar_t *wname, service_name[MAX_STRING_LEN]; DWORD max_len_name = MAX_STRING_LEN; if (2 < request->nparam) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); return SYSINFO_RET_FAIL; } name = get_rparam(request, 0); param = get_rparam(request, 1); if (NULL == name || '\0' == *name) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); return SYSINFO_RET_FAIL; } if (NULL == param || '\0' == *param || 0 == strcmp(param, "state")) /* default second parameter */ param_type = ZBX_SRV_PARAM_STATE; else if (0 == strcmp(param, "displayname")) param_type = ZBX_SRV_PARAM_DISPLAYNAME; else if (0 == strcmp(param, "path")) param_type = ZBX_SRV_PARAM_PATH; else if (0 == strcmp(param, "user")) param_type = ZBX_SRV_PARAM_USER; else if (0 == strcmp(param, "startup")) param_type = ZBX_SRV_PARAM_STARTUP; else if (0 == strcmp(param, "description")) param_type = ZBX_SRV_PARAM_DESCRIPTION; else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); return SYSINFO_RET_FAIL; } if (NULL == (h_mgr = OpenSCManager(NULL, NULL, GENERIC_READ))) { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information.")); return SYSINFO_RET_FAIL; } wname = zbx_utf8_to_unicode(name); h_srv = OpenService(h_mgr, wname, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); if (NULL == h_srv && 0 != GetServiceKeyName(h_mgr, wname, service_name, &max_len_name)) h_srv = OpenService(h_mgr, service_name, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); zbx_free(wname); if (NULL == h_srv) { int ret; if (ZBX_SRV_PARAM_STATE == param_type) { SET_UI64_RESULT(result, 255); ret = SYSINFO_RET_OK; } else { SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot find the specified service.")); ret = SYSINFO_RET_FAIL; } CloseServiceHandle(h_mgr); return ret; } if (ZBX_SRV_PARAM_STATE == param_type) { if (0 != QueryServiceStatus(h_srv, &status)) { for (i = 0; i < ARRSIZE(service_states) && status.dwCurrentState != service_states[i]; i++) ; SET_UI64_RESULT(result, i); } else SET_UI64_RESULT(result, 7); } else if (ZBX_SRV_PARAM_DESCRIPTION == param_type) { QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &sz); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s", strerror_from_system(GetLastError()))); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } scd = (SERVICE_DESCRIPTION *)zbx_malloc(scd, sz); if (0 == QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)scd, sz, &sz)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s", strerror_from_system(GetLastError()))); zbx_free(scd); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } if (NULL == scd->lpDescription) SET_TEXT_RESULT(result, zbx_strdup(NULL, "")); else SET_TEXT_RESULT(result, zbx_unicode_to_utf8(scd->lpDescription)); zbx_free(scd); } else { QueryServiceConfig(h_srv, NULL, 0, &sz); if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s", strerror_from_system(GetLastError()))); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } qsc = (QUERY_SERVICE_CONFIG *)zbx_malloc(qsc, sz); if (0 == QueryServiceConfig(h_srv, qsc, sz, &sz)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s", strerror_from_system(GetLastError()))); zbx_free(qsc); CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_FAIL; } switch (param_type) { case ZBX_SRV_PARAM_DISPLAYNAME: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpDisplayName)); break; case ZBX_SRV_PARAM_PATH: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpBinaryPathName)); break; case ZBX_SRV_PARAM_USER: SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpServiceStartName)); break; case ZBX_SRV_PARAM_STARTUP: if (SERVICE_AUTO_START == qsc->dwStartType) { if (SUCCEED == check_delayed_start(h_srv)) SET_UI64_RESULT(result, 1); else SET_UI64_RESULT(result, 0); } else { for (i = 2; i < ARRSIZE(start_types) && qsc->dwStartType != start_types[i]; i++) ; SET_UI64_RESULT(result, i); } break; } zbx_free(qsc); } CloseServiceHandle(h_srv); CloseServiceHandle(h_mgr); return SYSINFO_RET_OK; }
static void unregister_service(int argc, char *argv[]) { SC_HANDLE service, scm; BOOL success; SERVICE_STATUS status; sw_debug(SW_LOG_NOTICE, "starting...\n"); // // Open a connection to the SCM // scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); if (!scm) { service_error_handler("In OpenScManager", GetLastError()); exit(0); } // Get the service's handle service = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS | DELETE); if (!service) { service_error_handler("In OpenService", GetLastError()); } // // Stop the service if necessary // success = QueryServiceStatus(service, &status); if (!success) { service_error_handler("In QueryServiceStatus", GetLastError()); } if (status.dwCurrentState != SERVICE_STOPPED) { sw_debug(SW_LOG_NOTICE, "stopping service...\n"); success = ControlService(service, SERVICE_CONTROL_STOP, &status); if (!success) { service_error_handler("In ControlService", GetLastError()); } Sleep(500); } // // Remove the service // success = DeleteService(service); if (success) { sw_debug(SW_LOG_NOTICE, "service unregistered\n"); } else { service_error_handler("DeleteService", GetLastError()); } // // Clean up // CloseServiceHandle(service); CloseServiceHandle(scm); }
// // FUNCTION: CmdRemoveService() // // PURPOSE: Stops and removes the service // // PARAMETERS: // none // // RETURN VALUE: // 0 if success // // COMMENTS: // int CmdRemoveService() { SC_HANDLE schService; SC_HANDLE schSCManager; int ret = 0; schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_CONNECT // access required ); if ( schSCManager ) { schService = OpenService(schSCManager, TEXT(SZSERVICENAME), DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS); if (schService) { // try to stop the service if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) ) { _tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME)); Sleep( 1000 ); while ( QueryServiceStatus( schService, &ssStatus ) ) { if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING ) { _tprintf(TEXT(".")); Sleep( 1000 ); } else break; } if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) _tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) ); else { _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) ); ret = 1; } } // now remove the service if ( DeleteService(schService) ) _tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) ); else { _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256)); ret = 1; } CloseServiceHandle(schService); } else { _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256)); ret = 1; } CloseServiceHandle(schSCManager); } else { _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256)); ret = 1; } return ret; }
static INT_PTR CALLBACK EspRestartServiceDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PRESTART_SERVICE_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PRESTART_SERVICE_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PRESTART_SERVICE_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { PhCenterWindow(hwndDlg, GetParent(hwndDlg)); // TODO: Use the progress information. PhSetWindowStyle(GetDlgItem(hwndDlg, IDC_PROGRESS), PBS_MARQUEE, PBS_MARQUEE); SendMessage(GetDlgItem(hwndDlg, IDC_PROGRESS), PBM_SETMARQUEE, TRUE, 75); SetDlgItemText(hwndDlg, IDC_MESSAGE, PhaFormatString(L"Attempting to stop %s...", context->ServiceItem->Name->Buffer)->Buffer); if (PhUiStopService(hwndDlg, context->ServiceItem)) { SetTimer(hwndDlg, 1, 250, NULL); } else { EndDialog(hwndDlg, IDCANCEL); } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: { EndDialog(hwndDlg, IDCANCEL); } break; } } break; case WM_TIMER: { if (wParam == 1 && !context->DisableTimer) { SERVICE_STATUS serviceStatus; if (QueryServiceStatus(context->ServiceHandle, &serviceStatus)) { if (!context->Starting && serviceStatus.dwCurrentState == SERVICE_STOPPED) { // The service is stopped, so start the service now. SetDlgItemText(hwndDlg, IDC_MESSAGE, PhaFormatString(L"Attempting to start %s...", context->ServiceItem->Name->Buffer)->Buffer); context->DisableTimer = TRUE; if (PhUiStartService(hwndDlg, context->ServiceItem)) { context->DisableTimer = FALSE; context->Starting = TRUE; } else { EndDialog(hwndDlg, IDCANCEL); } } else if (context->Starting && serviceStatus.dwCurrentState == SERVICE_RUNNING) { EndDialog(hwndDlg, IDOK); } } } } break; } return FALSE; }
int wisvc_StartKublService (int argc, char **argv, SC_HANDLE schService, char *service_name, char *BinaryPathName, int discard_argv) { /* The last two arguments not really needed except for error messages */ int called_as_service = 0; /* Needed by macro err_printf */ int checkpoint_has_stayed_stagnant_n_iterations = 0; SERVICE_STATUS ssStatus; DWORD dwOldCheckPoint = 0, dwOlderCheckPoint = 0; /* err_printf(("StartKublService: argc=%d, argv[0]=%s, argv[1]=%s\n", argc,argv[0],argv[1])); */ if (!StartService (schService, /* handle of service */ (discard_argv ? 0 : (argc - 1)), /* number of arguments */ (discard_argv ? NULL : (argv + 1)))) /* Arg vector from main */ { /* without argv[0] */ DWORD erhe = GetLastError (); err_printf (( "%s: Starting service \"%s\" (path: \"%s\") failed. " "StartService returned zero, errno=%ld%s\n", argv[0], service_name, BinaryPathName, erhe, ((ERROR_SERVICE_ALREADY_RUNNING == erhe) ? " because service has been already started!" : ".") )); return (0); } else { err_printf (("Service %s start in progress, BinaryPathName=%s\n", service_name, BinaryPathName)); } /* Check the status until the service is running. */ if (!QueryServiceStatus (schService, /* handle of service */ &ssStatus)) /* address of status info */ { DWORD erhe = GetLastError (); err_printf (( "%s: Querying status of service \"%s\" (path: \"%s\") failed. " "QueryServiceStatus returned zero, errno=%ld.\n", argv[0], service_name, BinaryPathName, erhe)); return (0); } Sleep (10); /* First sleep ten seconds. */ while (ssStatus.dwCurrentState != SERVICE_RUNNING) { if (SERVICE_STOPPED == ssStatus.dwCurrentState) { break; } dwOlderCheckPoint = dwOldCheckPoint; dwOldCheckPoint = ssStatus.dwCheckPoint; /* Save current checkpoint */ if (ssStatus.dwWaitHint > 300) { ssStatus.dwWaitHint = 300; } Sleep (ssStatus.dwWaitHint); /* Wait for the specified interval. */ /* Check the status again. */ if (!QueryServiceStatus (schService, &ssStatus)) { break; } /* err_printf(( "dwOlderCheckPoint=%ld, dwOldCheckPoint=%ld, ssStatus.dwCheckPoint=%ld, ssStatus.dwWaitHint=%ld\n", dwOlderCheckPoint, dwOldCheckPoint, ssStatus.dwCheckPoint, ssStatus.dwWaitHint)); */ /* Break if the checkpoint has not been incremented for three times. */ if ((dwOldCheckPoint >= ssStatus.dwCheckPoint) && (dwOlderCheckPoint >= ssStatus.dwCheckPoint)) { if (++checkpoint_has_stayed_stagnant_n_iterations > 3) { break; } } checkpoint_has_stayed_stagnant_n_iterations = 0; } if (ssStatus.dwCurrentState == SERVICE_RUNNING) { { err_printf (( "%s: Service \"%s\" started successfully (path: \"%s\").\n", argv[0], service_name, BinaryPathName)); } return (1); } else { err_printf (( "%s: Service \"%s\" (path: \"%s\") %s started correctly.\n", argv[0], service_name, BinaryPathName, ((SERVICE_START_PENDING != ssStatus.dwCurrentState) ? "has not" : "may or may not have"))); err_printf ((" Current State: %d\n", ssStatus.dwCurrentState)); err_printf ((" Exit Code: %d\n", ssStatus.dwWin32ExitCode)); err_printf ((" Service Specific Exit Code: %d\n", ssStatus.dwServiceSpecificExitCode)); err_printf ((" Check Point: %d\n", ssStatus.dwCheckPoint)); err_printf ((" Wait Hint: %d\n", ssStatus.dwWaitHint)); err_printf (( "Please use services icon in Control Panel to see whether service \"%s\" was really started." " Check also the file wi.err in the server's working directory.\n", service_name)); return (0); } }
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 }
void ACE_NT_Service::wait_for_service_state (DWORD desired_state, ACE_Time_Value *wait_time) { DWORD last_state = 0; DWORD last_check_point = 0; int first_time = 1; int service_ok; ACE_Time_Value time_out = ACE_OS::gettimeofday (); if (wait_time != 0) time_out += *wait_time; // Poll until the service reaches the desired state. for (;;) { service_ok = 0 != QueryServiceStatus (this->svc_sc_handle_, &this->svc_status_); // If we cannot query the service, we are done. if (!service_ok) break; // If the service has the desired state, we are done. if (desired_state == this->svc_status_.dwCurrentState) break; // If we time-out, we are done if (wait_time != 0 && ACE_OS::gettimeofday () > time_out ) { errno = ETIME; break; } if (first_time) { // remember the service state, the first time we wait last_state = this->svc_status_.dwCurrentState; last_check_point = this->svc_status_.dwCheckPoint; first_time = 0; } else { // update the state change. if (last_state != this->svc_status_.dwCurrentState) { last_state = this->svc_status_.dwCurrentState; last_check_point = this->svc_status_.dwCheckPoint; } else { // The check-point should have increased if (this->svc_status_.dwCheckPoint > last_check_point) last_check_point = this->svc_status_.dwCheckPoint; else { // Service control failure, we are done. service_ok = 0; break; } } } ::Sleep (this->svc_status_.dwWaitHint); } return; }
int uninstall_service(void) { SC_HANDLE scm, service; SERVICE_STATUS serviceStatus; scm=OpenSCManager(0, 0, SC_MANAGER_CONNECT); if(!scm) { MessageBoxSecure(NULL, "Failed to open service control manager", app_name, MB_ICONERROR); return 1; } service=OpenService(scm, service_name, SERVICE_QUERY_STATUS | DELETE); if(!service) { DWORD myerror=GetLastError(); if (myerror==ERROR_ACCESS_DENIED) { MessageBoxSecure(NULL, "Failed: Permission denied", app_name, MB_ICONERROR); CloseServiceHandle(scm); return 1; } if (myerror==ERROR_SERVICE_DOES_NOT_EXIST) { #if 0 MessageBoxSecure(NULL, "Failed: Service is not installed", app_name, MB_ICONERROR); #endif CloseServiceHandle(scm); return 1; } MessageBoxSecure(NULL, "Failed to open the service", app_name, MB_ICONERROR); CloseServiceHandle(scm); return 1; } if(!QueryServiceStatus(service, &serviceStatus)) { MessageBoxSecure(NULL, "Failed to query service status", app_name, MB_ICONERROR); CloseServiceHandle(service); CloseServiceHandle(scm); return 1; } if(serviceStatus.dwCurrentState!=SERVICE_STOPPED) { //MessageBoxSecure(NULL, "The service is still running, disable it first", // "UltraVnc", MB_ICONERROR); CloseServiceHandle(service); CloseServiceHandle(scm); Sleep(2500);uninstall_service(); return 1; } if(!DeleteService(service)) { MessageBoxSecure(NULL, "Failed to delete the service", app_name, MB_ICONERROR); CloseServiceHandle(service); CloseServiceHandle(scm); return 1; } CloseServiceHandle(service); CloseServiceHandle(scm); return 0; }
VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgSvcStart(LPCWSTR lpszSvcName) { SC_HANDLE hMgr = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_START); if (hMgr == NULL) { DWORD dwErr = GetLastError(); NonStandardLogRelCrap((__FUNCTION__": OpenSCManager failed, dwErr=%ld\n", dwErr)); return HRESULT_FROM_WIN32(dwErr); } HRESULT hr = S_OK; SC_HANDLE hSvc = OpenServiceW(hMgr, lpszSvcName, SERVICE_QUERY_STATUS | SERVICE_START); if (hSvc) { do { SERVICE_STATUS Status; BOOL fRc = QueryServiceStatus(hSvc, &Status); if (!fRc) { DWORD dwErr = GetLastError(); NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%ld\n", dwErr)); hr = HRESULT_FROM_WIN32(dwErr); break; } if (Status.dwCurrentState != SERVICE_RUNNING && Status.dwCurrentState != SERVICE_START_PENDING) { NonStandardLogRelCrap(("Starting service (%S)\n", lpszSvcName)); fRc = StartService(hSvc, 0, NULL); if (!fRc) { DWORD dwErr = GetLastError(); NonStandardLogRelCrap((__FUNCTION__": StartService failed dwErr=%ld\n", dwErr)); hr = HRESULT_FROM_WIN32(dwErr); break; } } fRc = QueryServiceStatus(hSvc, &Status); if (!fRc) { DWORD dwErr = GetLastError(); NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%ld\n", dwErr)); hr = HRESULT_FROM_WIN32(dwErr); break; } if (Status.dwCurrentState == SERVICE_START_PENDING) { for (int i = 0; i < VBOXDRVCFG_SVC_WAITSTART_RETRIES; ++i) { Sleep(VBOXDRVCFG_SVC_WAITSTART_TIME_PERIOD); fRc = QueryServiceStatus(hSvc, &Status); if (!fRc) { DWORD dwErr = GetLastError(); NonStandardLogRelCrap((__FUNCTION__": QueryServiceStatus failed dwErr=%ld\n", dwErr)); hr = HRESULT_FROM_WIN32(dwErr); break; } else if (Status.dwCurrentState != SERVICE_START_PENDING) break; } } if (hr != S_OK || Status.dwCurrentState != SERVICE_RUNNING) { NonStandardLogRelCrap((__FUNCTION__": Failed to start the service\n")); hr = E_FAIL; break; } } while (0); CloseServiceHandle(hSvc); } else { DWORD dwErr = GetLastError(); NonStandardLogRelCrap((__FUNCTION__": OpenServiceW failed, dwErr=%ld\n", dwErr)); hr = HRESULT_FROM_WIN32(dwErr); } CloseServiceHandle(hMgr); return hr; }
// // サービスとして起動したかチェック // 実行ファイルのディレクトリと、カレントディレクトリを比較 // out: TRUE .. サービスとして起動したと思われる // BOOL check_execute_service(void) { TCHAR current_path[MAX_PATH]; OSVERSIONINFO ovi; SC_HANDLE scm, sc; SERVICE_STATUS st; DWORD size; LPQUERY_SERVICE_CONFIG qsc; nt_flag = FALSE; service_install_flag = FALSE; service_stop_flag = FALSE; ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&ovi); if(ovi.dwPlatformId == VER_PLATFORM_WIN32_NT) { nt_flag = TRUE; GetCurrentDirectory(MAX_PATH, current_path); // 実行ファイルのパスとカレントパスが違う場合、 // サービスとして起動されたと判定。 // 起動ドライブのルートにこのプログラムが置かれてたり、 // CreateProcess で違うディレクトリで起動されるとまずい // ような気がする。まあ大丈夫でしょう。いいかげん。 if(_tcsicmp(execute_path, current_path)) { SetCurrentDirectory(execute_path); return TRUE; } // サービスインストールチェック if(scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE)) { if(sc = OpenService(scm, service_name, SERVICE_ALL_ACCESS)) { // サービスインストール済み service_install_flag = TRUE; // 2004/8/9 QueryServiceConfig(sc, 0, 0, &size); qsc = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LPTR, size); QueryServiceConfig(sc, qsc, size, &size); if(qsc->dwStartType == SERVICE_AUTO_START) { auto_flag = 1; } else if(qsc->dwStartType == SERVICE_DEMAND_START) { auto_flag = 0; } if(qsc->dwServiceType & SERVICE_INTERACTIVE_PROCESS) { desktop_flag = 1; } else { desktop_flag = 0; } LocalFree(qsc); if(QueryServiceStatus(sc, &st)) { if(st.dwCurrentState != SERVICE_STOPPED) { service_stop_flag = TRUE; } ControlService(sc, SERVICE_CONTROL_STOP, &st); Sleep(500); } else { // サービスを停止できません。\nサービスの権限のあるユーザーでログインしてください。 MessageBoxResourceText(NULL, IDS_ERROR_STOP_SERVICE, NULL, ERROR_HEADER, MB_OK); } CloseServiceHandle(sc); } CloseServiceHandle(scm); } } return FALSE; }
BOOL RunService (LPCTSTR lpszServiceName, DWORD& dwError) { SC_HANDLE schSCManager; SC_HANDLE schService; SERVICE_STATUS svrstatus; memset (&svrstatus, sizeof(svrstatus), 0); // // Connect to service control manager on the local machine and // open the ServicesActive database schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (schSCManager == NULL ) { CString strMsg; dwError = GetLastError(); switch (dwError) { case ERROR_ACCESS_DENIED: case ERROR_DATABASE_DOES_NOT_EXIST: case ERROR_INVALID_PARAMETER: //strMsg = _T("Failed to connect to the Service Control Manager"); AfxMessageBox (VDBA_MfcResourceString(IDS_E_CONNECT_SERVICE)); break; } return FALSE; } // // Check if the Service 'lpszServiceName' is already installed // REGEDT32.EXE can check this on // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services schService = OpenService (schSCManager, lpszServiceName, SERVICE_ALL_ACCESS); if (schService == NULL) return FALSE; if (!StartService (schService, 0, NULL)) { dwError = GetLastError(); return FALSE; } CTime tStarted = CTime::GetCurrentTime(); CTime t = CTime::GetCurrentTime(); CTimeSpan tdiff = t - tStarted; int nTotalSecods = 0; // // Check if the Service 'lpszServiceName' is Running if (!QueryServiceStatus (schService, &svrstatus)) { //CString strMsg = _T("Cannot query the service status information"); AfxMessageBox (VDBA_MfcResourceString(IDS_E_SERVICE_STATUS)); dwError = GetLastError(); return FALSE; } // // Maximum time 20 seconds waiting for the service finishs starting. while (svrstatus.dwCurrentState == SERVICE_START_PENDING && nTotalSecods < 20) { Sleep (200); QueryServiceStatus (schService, &svrstatus); if (svrstatus.dwCurrentState == SERVICE_RUNNING) return TRUE; t = CTime::GetCurrentTime(); tdiff = t - tStarted; nTotalSecods = (int)tdiff.GetTotalSeconds(); } QueryServiceStatus (schService, &svrstatus); if (svrstatus.dwCurrentState =! SERVICE_RUNNING) { dwError = GetLastError(); return FALSE; } else return TRUE; }
bool StartStopWindowsService(std::string sServiceName, int iStartorStop) { bool bResult = false; SC_HANDLE ScManager = NULL; SC_HANDLE ScService = NULL; ScManager=::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS|GENERIC_ALL); if(ScManager == NULL) { bResult = false; } else { ScService =::OpenService(ScManager,sServiceName.data (),SERVICE_ALL_ACCESS); if(ScService == NULL) { DWORD WINAPI errCode = GetLastError(); bResult = false; } else { DWORD dwCurrentState = 0; SERVICE_STATUS lpSERVICE_STATUS = {0}; QueryServiceStatus(ScService, &lpSERVICE_STATUS); switch(lpSERVICE_STATUS.dwCurrentState) { case SERVICE_PAUSED: //service in paused state dwCurrentState = SERVICE_PAUSED; break; case SERVICE_RUNNING: // The service is running. dwCurrentState = SERVICE_RUNNING; break; case SERVICE_STOPPED:// The service is stopped dwCurrentState = SERVICE_STOPPED; break; case SERVICE_START_PENDING: // The service is starting dwCurrentState = SERVICE_START_PENDING; break; case SERVICE_STOP_PENDING : // The service is stopped dwCurrentState = SERVICE_STOP_PENDING; break; default: //unknown state break; } if ( (dwCurrentState == SERVICE_STOPPED || dwCurrentState == SERVICE_PAUSED || dwCurrentState == SERVICE_STOP_PENDING ) && iStartorStop == 1 ) { std::cout << "starting service.."; bResult = (::StartService(ScService,0,NULL) == S_OK); } else if ( (dwCurrentState == SERVICE_RUNNING || dwCurrentState == SERVICE_START_PENDING) && iStartorStop == 0 ) { std::cout << "stopping service.."; bResult = (::ControlService(ScService,SERVICE_CONTROL_STOP,&lpSERVICE_STATUS) != 0); } }// else if(ScService==NULL) }//else if(ScManager==NULL) if (ScManager) ::CloseServiceHandle(ScManager); if (ScService) ::CloseServiceHandle(ScService); return bResult; }
void CSystemService::Install(LPCWSTR displayname) { WCHAR startcmd[MAX_PATH+5]; TCHAR filename[MAX_PATH]; if(0==::GetModuleFileName(nullptr,filename,MAX_PATH)) return; if(0==swprintf_s(startcmd,L"\"%s\" -s",filename))return; SC_HANDLE newService=nullptr, scm=nullptr; SERVICE_STATUS status; __try { scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); if (!scm) __leave; // Install the new service newService = OpenServiceW(scm,ServiceTable[0].lpServiceName,SERVICE_ALL_ACCESS); if(newService) { QUERY_SERVICE_CONFIG* querybuff=nullptr; DWORD bufsz=0; if(QueryServiceConfig(newService,querybuff,0,&bufsz)==FALSE) { if(ERROR_INSUFFICIENT_BUFFER==GetLastError()) { querybuff=(QUERY_SERVICE_CONFIG*)malloc(bufsz); if(querybuff) { if(QueryServiceConfig(newService,querybuff,bufsz,&bufsz)) { wchar_t* firstQuotes=nullptr,*secondQuotes=nullptr; firstQuotes=wcschr(querybuff->lpBinaryPathName,'"'); if(firstQuotes) { secondQuotes=wcschr(firstQuotes+1,'"'); if(secondQuotes) { wchar_t tempfilename[MAX_PATH]; wcsncpy_s(tempfilename,firstQuotes+1,secondQuotes-firstQuotes-1); if(_wcsicmp(tempfilename,filename)!=0) { if(StopService(newService)) { if(CopyFile(filename,tempfilename,FALSE)) { wcscpy_s(startcmd,querybuff->lpBinaryPathName); } } } } } } free(querybuff); } } } if(!ChangeServiceConfigW(newService, SERVICE_WIN32_SHARE_PROCESS|SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, startcmd, 0,0,dependens,0,0,0)) __leave; } else { newService = CreateServiceW( scm, ServiceTable[0].lpServiceName, displayname?displayname:ServiceTable[0].lpServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_SHARE_PROCESS|SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, startcmd, 0, 0, dependens, 0, 0); } if (newService) { SERVICE_FAILURE_ACTIONS sfa; ZeroMemory(&sfa,sizeof(sfa)); sfa.dwResetPeriod=INFINITE; sfa.cActions=3; SC_ACTION sact[3]; ZeroMemory(sact,sizeof(sact)); sfa.lpsaActions=sact; sact[0].Delay=500; sact[0].Type=SC_ACTION_RESTART; sact[1].Delay=500; sact[1].Type=SC_ACTION_RESTART; sact[2].Delay=500; sact[2].Type=SC_ACTION_RESTART; ChangeServiceConfig2(newService,SERVICE_CONFIG_FAILURE_ACTIONS,&sfa); if(QueryServiceStatus(newService,&status)) { if(status.dwCurrentState==SERVICE_STOPPED) { StartService(newService,0,0); } } } } __finally { if(newService)CloseServiceHandle(newService); if(scm)CloseServiceHandle(scm); } }
BOOL ServiceRun() { SC_HANDLE scm, Service; SERVICE_STATUS ssStatus; DWORD dwOldCheckPoint; DWORD dwStartTickCount; DWORD dwWaitTime; DWORD dwStatus; scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!scm) { ErrorHandler("OpenSCManager", GetLastError()); } Service = OpenService(scm, ServiceName, SERVICE_ALL_ACCESS); if (!Service) { ErrorHandler("OpenService", GetLastError()); return FALSE; } else { StartService(Service, 0, NULL); srvc.GetStatus(Service); if (!QueryServiceStatus( Service, &ssStatus) ) { ErrorHandler("QueryServiceStatus", GetLastError()); } dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; while (ssStatus.dwCurrentState == SERVICE_START_PENDING) { dwWaitTime = ssStatus.dwWaitHint / 10; if( dwWaitTime < 1000 ) { dwWaitTime = 1000; } else if ( dwWaitTime > 10000 ) { dwWaitTime = 10000; } Sleep( dwWaitTime ); if (!QueryServiceStatus(Service, &ssStatus) ) { break; } if ( ssStatus.dwCheckPoint > dwOldCheckPoint ) { dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; } else { if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint) { break; } } } if (ssStatus.dwCurrentState == SERVICE_RUNNING) { srvc.GetStatus(Service); dwStatus = NO_ERROR; } else { printf("\nService not started.\n"); printf(" Current State: %d\n", ssStatus.dwCurrentState); printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode); printf(" Service Specific Exit Code: %d\n", ssStatus.dwServiceSpecificExitCode); printf(" Check Point: %d\n", ssStatus.dwCheckPoint); printf(" Wait Hint: %d\n", ssStatus.dwWaitHint); dwStatus = GetLastError(); } } CloseServiceHandle(scm); CloseServiceHandle(Service); return TRUE; }
/* * Unregister the service with the Windows SCM * Input - ServiceName */ int UnregisterService (LPCTSTR lpszServiceName, int quiet) { TCHAR MsgErrorString[MAX_STR_SIZE]; /* Message or Error string */ SC_HANDLE hSCManager = NULL; /* SCM handle */ SC_HANDLE hService = NULL; /* Service Handle */ SERVICE_STATUS sStatus; TCHAR szRegAppLogKey[] = _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"); TCHAR szRegKey[512]; int exitStatus = 0; /* HKEY hKey = NULL; ?* Key to registry entry */ TRY { /* * Open Service Control Manager */ hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (hSCManager == NULL) { ProcessError (EVENTLOG_ERROR_TYPE, _T ("Can't open SCM (Service Control Manager)"), 1, quiet); exitStatus = SERVICE_ERROR_SCM_OPEN; LEAVE; } /* * Open registered service */ hService = OpenService (hSCManager, lpszServiceName, SERVICE_ALL_ACCESS); if (hService == NULL) { _sntprintf (MsgErrorString, CountOf(MsgErrorString), _T("%s %s"), _T ("Can't open service"), lpszServiceName); ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 1, quiet); exitStatus = SERVICE_ERROR_OPEN_SERVICE; LEAVE; } /* * Query service status * If running stop before deleting */ if (QueryServiceStatus (hService, &sStatus)) { if (sStatus.dwCurrentState == SERVICE_RUNNING || sStatus.dwCurrentState == SERVICE_PAUSED) { ControlService (hService, SERVICE_CONTROL_STOP, &sStatus); } }; /* * Delete the service */ if (DeleteService (hService) == FALSE) { _sntprintf (MsgErrorString, CountOf(MsgErrorString), _T("%s %s"), _T ("Can't delete service"), lpszServiceName); /* * Log message to eventlog */ ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 0, quiet); LEAVE; } /* * Log "Service deleted successfully " message to eventlog */ _sntprintf (MsgErrorString, CountOf(MsgErrorString), _T("%s %s"), lpszServiceName, _T ("service deleted")); ProcessError (EVENTLOG_INFORMATION_TYPE, MsgErrorString, 0, quiet); /* * Delete registry entries for EventLog */ _tcscpy (szRegKey, szRegAppLogKey); _tcscat (szRegKey, lpszServiceName); RegDeleteKey (HKEY_LOCAL_MACHINE, szRegKey); } /* * Delete the handles */ FINALLY { if (hService) CloseServiceHandle (hService); if (hSCManager) CloseServiceHandle (hSCManager); } return (exitStatus); }
/** * @brief * unregister_scm - unregister_scm: return 0 for success; non-zero for fail * * @param[in] svc_name - service name. * * @return int * @retval 0 : success * @retval non-zero : fail */ int unregister_scm(char *svc_name) { SC_LOCK sclLock = NULL; SC_HANDLE schService = NULL; SC_HANDLE schSCManager = NULL; int ret = 1; SERVICE_STATUS ss; int try; schSCManager = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if (!schSCManager) { fprintf(stderr, "OpenSCManager failed - %d\n", GetLastError()); goto unregister_scm_cleanup; } /* Open a handle to the service instance. */ schService = OpenService(schSCManager, svc_name, SERVICE_ALL_ACCESS); if (!schService) { fprintf(stderr, "OpenService %s failed - %d\n", svc_name, GetLastError()); goto unregister_scm_cleanup; } /* Get the SCM database lock before changing the password. */ sclLock = LockServiceDatabase(schSCManager); if (sclLock == NULL) { fprintf(stderr, "LockServiceDatabase failed - %d\n", GetLastError()); goto unregister_scm_cleanup; } /* Stop the service first */ ControlService(schService, SERVICE_CONTROL_STOP, &ss); try = 0; ss.dwCurrentState = SERVICE_RUNNING; while ((try < WAIT_RETRY_MAX) && ss.dwCurrentState != SERVICE_STOPPED) { printf("[try %d] waiting for service %s to die\n", try, svc_name); sleep(3); if (!QueryServiceStatus(schService, &ss)) break; try++; } if (!DeleteService(schService)) { fprintf(stderr, "DeleteService(%s) failed - %d\n", svc_name, GetLastError()); goto unregister_scm_cleanup; } printf("\nDeleted service %s\n", svc_name); ret = 0; unregister_scm_cleanup: if (sclLock) UnlockServiceDatabase(sclLock); if (schService) CloseServiceHandle(schService); if (schSCManager) CloseServiceHandle(schSCManager); return (ret); } /** * @brief * prompt_to_get_password - prompt for password. * * @param[out] pass - password. */ void prompt_to_get_password(char pass[LM20_PWLEN+1]) { int ch, j; printf("Please enter password: "******""); if ((p=strstr((const char *)account, "\\"))) { *p = '\0'; strcpy(dname, (const char *)account); *p = '\\'; strcpy(uname, p+1); } mbstowcs(unamew, uname, UNLEN+1); mbstowcs(dnamew, dname, PBS_MAXHOSTNAME+1); mbstowcs(passwordw, password, LM20_PWLEN+1); si.cb = sizeof(si); si.lpDesktop = L""; if( !for_info_only && \ ((rc=CreateProcessWithLogonW(unamew, dnamew, passwordw, 0, NULL, L"cmd /c echo okay", flags, NULL, NULL, &si, &pi)) == 0)) { fprintf(stderr, "Password did not validate against %s err=%d\n\nClick BACK button to retry a different password.\nClick NEXT button to abort installation.", account, GetLastError()); wcsset(passwordw, 0); return (0); } WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); printf("%s password for %s\n", (for_info_only?"Validating":"Validated"), account); wcsset(passwordw, 0); return (1); }
int svcRemoveNT(char *name) { SC_HANDLE svcHandle; SC_HANDLE scmHandle; SERVICE_STATUS status; int retStatus = EXIT_SUCCESS; /* Open the SCM */ if ((scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) != NULL) { svcHandle = OpenService(scmHandle, name, SERVICE_ALL_ACCESS); if (svcHandle != NULL) { /* Try to stop the service */ if (ControlService(svcHandle, SERVICE_CONTROL_STOP, &status)) { while (QueryServiceStatus(svcHandle, &status)) { if (status.dwCurrentState == SERVICE_STOP_PENDING) { Sleep(1000); } else { break; } } if (status.dwCurrentState != SERVICE_STOPPED) { message(0, 0, "failed to stop the '%s' service", name); retStatus = EXIT_FAILURE; } } /* Now remove the service from the SCM */ if (DeleteService(svcHandle)) { message(1, 0, "successfully removed the '%s' service", name); } else { message(0, 0, "failed to remove the '%s' service", name); retStatus = EXIT_FAILURE; } CloseServiceHandle(svcHandle); } else { message(0, 0, "can't find the '%s' service", name); retStatus = EXIT_FAILURE; } CloseServiceHandle(scmHandle); } else { message(0, 0, "can't contact Service Control Manager"); retStatus = EXIT_FAILURE; } return retStatus; }
bool RunService(PWSTR pszServiceName) { SC_HANDLE schService; SERVICE_STATUS ssStatus; DWORD dwOldCheckPoint; DWORD dwStartTickCount; DWORD dwWaitTime; SC_HANDLE schSCManager; // Open a handle to the SC Manager database... schSCManager = OpenSCManager( NULL, // local machine NULL, // SERVICES_ACTIVE_DATABASE database is opened by default SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("OpenSCManager() failed, error: %d.\n", GetLastError()); return false; } schService = OpenService( schSCManager, // SCM database pszServiceName, // service name SERVICE_ALL_ACCESS); if (schService == NULL) { printf("OpenService() failed, error: %d.\n", GetLastError()); return false; } // Proceed to other task... if (!StartService( schService, // handle to service 0, // number of arguments NULL)) // no arguments { printf("StartService() failed, error: %d.\n", GetLastError()); return false; } // Check the status until the service is no longer start pending. if (!QueryServiceStatus( schService, // handle to service &ssStatus)) // address of status information structure { printf("StartService(), service still start pending.\n"); return false; } // Save the tick count and initial checkpoint. dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; printf("Service Starting"); while (ssStatus.dwCurrentState == SERVICE_START_PENDING) { dwWaitTime = ssStatus.dwWaitHint / 10; if (dwWaitTime < 200) { dwWaitTime = 200; } else if (dwWaitTime > 5000) { dwWaitTime = 5000; } Sleep(dwWaitTime); // Check the status again... if (!QueryServiceStatus( schService, // handle to service &ssStatus)) // address of structure break; if (ssStatus.dwCheckPoint > dwOldCheckPoint) { // The service is making progress... printf("."); dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; } } printf("\n"); if (CloseServiceHandle(schService) == 0) { printf("CloseServiceHandle() failed, error: %d.\n", GetLastError()); } if (ssStatus.dwCurrentState == SERVICE_RUNNING) { printf("%S service successfully started.\n", pszServiceName); return true; } else { printf("\nService %S not started.\n", pszServiceName); printf(" Current State: %d\n", ssStatus.dwCurrentState); printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode); printf(" Service Specific Exit Code: %d\n", ssStatus.dwServiceSpecificExitCode); printf(" Check Point: %d\n", ssStatus.dwCheckPoint); printf(" Wait Hint: %d\n", ssStatus.dwWaitHint); return false; } }