📄 service.c
字号:
}void service_stopped(void){ /* Still have a thread & window to clean up, so signal now */ if (globdat.service_thread) { if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { /* Stop logging to the event log */ mpm_nt_eventlog_stderr_flush(); /* Cause the service_nt_main_fn to complete */ ReleaseMutex(globdat.service_term); ReportStatusToSCMgr(SERVICE_STOPPED, // service state NO_ERROR, // exit code 0); // wait hint } else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ { RegisterServiceProcess(0, 0); PostThreadMessage(globdat.service_thread_id, WM_CLOSE, 0, 0); } WaitForSingleObject(globdat.service_thread, 5000); CloseHandle(globdat.service_thread); }}apr_status_t mpm_service_to_start(const char **display_name, apr_pool_t *p){ HANDLE hProc = GetCurrentProcess(); HANDLE hThread = GetCurrentThread(); HANDLE waitfor[2]; /* Prevent holding open the (hidden) console */ real_exit_code = 0; /* GetCurrentThread returns a psuedo-handle, we need * a real handle for another thread to wait upon. */ if (!DuplicateHandle(hProc, hThread, hProc, &(globdat.mpm_thread), 0, FALSE, DUPLICATE_SAME_ACCESS)) { return APR_ENOTHREAD; } if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { globdat.service_init = CreateEvent(NULL, FALSE, FALSE, NULL); globdat.service_term = CreateMutex(NULL, TRUE, NULL); if (!globdat.service_init || !globdat.service_term) { return APR_EGENERAL; } globdat.service_thread = CreateThread(NULL, 0, service_nt_dispatch_thread, NULL, 0, &globdat.service_thread_id); } else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ { if (!RegisterServiceProcess(0, 1)) return GetLastError(); globdat.service_init = CreateEvent(NULL, FALSE, FALSE, NULL); if (!globdat.service_init) { return APR_EGENERAL; } globdat.service_thread = CreateThread(NULL, 0, monitor_service_9x_thread, (LPVOID) mpm_service_name, 0, &globdat.service_thread_id); } if (!globdat.service_thread) { return APR_ENOTHREAD; } waitfor[0] = globdat.service_init; waitfor[1] = globdat.service_thread; /* Wait for controlling thread init or termination */ if (WaitForMultipleObjects(2, waitfor, FALSE, 10000) != WAIT_OBJECT_0) { return APR_ENOTHREAD; } atexit(service_stopped); *display_name = mpm_display_name; return APR_SUCCESS;}apr_status_t mpm_service_started(void){ set_service_description(); if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { ReportStatusToSCMgr(SERVICE_RUNNING, // service state NO_ERROR, // exit code 0); // wait hint } return APR_SUCCESS;}void mpm_service_stopping(void){ if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) ReportStatusToSCMgr(SERVICE_STOP_PENDING, // service state NO_ERROR, // exit code 30000); // wait hint}apr_status_t mpm_service_install(apr_pool_t *ptemp, int argc, const char * const * argv, int reconfig){ char key_name[MAX_PATH]; char exe_path[MAX_PATH]; char *launch_cmd; ap_regkey_t *key; apr_status_t rv; fprintf(stderr,reconfig ? "Reconfiguring the %s service\n" : "Installing the %s service\n", mpm_display_name); /* ###: utf-ize */ if (GetModuleFileName(NULL, exe_path, sizeof(exe_path)) == 0) { apr_status_t rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "GetModuleFileName failed"); return rv; } if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { SC_HANDLE schService; SC_HANDLE schSCManager; schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ SC_MANAGER_CREATE_SERVICE); if (!schSCManager) { rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "Failed to open the WinNT service manager"); return (rv); } launch_cmd = apr_psprintf(ptemp, "\"%s\" -k runservice", exe_path); if (reconfig) { /* ###: utf-ize */ schService = OpenService(schSCManager, mpm_service_name, SERVICE_CHANGE_CONFIG); if (!schService) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, apr_get_os_error(), NULL, "OpenService failed"); } /* ###: utf-ize */ else if (!ChangeServiceConfig(schService, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, launch_cmd, NULL, NULL, "Tcpip\0Afd\0", NULL, NULL, mpm_display_name)) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_ERR, apr_get_os_error(), NULL, "ChangeServiceConfig failed"); /* !schService aborts configuration below */ CloseServiceHandle(schService); schService = NULL; } } else { /* RPCSS is the Remote Procedure Call (RPC) Locator required * for DCOM communication pipes. I am far from convinced we * should add this to the default service dependencies, but * be warned that future apache modules or ISAPI dll's may * depend on it. */ /* ###: utf-ize */ schService = CreateService(schSCManager, // SCManager database mpm_service_name, // name of service mpm_display_name, // name to display SERVICE_ALL_ACCESS, // access required SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type launch_cmd, // service's binary NULL, // no load svc group NULL, // no tag identifier "Tcpip\0Afd\0", // dependencies NULL, // use SYSTEM account NULL); // no password if (!schService) { rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "Failed to create WinNT Service Profile"); CloseServiceHandle(schSCManager); return (rv); } } CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ { /* Store the launch command in the registry */ launch_cmd = apr_psprintf(ptemp, "\"%s\" -n %s -k runservice", exe_path, mpm_service_name); rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, SERVICECONFIG9X, APR_READ | APR_WRITE | APR_CREATE, pconf); if (rv == APR_SUCCESS) { rv = ap_regkey_value_set(key, mpm_service_name, launch_cmd, 0, pconf); ap_regkey_close(key); } if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "%s: Failed to add the RunServices registry entry.", mpm_display_name); return (rv); } apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, mpm_service_name); rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, APR_READ | APR_WRITE | APR_CREATE, pconf); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "%s: Failed to create the registry service key.", mpm_display_name); return (rv); } rv = ap_regkey_value_set(key, "ImagePath", launch_cmd, 0, pconf); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "%s: Failed to store ImagePath in the registry.", mpm_display_name); ap_regkey_close(key); return (rv); } rv = ap_regkey_value_set(key, "DisplayName", mpm_display_name, 0, pconf); ap_regkey_close(key); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "%s: Failed to store DisplayName in the registry.", mpm_display_name); return (rv); } } set_service_description(); /* For both WinNT & Win9x store the service ConfigArgs in the registry... */ apr_snprintf(key_name, sizeof(key_name), SERVICEPARAMS, mpm_service_name); rv = ap_regkey_open(&key, AP_REGKEY_LOCAL_MACHINE, key_name, APR_READ | APR_WRITE | APR_CREATE, pconf); if (rv == APR_SUCCESS) { rv = ap_regkey_value_array_set(key, "ConfigArgs", argc, argv, pconf); ap_regkey_close(key); } if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "%s: Failed to store the ConfigArgs in the registry.", mpm_display_name); return (rv); } fprintf(stderr,"The %s service is successfully installed.\n", mpm_display_name); return APR_SUCCESS;}apr_status_t mpm_service_uninstall(void){ char key_name[MAX_PATH]; apr_status_t rv; if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { SC_HANDLE schService; SC_HANDLE schSCManager; fprintf(stderr,"Removing the %s service\n", mpm_display_name); schSCManager = OpenSCManager(NULL, NULL, /* local, default database */ SC_MANAGER_CONNECT); if (!schSCManager) { rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "Failed to open the WinNT service manager."); return (rv); } /* ###: utf-ize */ schService = OpenService(schSCManager, mpm_service_name, DELETE); if (!schService) { rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "%s: OpenService failed", mpm_display_name); return (rv); } /* assure the service is stopped before continuing * * This may be out of order... we might not be able to be * granted all access if the service is running anyway. * * And do we want to make it *this easy* for them * to uninstall their service unintentionally? */ // ap_stop_service(schService); if (DeleteService(schService) == 0) { rv = apr_get_os_error(); ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL, "%s: Failed to delete the service.", mpm_display_name); return (rv); } CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */ { apr_status_t rv2, rv3; ap_regkey_t *key; fprintf(stderr,"Removing the %s service\n", mpm_display_name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -