📄 service.c
字号:
else { /* try to stop the service */ ap_stop_service(schService); // now remove the service if (DeleteService(schService) == 0) ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "DeleteService failed"); else success = TRUE; CloseServiceHandle(schService); } /* SCM removes registry parameters */ CloseServiceHandle(schSCManager); } else /* !isWindowsNT() */ { HKEY hkey; DWORD service_pid; DWORD rv; HWND hwnd; /* Locate the named window of class ApacheWin95ServiceMonitor * from the active top level windows */ hwnd = FindWindow("ApacheWin95ServiceMonitor", service_name); if (hwnd && GetWindowThreadProcessId(hwnd, &service_pid)) { int ticks = 120; char prefix[20]; ap_snprintf(prefix, sizeof(prefix), "ap%ld", (long)service_pid); setup_signal_names(prefix); ap_start_shutdown(); while (--ticks) { if (!IsWindow(hwnd)) break; Sleep(1000); } } /* Open the RunServices key */ rv = RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", &hkey); if (rv != ERROR_SUCCESS) { SetLastError(rv); ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "Could not open the RunServices registry key."); } else { /* Delete the registry value for this service */ rv = RegDeleteValue(hkey, service_name); if (rv != ERROR_SUCCESS) { SetLastError(rv); ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "Unable to remove service: " "Could not delete the RunServices entry."); } else success = TRUE; } RegCloseKey(hkey); /* Open the Services key */ rv = RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services", &hkey); if (rv != ERROR_SUCCESS) { rv = RegDeleteValue(hkey, service_name); ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "Could not open the Services registry key."); success = FALSE; } else { /* Delete the registry key for this service */ rv = RegDeleteKey(hkey, service_name); if (rv != ERROR_SUCCESS) { SetLastError(rv); ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "Unable to remove service: " "Could not delete the Services registry key."); success = FALSE; } } RegCloseKey(hkey); } if (success) printf("The %s service has been removed successfully.\n", display_name);}BOOL isWindowsNT(void){ static BOOL once = FALSE; static BOOL isNT = FALSE; if (!once) { OSVERSIONINFO osver; osver.dwOSVersionInfoSize = sizeof(osver); if (GetVersionEx(&osver)) if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) isNT = TRUE; once = TRUE; } return isNT;}/* * A hack to determine if we're running as a service without waiting for * the SCM to fail. */BOOL isProcessService() { if (is_service != -1) return is_service; if (!isWindowsNT() || !AllocConsole()) { /* Don't assume anything, just yet */ return FALSE; } FreeConsole(); is_service = 1; return TRUE;}/* Determine is service_name is a valid service * * TODO: be nice if we tested that it is an 'apache' service, no? */BOOL isValidService(char *display_name) { char service_key[MAX_PATH]; char *service_name; HKEY hkey; /* Remove spaces from display name to create service name */ strcpy(service_key, "System\\CurrentControlSet\\Services\\"); service_name = get_service_name(display_name); strcat(service_key, service_name); if (RegOpenKey(HKEY_LOCAL_MACHINE, service_key, &hkey) != ERROR_SUCCESS) { return FALSE; } RegCloseKey(hkey); return TRUE;}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;}int ap_stop_service(SC_HANDLE schService){ if (ControlService(schService, SERVICE_CONTROL_STOP, &globdat.ssStatus)) { Sleep(1000); while (QueryServiceStatus(schService, &globdat.ssStatus)) { if (globdat.ssStatus.dwCurrentState == SERVICE_STOP_PENDING) Sleep(1000); else break; } } if (QueryServiceStatus(schService, &globdat.ssStatus)) if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) return TRUE; return FALSE;}int ap_start_service(SC_HANDLE schService, DWORD argc, char **argv) { if (StartService(schService, argc, argv)) { Sleep(1000); while(QueryServiceStatus(schService, &globdat.ssStatus)) { if(globdat.ssStatus.dwCurrentState == SERVICE_START_PENDING) Sleep(1000); else break; } } if (QueryServiceStatus(schService, &globdat.ssStatus)) if (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING) return TRUE; return FALSE;}int ap_restart_service(SC_HANDLE schService) { int ticks; if (ControlService(schService, SERVICE_APACHE_RESTART, &globdat.ssStatus)) { ticks = 60; while (globdat.ssStatus.dwCurrentState == SERVICE_START_PENDING) { Sleep(1000); if (!QueryServiceStatus(schService, &globdat.ssStatus)) return FALSE; if (!--ticks) break; } } if (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING) return TRUE; return FALSE;}#endif /* WIN32 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -