/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef WIN32

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <direct.h>

#include "httpd.h"
#include "http_conf_globals.h"
#include "http_log.h"
#include "http_main.h"
#include "multithread.h"
#include "service.h"
#include "registry.h"
#include "Win9xConHook.h"

#define SERVICE_APACHE_RESTART 128

static struct
{
    int (*main_fn)(int, char **);
    int connected;
    SERVICE_STATUS_HANDLE hServiceStatus;
    char *name;
    int exit_status;
    SERVICE_STATUS ssStatus;
    FILE *logFile;
} globdat;

/* statics for atexit processing or shared between threads */
static BOOL  die_on_logoff = FALSE;
static HWND  console_wnd = NULL;
static int   is_service = -1;

static void WINAPI service_main_fn(DWORD, LPTSTR *);
static void WINAPI service_ctrl(DWORD ctrlCode);
static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint);
static int ap_start_service(SC_HANDLE, DWORD argc, char **argv);
static int ap_stop_service(SC_HANDLE);
static int ap_restart_service(SC_HANDLE);

/* exit() for Win32 is macro mapped (horrible, we agree) that allows us 
 * to catch the non-zero conditions and inform the console process that
 * the application died, and hang on to the console a bit longer.
 *
 * The macro only maps for http_main.c and other sources that include
 * the service.h header, so we best assume it's an error to exit from
 * _any_ other module.
 *
 * If real_exit_code is not set to 2, it will not be set or trigger this
 * behavior on exit.  All service and child processes are expected to
 * reset this flag to zero to avoid undesireable side effects.  The value
 * 1 simply tells the system it is safe to enable the feature (set to 2),
 * while 0 prohibits the feature from being enabled.
 */
int real_exit_code = 1;

void hold_console_open_on_error(void)
{
    HANDLE hConIn;
    HANDLE hConErr;
    DWORD result;
    DWORD mode;
    time_t start;
    time_t remains;
    char *msg = "Note the errors or messages above, "
                "and press the <ESC> key to exit.  ";
    CONSOLE_SCREEN_BUFFER_INFO coninfo;
    INPUT_RECORD in;
    char count[16];

#ifdef WIN32
    /* The service parent cannot just 'pop' out of the main thread,
     * as it is about to try to do...
     * We must end this thread properly so the service control
     * thread exits gracefully.  atexit()s registered in the running
     * apache_main thread _should_ have already been handled, so now
     * we can exit this thread and allow the service thread to exit.
     */
    if (isWindowsNT() && isProcessService() && globdat.connected) {
        service_set_status(SERVICE_STOPPED);
        ExitThread(0);
    }
#endif

    if (!real_exit_code)
        return;
    hConIn = GetStdHandle(STD_INPUT_HANDLE);
    hConErr = GetStdHandle(STD_ERROR_HANDLE);
    if ((hConIn == INVALID_HANDLE_VALUE) || (hConErr == INVALID_HANDLE_VALUE))
        return;
    if (!WriteConsole(hConErr, msg, strlen(msg), &result, NULL) || !result)
        return;
    if (!GetConsoleScreenBufferInfo(hConErr, &coninfo))
        return;
    if (isWindowsNT())
        mode = ENABLE_MOUSE_INPUT | 0x80;
    else
        mode = ENABLE_MOUSE_INPUT;
    if (!SetConsoleMode(hConIn, mode))
        return;
        
    start = time(NULL);
    do
    {
        while (PeekConsoleInput(hConIn, &in, 1, &result) && result)
        {
            if (!ReadConsoleInput(hConIn, &in, 1, &result) || !result)
                return;
            if ((in.EventType == KEY_EVENT) && in.Event.KeyEvent.bKeyDown 
                    && (in.Event.KeyEvent.uChar.AsciiChar == 27))
                return;
            if (in.EventType == MOUSE_EVENT 
                    && (in.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK))
                return;
        }
        remains = ((start + 30) - time(NULL)); 
        sprintf (count, "%d...", remains);
        if (!SetConsoleCursorPosition(hConErr, coninfo.dwCursorPosition))
            return;
        if (!WriteConsole(hConErr, count, strlen(count), &result, NULL) 
                || !result)
            return;
    }
    while ((remains > 0) && WaitForSingleObject(hConIn, 1000) != WAIT_FAILED);
}

