📄 service.c
字号:
if (!ChangeServiceDescription) { set_service_description_string(full_description); return; } schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (schSCManager) { SC_HANDLE schService = OpenService(schSCManager, globdat.name, SERVICE_ALL_ACCESS); if (schService) { ret = ChangeServiceDescription(schService, 1 /* SERVICE_CONFIG_DESCRIPTION */, &full_description); CloseServiceHandle(schService); } CloseServiceHandle(schSCManager); } if (!ret) set_service_description_string(full_description);}//// 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: See the user-defined Handler() entry in the PSDK//VOID WINAPI service_ctrl(DWORD dwCtrlCode){ switch(dwCtrlCode) { // Stop the service. // case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL, "Service Stop/Shutdown signaled, shutting down server."); ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 15000); ap_start_shutdown(); break; case SERVICE_APACHE_RESTART: ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL, "Service Restart signaled, shutting down server."); ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 15000); ap_start_restart(1); break; // Update the service status. // case SERVICE_CONTROL_INTERROGATE: ReportStatusToSCMgr(globdat.ssStatus.dwCurrentState, NO_ERROR, 0); break; // invalid control code, ignored // default: break; }}int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint){ static int firstTime = 1; static int checkPoint = 1; int rv; if (firstTime) { firstTime = 0; globdat.ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; globdat.ssStatus.dwServiceSpecificExitCode = 0; globdat.ssStatus.dwCheckPoint = 1; } if (globdat.connected) { if ((currentState == SERVICE_START_PENDING) || (currentState == SERVICE_STOP_PENDING)) globdat.ssStatus.dwControlsAccepted = 0; else globdat.ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; globdat.ssStatus.dwCurrentState = currentState; globdat.ssStatus.dwWin32ExitCode = exitCode; if ( ( currentState == SERVICE_RUNNING ) || ( currentState == SERVICE_STOPPED ) ) { globdat.ssStatus.dwWaitHint = 0; globdat.ssStatus.dwCheckPoint = 0; } else { if(waitHint) globdat.ssStatus.dwWaitHint = waitHint; globdat.ssStatus.dwCheckPoint = ++checkPoint; } rv = SetServiceStatus(globdat.hServiceStatus, &globdat.ssStatus); } return(1);}void InstallService(pool *p, char *display_name, int argc, char **argv, int reconfig){ TCHAR szPath[MAX_PATH]; TCHAR szQuotedPath[512]; char *service_name; int regargc = 0; char default_depends[] = "Tcpip\0Afd\0"; char *depends = default_depends; size_t depends_len = sizeof(default_depends); char **regargv = malloc((argc + 4) * sizeof(char*)); char **newelem = regargv; regargc += 4; *(newelem++) = "-d"; *(newelem++) = ap_server_root; *(newelem++) = "-f"; *(newelem++) = ap_server_confname; while (++argv, --argc) { if ((**argv == '-') && strchr("kndf", argv[0][1])) --argc, ++argv; /* Skip already handled -k -n -d -f options */ else if ((**argv == '-') && (argv[0][1] == 'W')) { /* Catch this service -W dependency * the depends list is null seperated, double-null terminated */ char *service = get_service_name(*(argv + 1)); size_t add_len = strlen(service) + 1; char *more_depends = malloc(depends_len + add_len); memcpy (more_depends, depends, depends_len - 1); memcpy (more_depends + depends_len - 1, service, add_len); depends_len += add_len; depends = more_depends; depends[depends_len - 1] = '\0'; ++argv, --argc; } else if ((**argv != '-') || !strchr("iuw", argv[0][1])) *(newelem++) = *argv, ++regargc; /* Ignoring -i -u -w options */ } /* Remove spaces from display name to create service name */ service_name = get_service_name(display_name); printf(reconfig ? "Reconfiguring the %s service\n" : "Installing the %s service\n", display_name); if (GetModuleFileName( NULL, szPath, 512 ) == 0) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "GetModuleFileName failed"); return; } if (isWindowsNT()) { SC_HANDLE schService; SC_HANDLE schSCManager; ap_snprintf(szQuotedPath, sizeof(szQuotedPath), "\"%s\" --ntservice", szPath); schSCManager = OpenSCManager( NULL, // machine (local) NULL, // database (default) SC_MANAGER_ALL_ACCESS // access required ); if (!schSCManager) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "OpenSCManager failed"); return; } /* Added dependencies for the following: TCPIP, AFD * AFD is the winsock handler, TCPIP is self evident * * RPCSS is the Remote Procedure Call (RPC) Locator * required for DCOM communication. I am far from * convinced we should toggle this, but be warned that * future apache modules or ISAPI dll's may depend on it. * Also UNC share users may need the networking service * started (usually "LanmanWorkstation"). "ProtectedStorage" * may be needed depending on how files and registry keys are * stored. And W3SVC may be needed to wait until IIS has * glommed and released 0.0.0.0:80 if the admin allocates * two different IP's to Apache and IIS on the same port. */ if (reconfig) { schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS); if (!schService) ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "OpenService failed"); else if (!ChangeServiceConfig( schService, // Service handle SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type szQuotedPath, // service's binary NULL, // no load ordering group NULL, // no tag identifier depends, // dependencies NULL, // user account NULL, // account password display_name)) { // service display name ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "ChangeServiceConfig failed"); /* !schService aborts configuration below */ CloseServiceHandle(schService); schService = NULL; } } else /* !reconfig */ { schService = CreateService( schSCManager, // SCManager database service_name, // name of service display_name, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type szQuotedPath, // service's binary NULL, // no load ordering group NULL, // no tag identifier depends, // dependencies NULL, // user account NULL); // account password if (!schService) ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "CreateService failed"); } if (schService) CloseServiceHandle(schService); CloseServiceHandle(schSCManager); if (!schService) return; } else /* !isWindowsNT() */ { HKEY hkey; DWORD rv; ap_snprintf(szQuotedPath, sizeof(szQuotedPath), "\"%s\" -k start -n %s", szPath, service_name); /* Create/Find the RunServices key */ rv = RegCreateKey(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 create/open the RunServices registry key"); return; } /* Attempt to add the value for our service */ rv = RegSetValueEx(hkey, service_name, 0, REG_SZ, (unsigned char *)szQuotedPath, strlen(szQuotedPath) + 1); if (rv != ERROR_SUCCESS) { SetLastError(rv); ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "Unable to install service: " "Could not add to RunServices Registry Key"); RegCloseKey(hkey); return; } RegCloseKey(hkey); /* Create/Find the Service key for Monitor Applications to iterate */ ap_snprintf(szPath, sizeof(szPath), "SYSTEM\\CurrentControlSet\\Services\\%s", service_name); rv = RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hkey); if (rv != ERROR_SUCCESS) { SetLastError(rv); ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "Could not create/open the %s registry key", szPath); return; } /* Attempt to add the ImagePath value to identify it as Apache */ rv = RegSetValueEx(hkey, "ImagePath", 0, REG_SZ, (unsigned char *)szQuotedPath, strlen(szQuotedPath) + 1); if (rv != ERROR_SUCCESS) { SetLastError(rv); ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "Unable to install service: " "Could not add ImagePath to %s Registry Key", service_name); RegCloseKey(hkey); return; } /* Attempt to add the DisplayName value for our service */ rv = RegSetValueEx(hkey, "DisplayName", 0, REG_SZ, (unsigned char *)display_name, strlen(display_name) + 1); if (rv != ERROR_SUCCESS) { SetLastError(rv); ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "Unable to install service: " "Could not add DisplayName to %s Registry Key", service_name); RegCloseKey(hkey); return; } RegCloseKey(hkey); } /* Both Platforms: Now store the args in the registry */ if (ap_registry_set_service_args(p, regargc, regargv, service_name)) { return; } printf("The %s service has been %s successfully.\n", display_name, reconfig ? "reconfigured" : "installed");}void RemoveService(char *display_name){ char *service_name; BOOL success = FALSE; printf("Removing the %s service\n", display_name); /* Remove spaces from display name to create service name */ service_name = get_service_name(display_name); if (isWindowsNT()) { SC_HANDLE schService; SC_HANDLE schSCManager; 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; } 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"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -