⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 service.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 3 页
字号:
                                   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, service_name);        rv = ap_registry_store_value(SERVICECONFIG9X, service_name, launch_cmd);        if (rv != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,                          "%s: Failed to add the RunServices registry entry.",                          display_name);            return (rv);        }        apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, service_name);        rv = ap_registry_store_value(key_name, "DisplayName", display_name);        if (rv != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,                          "%s: Failed to store DisplayName in the registry.",                          display_name);            return (rv);        }    }    /* For both WinNT & Win9x store the service ConfigArgs in the registry...     */    apr_snprintf(key_name, sizeof(key_name), SERVICEPARAMS, service_name);    rv = ap_registry_store_array(ptemp, key_name, "ConfigArgs", argc, argv);    if (rv != APR_SUCCESS) {        ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,                      "%s: Failed to store the ConfigArgs in the registry.",                      display_name);        return (rv);    }    printf("The %s service is successfully installed.\n", display_name);}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;        printf("Removing the %s service\n", display_name);        // TODO: Determine the minimum permissions required for security        schSCManager = OpenSCManager(NULL, NULL, /* local, default database */                                     SC_MANAGER_ALL_ACCESS);        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);        }                schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS);        if (!schService) {           rv = apr_get_os_error();           ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,			"%s: OpenService failed", 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.", display_name);            return (rv);        }                CloseServiceHandle(schService);                CloseServiceHandle(schSCManager);    }    else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */    {        printf("Removing the %s service\n", display_name);        /* TODO: assure the service is stopped before continuing */        if (ap_registry_delete_value(SERVICECONFIG9X, service_name)) {            rv = apr_get_os_error();	    ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,                         "%s: Failed to remove the RunServices registry "                         "entry.", display_name);            return (rv);        }                /* we blast Services/us, not just the Services/us/Parameters branch */        apr_snprintf(key_name, sizeof(key_name), SERVICECONFIG, service_name);        if (ap_registry_delete_key(key_name))         {            rv = apr_get_os_error();            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,                         "%s: Failed to remove the service config from the "                         "registry.", display_name);            return (rv);        }    }    printf("The %s service has been removed successfully.\n", display_name);    return APR_SUCCESS;}/* signal_service_transition is a simple thunk to signal the service * and monitor it's successful transition.  If the signal passed is 0, * then the caller is assumed to already have performed some service  * operation to be monitored (such as StartService), and no actual * ControlService signal is sent. */static int signal_service_transition(SC_HANDLE schService, DWORD signal, DWORD pending, DWORD complete){    if (signal && !ControlService(schService, signal, &globdat.ssStatus))         return FALSE;        do {        Sleep(1000);            if (!QueryServiceStatus(schService, &globdat.ssStatus))            return FALSE;    } while (globdat.ssStatus.dwCurrentState == pending);            return (globdat.ssStatus.dwCurrentState == complete);}apr_status_t mpm_service_start(apr_pool_t *ptemp, int argc,                                const char * const * argv){    apr_status_t rv;        printf("Starting the %s service\n", display_name);    if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT)    {        char **start_argv;        SC_HANDLE   schService;        SC_HANDLE   schSCManager;        // TODO: Determine the minimum permissions required for security        schSCManager = OpenSCManager(NULL, NULL, /* local, default database */                                     SC_MANAGER_ALL_ACCESS);        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);        }        schService = OpenService(schSCManager, service_name,                                  SERVICE_START | SERVICE_QUERY_STATUS);        if (!schService) {            rv = apr_get_os_error();            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, rv, NULL,                         "%s: Failed to open the service.", display_name);            CloseServiceHandle(schSCManager);            return (rv);        }        if (QueryServiceStatus(schService, &globdat.ssStatus)            && (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING)) {            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, 0, NULL,                         "Service %s is already started!", display_name);            CloseServiceHandle(schService);            CloseServiceHandle(schSCManager);            return 0;        }                argc += 1;        start_argv = apr_palloc(ptemp, argc * sizeof(const char **));        start_argv[0] = service_name;        if (argc > 1)            memcpy(start_argv + 1, argv, (argc - 1) * sizeof(const char **));                rv = APR_EINIT;        if (StartService(schService, argc, start_argv)            && signal_service_transition(schService, 0, /* test only */                                         SERVICE_START_PENDING,                                          SERVICE_RUNNING))                rv = APR_SUCCESS;        if (rv != APR_SUCCESS)            rv = apr_get_os_error();                CloseServiceHandle(schService);        CloseServiceHandle(schSCManager);    }    else /* osver.dwPlatformId != VER_PLATFORM_WIN32_NT */    {        STARTUPINFO si;           /* Filled in prior to call to CreateProcess */        PROCESS_INFORMATION pi;   /* filled in on call to CreateProcess */        char exe_path[MAX_PATH];        char *pCommand;        int i;        /* Locate the active top level window named service_name         * provided the class is ApacheWin95ServiceMonitor         */        if (FindWindow("ApacheWin95ServiceMonitor", service_name)) {            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, 0, NULL,                         "Service %s is already started!", display_name);            return 0;        }        /* This may not appear intuitive, but Win9x will not allow a process         * to detach from the console without releasing the entire console.         * Ergo, we must spawn a new process for the service to get back our         * console window.         * The config is pre-flighted, so there should be no danger of failure.         */                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;        }                pCommand = apr_psprintf(ptemp, "\"%s\" -n %s -k runservice",                                exe_path, service_name);          for (i = 0; i < argc; ++i) {            pCommand = apr_pstrcat(ptemp, pCommand,                                   " \"", argv[i], "\"", NULL);        }                memset(&si, 0, sizeof(si));        memset(&pi, 0, sizeof(pi));        si.cb = sizeof(si);        si.dwFlags     = STARTF_USESHOWWINDOW;        si.wShowWindow = SW_HIDE;   /* This might be redundant */                rv = APR_EINIT;        if (CreateProcess(NULL, pCommand, NULL, NULL, FALSE,                            DETACHED_PROCESS, /* Creation flags */                           NULL, NULL, &si, &pi))         {            DWORD code;            while (GetExitCodeProcess(pi.hProcess, &code) == STILL_ACTIVE) {                if (FindWindow("ApacheWin95ServiceMonitor", service_name)) {                    rv = APR_SUCCESS;                    break;                }                Sleep (1000);            }        }                if (rv != APR_SUCCESS)            rv = apr_get_os_error();                CloseHandle(pi.hProcess);        CloseHandle(pi.hThread);    }        if (rv == APR_SUCCESS)        printf("The %s service is running.\n", display_name);    else        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,                     "%s: Failed to start the service process.",                     display_name);            return rv;}/* signal is zero to stop, non-zero for restart */void mpm_signal_service(apr_pool_t *ptemp, int signal){    int success = FALSE;        if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT)     {        SC_HANDLE   schService;        SC_HANDLE   schSCManager;        schSCManager = OpenSCManager(NULL, NULL, // default machine & database                                     SC_MANAGER_ALL_ACCESS);                if (!schSCManager) {            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL,                         "Failed to open the NT Service Manager");            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_STARTUP, apr_get_os_error(), NULL,                         "Failed to open the %s Service", display_name);            CloseServiceHandle(schSCManager);            return;        }                if (!QueryServiceStatus(schService, &globdat.ssStatus)) {            ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, apr_get_os_error(), NULL,                         "Query of Service %s failed", display_name);            CloseServiceHandle(schService);            CloseServiceHandle(schSCManager);            return;        }        if (!signal && (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED)) {            printf("The %s service is not started.\n", display_name);            CloseServiceHandle(schService);            CloseServiceHandle(schSCManager);            return;        }                printf("The %s service is %s.\n", display_name,                signal ? "restarting" : "stopping");        if (!signal)            success = signal_service_transition(schService,                                                 SERVICE_CONTROL_STOP,                                                 SERVICE_STOP_PENDING,                                                 SERVICE_STOPPED);        else if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) {            mpm_service_start(ptemp, 0, NULL);            CloseServiceHandle(schService);            CloseServiceHandle(schSCManager);            return;        }        else            success = signal_service_transition(schService,                                                 SERVICE_APACHE_RESTART,                                                 SERVICE_START_PENDING,                                                 SERVICE_RUNNING);        CloseServiceHandle(schService);        CloseServiceHandle(schSCManager);    }    else /* !isWindowsNT() */    {        DWORD       service_pid;        HANDLE      hwnd;        char prefix[20];        /* Locate the active top level window named service_name         * provided the class is ApacheWin95ServiceMonitor         */        hwnd = FindWindow("ApacheWin95ServiceMonitor", service_name);        if (hwnd && GetWindowThreadProcessId(hwnd, &service_pid))            globdat.ssStatus.dwCurrentState = SERVICE_RUNNING;        else        {            globdat.ssStatus.dwCurrentState = SERVICE_STOPPED;            if (!signal) {                printf("The %s service is not started.\n", display_name);                return;            }        }        printf("The %s service is %s.\n", display_name,                signal ? "restarting" : "stopping");        apr_snprintf(prefix, sizeof(prefix), "ap%ld", (long)service_pid);        setup_signal_names(prefix);        if (!signal)         {            int ticks = 60;            ap_start_shutdown();            while (--ticks)            {                if (!IsWindow(hwnd)) {                    success = TRUE;                    break;                }                Sleep(1000);            }        }        else /* !stop */        {               /* TODO: Aught to add a little test to the restart logic, and             * store the restart counter in the window's user dword.             * Then we can hang on and report a successful restart.  But             * that's a project for another day.             */            if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) {                mpm_service_start(ptemp, 0, NULL);                return;            }            else {                success = TRUE;                ap_start_restart(1);            }        }    }    if (success)        printf("The %s service has %s.\n", display_name,                signal ? "restarted" : "stopped");    else        printf("Failed to %s the %s service.\n",                signal ? "restart" : "stop", display_name);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -