Exemplo n.º 1
0
//
//  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;
    }
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
static void restart(int sig)
{
    ap_start_restart(sig == AP_SIG_GRACEFUL);
}