/* Console Control handler for processing Ctrl-C/Ctrl-Break and
 * on Windows NT also user logoff and system shutdown,
 * this also used for the Win9x hidden service and child process
 */
static BOOL CALLBACK ap_control_handler(DWORD ctrl_type)
{
    switch (ctrl_type)
    {
        case CTRL_C_EVENT:
        case CTRL_BREAK_EVENT:
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
                         "Ctrl+C/Break initiated, shutting down server.");

            real_exit_code = 0;
            /* for Interrupt signals, shut down the server.
             * Tell the system we have dealt with the signal
             * without waiting for Apache to terminate.
             */
            ap_start_shutdown();
            return TRUE;

        case CTRL_LOGOFF_EVENT:
            if (!die_on_logoff)
                return TRUE;
            /* or fall through... */

        case CTRL_CLOSE_EVENT:
        case CTRL_SHUTDOWN_EVENT:
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
                         "Close/Logoff/Shutdown initiated, shutting down server.");

            /* for Terminate signals, shut down the server.
             * Wait for Apache to terminate, but respond
             * after a reasonable time to tell the system
             * that we have already tried to shut down.
             */
            real_exit_code = 0;
            fprintf(stderr, "Apache server shutdown initiated...\n");
            ap_start_shutdown();
            Sleep(30000);
            return TRUE;
    }
 
    /* We should never get here, but this is (mostly) harmless */
    return FALSE;
}

/* Once we are running a child process in our tty, it can no longer 
 * determine which console window is our own, since the window
 * reports that it is owned by the child process.
 */
static BOOL CALLBACK EnumttyWindow(HWND wnd, LPARAM retwnd)
{
    char tmp[20], *tty;
    if (isWindowsNT())
        tty = "ConsoleWindowClass";
    else
        tty = "tty";
    if (GetClassName(wnd, tmp, sizeof(tmp)) && !strcmp(tmp, tty)) 
    {
        DWORD wndproc, thisproc = GetCurrentProcessId();
        GetWindowThreadProcessId(wnd, &wndproc);
        if (wndproc == thisproc) {
            *((HWND*)retwnd) = wnd;
            return FALSE;
        }
    }
    return TRUE;
}

void stop_child_monitor(void)
{
    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
                 "Unhooking the child process monitor for shutdown.");

    FixConsoleCtrlHandler(ap_control_handler, 0);
}

/*
 * The Win32 Apache child cannot loose its console since 16bit cgi 
 * processes will hang (9x) or fail (NT) if they are not launched 
 * from a 32bit console app into that app's console window.  
 * Mark the 9x child as a service process and let the parent process 
 * clean it up as necessary.
 */
void ap_start_child_console(int is_child_of_service)
{
    int maxwait = 100;

    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
                 "Hooking up the child process monitor to watch for shutdown.");

    /* The child is never exactly a service */
    is_service = 0;
    
    /* Prevent holding open the (hidden) console */
    real_exit_code = 0;

    /* We only die on logoff if we not a service's child */
    die_on_logoff = !is_child_of_service;

    if (isWindowsNT()) {
        if (!is_child_of_service) {
            /*
             * Console mode Apache/WinNT needs to detach from the parent
             * console and create and hide it's own console window.
             * Not only is logout and shutdown more stable under W2K,
             * but this eliminates the mystery 'flicker' that users see
             * when invoking CGI apps (e.g. the titlebar or icon of the
             * console window changing to the cgi process's identifiers.)
             */
            FreeConsole();
            AllocConsole();
            EnumWindows(EnumttyWindow, (long)(&console_wnd));
            if (console_wnd)
                ShowWindow(console_wnd, SW_HIDE);
        }
        /*
         * Apache/WinNT installs no child console handler, otherwise
         * logoffs interfere with the service's child process!
         * The child process must have a later shutdown priority
         * than the parent, or the parent cannot shut down the
         * child process properly.  (The parent's default is 0x280.)
         */
        SetProcessShutdownParameters(0x200, 0);
        return;
    }

    if (!is_child_of_service) {
        FreeConsole();
        AllocConsole();
    }
    while (!console_wnd && maxwait-- > 0) { 
        EnumWindows(EnumttyWindow, (long)(&console_wnd));
        Sleep(100);
    }
    if (console_wnd) {
        FixConsoleCtrlHandler(ap_control_handler, die_on_logoff ? 1 : 2);
        ShowWindow(console_wnd, SW_HIDE);
        atexit(stop_child_monitor);
    }
}


void stop_console_monitor(void)
{
    /* Remove the control handler at the end of the day. */
    SetConsoleCtrlHandler(ap_control_handler, FALSE);

    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
                 "Unhooking the console monitor for shutdown.");

    if (!isWindowsNT())
        FixConsoleCtrlHandler(ap_control_handler, 0);
}

void ap_start_console_monitor(void)
{
    HANDLE console_input;

    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
                 "Hooking up the console monitor to watch for shutdown.");

    die_on_logoff = TRUE;

    is_service = 0;

    console_input = GetStdHandle(STD_INPUT_HANDLE);
    /* Assure we properly accept Ctrl+C as an interrupt...
     * Win/2000 definately makes some odd assumptions about 
     * ctrl+c and the reserved console mode bits!
     */
    if (console_input != INVALID_HANDLE_VALUE)
    {
        /* The SetConsoleCtrlHandler(NULL... would fault under Win9x 
         * WinNT also includes an undocumented 0x80 bit for console mode
         * that preserves the console window behavior, and prevents the
         * bogus 'selection' mode from being accedently triggered.
         */
        if (isWindowsNT()) {
	    SetConsoleCtrlHandler(NULL, FALSE);
            SetConsoleMode(console_input, ENABLE_LINE_INPUT 
                                        | ENABLE_ECHO_INPUT 
                                        | ENABLE_PROCESSED_INPUT
                                        | 0x80);
        }
	else {
            SetConsoleMode(console_input, ENABLE_LINE_INPUT 
                                        | ENABLE_ECHO_INPUT 
                                        | ENABLE_PROCESSED_INPUT);
        }
    }
    
    if (!isWindowsNT())
        FixConsoleCtrlHandler(ap_control_handler, die_on_logoff ? 1 : 2);

    SetConsoleCtrlHandler(ap_control_handler, TRUE);

    atexit(stop_console_monitor);
}

void stop_service_monitor(void)
{
    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
                 "Unhooking up the service monitor for shutdown.");

    Windows9xServiceCtrlHandler(ap_control_handler, FALSE);
}

int service95_main(int (*main_fn)(int, char **), int argc, char **argv, 
		   char *display_name)
{
    /* Windows 95/98 */
    char *service_name;

    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
                 "Hooking up the service monitor to watch for shutdown.");

    is_service = 1;
    die_on_logoff = FALSE;

    /* Set up the Win9x server name, as WinNT would */
    ap_server_argv0 = globdat.name = display_name;

    /* Remove spaces from display name to create service name */
    service_name = strdup(display_name);
    ap_remove_spaces(service_name, display_name);

    /* Prevent holding open the (hidden) console */
    real_exit_code = 0;

    Windows9xServiceCtrlHandler(ap_control_handler, service_name);

    atexit(stop_service_monitor);
    
    /* Run the service */
    globdat.exit_status = main_fn(argc, argv);

    return (globdat.exit_status);
}

static HANDLE eventlog_pipewrite = NULL;
static HANDLE eventlog_thread = NULL;

int service_main(int (*main_fn)(int, char **), int argc, char **argv )
{
    SERVICE_TABLE_ENTRY dispatchTable[] =
    {
        { "", service_main_fn },
        { NULL, NULL }
    };

    /* Prevent holding open the (nonexistant) console and allow us past
     * the first NT service to parse the service's args in apache_main() 
     */
    ap_server_argv0 = argv[0];
    real_exit_code = 0;

    /* keep the server from going to any real effort, since we know */
    is_service = 1;

    globdat.main_fn = main_fn;
    globdat.connected = 1;

    if(!StartServiceCtrlDispatcher(dispatchTable))
    {
        /* This is a genuine failure of the SCM. */
        ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
                     "Error starting service control dispatcher");
    }

    globdat.connected = 0;

    if (eventlog_pipewrite)
    {
        CloseHandle(eventlog_pipewrite);
        WaitForSingleObject(eventlog_thread, 10000);
        eventlog_pipewrite = NULL;
    }

    return(globdat.exit_status);
}

long __stdcall service_stderr_thread(LPVOID hPipe)
{
    HANDLE hPipeRead = (HANDLE) hPipe;
    HANDLE hEventSource;
    char errbuf[256];
    char *errmsg = errbuf;
    char *errarg[9];
    DWORD errlen = 0;
    DWORD errres;
    HKEY hk;
    
    errarg[0] = "The Apache service named";
    errarg[1] = ap_server_argv0;
    errarg[2] = "reported the following error:\r\n>>>";
    errarg[3] = errmsg;
    errarg[4] = "<<<\r\n before the error.log file could be opened.\r\n";
    errarg[5] = "More information may be available in the error.log file.";
    errarg[6] = NULL;
    errarg[7] = NULL;
    errarg[8] = NULL;
    
    /* What are we going to do in here, bail on the user?  not. */
    if (!RegCreateKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services"
                      "\\EventLog\\Application\\Apache Service", &hk)) 
    {
        /* The stock message file */
        char *netmsgkey = "%SystemRoot%\\System32\\netmsg.dll";
        DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | 
                       EVENTLOG_INFORMATION_TYPE; 
 
        RegSetValueEx(hk, "EventMessageFile", 0, REG_EXPAND_SZ,
                          (LPBYTE) netmsgkey, strlen(netmsgkey) + 1);
        
        RegSetValueEx(hk, "TypesSupported", 0, REG_DWORD,
                          (LPBYTE) &dwData, sizeof(dwData));
        RegCloseKey(hk);
    }

    hEventSource = RegisterEventSource(NULL, "Apache Service");

    while (ReadFile(hPipeRead, errmsg, 1, &errres, NULL) && (errres == 1))
    {
        if ((errmsg > errbuf) || !isspace(*errmsg))
        {
            ++errlen;
            ++errmsg;
            if ((*(errmsg - 1) == '\n') || (errlen == sizeof(errbuf) - 1))
            {
                while (errlen && isspace(errbuf[errlen - 1]))
                    --errlen;
                errbuf[errlen] = '\0';

                /* Generic message: '%1 %2 %3 %4 %5 %6 %7 %8 %9'
                 * The event code in netmsg.dll is 3299
                 */
                ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, 
                            3299, NULL, 9, 0, errarg, NULL);
                errmsg = errbuf;
                errlen = 0;
            }
        }
    }

    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
                 "Shut down the Service Error Event Logger.");

    CloseHandle(eventlog_pipewrite);
    eventlog_pipewrite = NULL;
    
    CloseHandle(hPipeRead);

    CloseHandle(eventlog_thread);
    eventlog_thread = NULL;
    return 0;
}

void __stdcall service_main_fn(DWORD argc, LPTSTR *argv)
{
    HANDLE hCurrentProcess;
    HANDLE hPipeRead = NULL;
    HANDLE hPipeReadDup;
    HANDLE hNullFile;
    DWORD  threadid;
    SECURITY_ATTRIBUTES sa = {0};
    char **newargv;

    if(!(globdat.hServiceStatus = RegisterServiceCtrlHandler(argv[0], 
                                                             service_ctrl)))
    {
        ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL,
        "Failure registering service handler");
        return;
    }

    ReportStatusToSCMgr(
        SERVICE_START_PENDING, // service state
        NO_ERROR,              // exit code
        3000);                 // wait hint

    /* Create a pipe to send stderr messages to the system error log */
    hCurrentProcess = GetCurrentProcess();
    if (CreatePipe(&hPipeRead, &eventlog_pipewrite, &sa, 0)) 
    {
        if (DuplicateHandle(hCurrentProcess, hPipeRead, hCurrentProcess,
                            &hPipeReadDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
        {
            CloseHandle(hPipeRead);
            hPipeRead = hPipeReadDup;
            eventlog_thread = CreateThread(NULL, 0, service_stderr_thread, 
                                           (LPVOID) hPipeRead, 0, &threadid);
            if (eventlog_thread)
            {
                int fh;
                FILE *fl;
            	fflush(stderr);
		SetStdHandle(STD_ERROR_HANDLE, eventlog_pipewrite);
				
                fh = _open_osfhandle((long) STD_ERROR_HANDLE, 
                                     _O_WRONLY | _O_BINARY);
                dup2(fh, STDERR_FILENO);
                fl = _fdopen(STDERR_FILENO, "wcb");
                memcpy(stderr, fl, sizeof(FILE));
            }
            else
            {
                CloseHandle(hPipeRead);
                CloseHandle(eventlog_pipewrite);
                eventlog_pipewrite = NULL;
            }            
        }
        else
        {
            CloseHandle(hPipeRead);
            CloseHandle(eventlog_pipewrite);
            eventlog_pipewrite = NULL;
        }            
    }

    /* Open a null handle to nak our stdin */
    hNullFile = CreateFile("nul", GENERIC_READ | GENERIC_WRITE, 
                           FILE_SHARE_READ | FILE_SHARE_WRITE, 
                           &sa, OPEN_EXISTING, 0, NULL);
    if (hNullFile == INVALID_HANDLE_VALUE) {
        ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, NULL,
                     "Parent: Unable to create null stdin pipe for this service process.\n");
    }
    else {
        int fh;
        FILE *fl;
        fflush(stdin);
	SetStdHandle(STD_INPUT_HANDLE, hNullFile);
        fh = _open_osfhandle((long) STD_INPUT_HANDLE, 
                             _O_RDONLY | _O_BINARY);
        dup2(fh, STDIN_FILENO);
        fl = _fdopen(STDIN_FILENO, "rcb");
        memcpy(stdin, fl, sizeof(FILE));
    }

    /* Open a null handle to soak our stdout */
    hNullFile = CreateFile("nul", GENERIC_READ | GENERIC_WRITE, 
                           FILE_SHARE_READ | FILE_SHARE_WRITE, 
                           &sa, OPEN_EXISTING, 0, NULL);
    if (hNullFile == INVALID_HANDLE_VALUE) {
        ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, NULL,
                     "Parent: Unable to create null stdout pipe for this service process.\n");
    }
    else {
        int fh;
        FILE *fl;
        fflush(stdout);
	SetStdHandle(STD_OUTPUT_HANDLE, hNullFile);
        fh = _open_osfhandle((long) STD_OUTPUT_HANDLE, 
                             _O_WRONLY | _O_BINARY);
        dup2(fh, STDOUT_FILENO);
        fl = _fdopen(STDOUT_FILENO, "wcb");
        memcpy(stdout, fl, sizeof(FILE));
    }

    /* Grab it or lose it */
    globdat.name = argv[0];

    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, NULL,
             "Hooked up the Service Error Event Logger.");

    /* Fold the "Start Parameters" in with the true executable argv[0],
     * and insert a -n tag to pass the service name from the SCM's argv[0]
     */
    newargv = (char**) malloc((argc + 3) * sizeof(char*));
    newargv[0] = ap_server_argv0;  /* The true executable name */
    newargv[1] = "-n";             /* True service name follows (argv[0]) */
    memcpy (newargv + 2, argv, argc * sizeof(char*));
    newargv[argc + 2] = NULL;      /* SCM doesn't null terminate the array */
    argv = newargv;
    argc += 2;

    /* Use the name of the service as the error log marker */
    ap_server_argv0 = globdat.name;

    globdat.exit_status = globdat.main_fn( argc, argv );
}

/* Set the service description regardless of platform.
 * We revert to set_service_description_string on NT/9x, the
 * very long way so any Apache management program can grab the
 * description.  This would be bad on Win2000, since it wouldn't
 * notify the service control manager of the name change.
 */
static void set_service_description_string(const char *description)
{
    char szPath[MAX_PATH];
    HKEY hkey;

    /* Create/Find the Service key that Monitor Applications iterate */
    ap_snprintf(szPath, sizeof(szPath), 
                "SYSTEM\\CurrentControlSet\\Services\\%s", globdat.name);
    ap_remove_spaces(szPath, szPath);
    if (RegCreateKey(HKEY_LOCAL_MACHINE, szPath, &hkey) != ERROR_SUCCESS) {
        return;
    }

    /* Attempt to set the Description value for our service */
    RegSetValueEx(hkey, "Description", 0, REG_SZ,  
                  (unsigned char *) description, 
                  strlen(description) + 1);
    RegCloseKey(hkey);
}


char *get_service_name(char *display_name)
{
    /* Get the service's true name from the SCM on NT/2000, since it
     * can be changed by the user on 2000, especially, from the
     * service control panel.  We can't trust the service name to 
     * match a space-collapsed display name.
     */
    char service_name[MAX_PATH];
    if (isWindowsNT())
    {
        SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
        DWORD namelen = sizeof(service_name);
        if (scm) {
            BOOL ok = GetServiceKeyName(scm, display_name, service_name, 
                                        &namelen);
            CloseServiceHandle(scm);
            if (ok)
                return strdup(service_name);
        }
    }
    ap_remove_spaces(service_name, display_name);
    return strdup(service_name);
}


char *get_display_name(char *service_name)
{
    /* Get the service's display name from the SCM on NT/2000, since it
     * can be changed by the user on 2000, especially, from the
     * service control panel.  We can't trust the service name as
     * provided by the user.
     */
    if (isWindowsNT())
    {
        char display_name[MAX_PATH];
        SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
        DWORD namelen = sizeof(display_name);
        if (scm) {
            BOOL ok = GetServiceDisplayName(scm, service_name, display_name,
                                            &namelen);
            CloseServiceHandle(scm);
            if (ok)
                return strdup(display_name);
        }
    }
    return service_name;
}


/* ChangeServiceConfig2() prototype:
 */
typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);


/* Windows 2000 alone supports ChangeServiceConfig2 in order to
 * register our server_version string... so we need some fixups
 * to avoid binding to that function if we are on WinNT/9x.
 * Fall back on set_service_description_string if we fail.
 */
void service_set_status(int status)
{
    const char *full_description;
    SC_HANDLE schSCManager;
    CSD_T ChangeServiceDescription;
    HANDLE hwin2000scm;
    BOOL ret = 0;

    /* Nothing to do if we are a console
     */
    if (!is_service)
        return;

    ReportStatusToSCMgr(status, NO_ERROR, 3000);

    if (status != SERVICE_RUNNING)
        return;

    /* Time to fix up the description, upon each successful restart
     */
    full_description = ap_get_server_version();
    hwin2000scm = GetModuleHandle("ADVAPI32.DLL");
    if (!hwin2000scm) {
        set_service_description_string(full_description);
        return;
    }
    ChangeServiceDescription = (CSD_T) GetProcAddress(hwin2000scm, 
                                                      "ChangeServiceConfig2A");
    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");
        }
        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 */
