/* 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.
 */

/* ====================================================================
 * prunsrv -- Service Runner.
 * Contributed by Mladen Turk <mturk@apache.org>
 * 05 Aug 2003
 * ====================================================================
 */

/* Force the JNI vprintf functions */
#define _DEBUG_JNI  1
#include "apxwin.h"
#include "private.h"
#include "prunsrv.h"

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <fcntl.h>
#include <io.h>         /* _open_osfhandle */
#include <share.h>

#ifndef  MIN
#define  MIN(a,b)    (((a)<(b)) ? (a) : (b))
#endif

#define STDIN_FILENO  0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define ONE_MINUTE    (60 * 1000)

#ifdef _WIN64
#define KREG_WOW6432  KEY_WOW64_32KEY
#define PRG_BITS      64
#else
#define KREG_WOW6432  0
#define PRG_BITS      32
#endif

typedef struct APX_STDWRAP {
    LPCWSTR szLogPath;
    LPCWSTR szStdOutFilename;
    LPCWSTR szStdErrFilename;
    FILE   *fpStdOutFile;
    FILE   *fpStdErrFile;
} APX_STDWRAP;

/* Use static variables instead of #defines */
static LPCWSTR  PRSRV_AUTO        = L"auto";
static LPCWSTR  PRSRV_JAVA        = L"java";
static LPCWSTR  PRSRV_JVM         = L"jvm";
static LPCWSTR  PRSRV_JDK         = L"jdk";
static LPCWSTR  PRSRV_JRE         = L"jre";
static LPCWSTR  PRSRV_DELAYED     = L"delayed";
static LPCWSTR  PRSRV_MANUAL      = L"manual";
static LPCWSTR  PRSRV_JBIN        = L"\\bin\\java.exe";
static LPCWSTR  PRSRV_PBIN        = L"\\bin";
static LPCWSTR  PRSRV_SIGNAL      = L"SIGNAL";
static LPCWSTR  PRSV_JVMOPTS9     = L"JDK_JAVA_OPTIONS=";
static LPCWSTR  STYPE_INTERACTIVE = L"interactive";

static LPWSTR       _service_name = NULL;
/* Allowed procrun commands */
static LPCWSTR _commands[] = {
    L"TS",      /*  1 Run Service as console application (default)*/
    L"RS",      /*  2 Run Service */
    L"ES",      /*  3 Execute start */
    L"SS",      /*  4 Stop Service */
    L"US",      /*  5 Update Service parameters */
    L"IS",      /*  6 Install Service */
    L"DS",      /*  7 Delete Service */
    L"PS",      /*  8 Print Service Configuration */
    L"?",       /*  9 Help */
    L"VS",      /* 10 Version */
    NULL
};

static LPCWSTR _altcmds[] = {
    L"run",         /*  1 Run Service as console application (default)*/
    L"service",     /*  2 Run Service */
    L"start",       /*  3 Start Service */
    L"stop",        /*  4 Stop Service */
    L"update",      /*  5 Update Service parameters */
    L"install",     /*  6 Install Service */
    L"delete",      /*  7 Delete Service */
	L"print",       /*  8 Print Service Configuration */
    L"help",        /*  9 Help */
    L"version",     /* 10 Version */
    NULL
};

/* Allowed procrun parameters */
static APXCMDLINEOPT _options[] = {

/* 0  */    { L"Description",       L"Description",     NULL,           APXCMDOPT_STR | APXCMDOPT_SRV, NULL, 0},
/* 1  */    { L"DisplayName",       L"DisplayName",     NULL,           APXCMDOPT_STR | APXCMDOPT_SRV, NULL, 0},
/* 2  */    { L"Install",           L"ImagePath",       NULL,           APXCMDOPT_STE | APXCMDOPT_SRV, NULL, 0},
/* 3  */    { L"ServiceUser",       L"ServiceUser",     NULL,           APXCMDOPT_STR | APXCMDOPT_SRV, NULL, 0},
/* 4  */    { L"ServicePassword",   L"ServicePassword", NULL,           APXCMDOPT_STR | APXCMDOPT_SRV, NULL, 0},
/* 5  */    { L"Startup",           L"Startup",         NULL,           APXCMDOPT_STR | APXCMDOPT_SRV, NULL, 0},
/* 6  */    { L"Type",              L"Type",            NULL,           APXCMDOPT_STR | APXCMDOPT_SRV, NULL, 0},

/* 7  */    { L"DependsOn",         L"DependsOn",       NULL,           APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 8  */    { L"Environment",       L"Environment",     NULL,           APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 9  */    { L"User",              L"User",            NULL,           APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 10 */    { L"Password",          L"Password",        NULL,           APXCMDOPT_BIN | APXCMDOPT_REG, NULL, 0},
/* 11 */    { L"LibraryPath",       L"LibraryPath",     NULL,           APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},

/* 12 */    { L"JavaHome",          L"JavaHome",        L"Java",        APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 13 */    { L"Jvm",               L"Jvm",             L"Java",        APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 14 */    { L"JvmOptions",        L"Options",         L"Java",        APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 15 */    { L"JvmOptions9",       L"Options9",        L"Java",        APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 16 */    { L"Classpath",         L"Classpath",       L"Java",        APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 17 */    { L"JvmMs",             L"JvmMs",           L"Java",        APXCMDOPT_INT | APXCMDOPT_REG, NULL, 0},
/* 18 */    { L"JvmMx",             L"JvmMx",           L"Java",        APXCMDOPT_INT | APXCMDOPT_REG, NULL, 0},
/* 19 */    { L"JvmSs",             L"JvmSs",           L"Java",        APXCMDOPT_INT | APXCMDOPT_REG, NULL, 0},

/* 20 */    { L"StopImage",         L"Image",           L"Stop",        APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 21 */    { L"StopPath",          L"WorkingPath",     L"Stop",        APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 22 */    { L"StopClass",         L"Class",           L"Stop",        APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 23 */    { L"StopParams",        L"Params",          L"Stop",        APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 24 */    { L"StopMethod",        L"Method",          L"Stop",        APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 25 */    { L"StopMode",          L"Mode",            L"Stop",        APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 26 */    { L"StopTimeout",       L"Timeout",         L"Stop",        APXCMDOPT_INT | APXCMDOPT_REG, NULL, 0},

/* 27 */    { L"StartImage",        L"Image",           L"Start",       APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 28 */    { L"StartPath",         L"WorkingPath",     L"Start",       APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 29 */    { L"StartClass",        L"Class",           L"Start",       APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 30 */    { L"StartParams",       L"Params",          L"Start",       APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 31 */    { L"StartMethod",       L"Method",          L"Start",       APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 32 */    { L"StartMode",         L"Mode",            L"Start",       APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},

/* 33 */    { L"LogPath",           L"Path",            L"Log",         APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 34 */    { L"LogPrefix",         L"Prefix",          L"Log",         APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 35 */    { L"LogLevel",          L"Level",           L"Log",         APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 36 */    { L"StdError",          L"StdError",        L"Log",         APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 37 */    { L"StdOutput",         L"StdOutput",       L"Log",         APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 38 */    { L"LogJniMessages",    L"LogJniMessages",  L"Log",         APXCMDOPT_INT | APXCMDOPT_REG, NULL, 1},
/* 39 */    { L"PidFile",           L"PidFile",         L"Log",         APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 40 */    { L"Rotate",            L"Rotate",          L"Log",         APXCMDOPT_INT | APXCMDOPT_REG, NULL, 0},
            /* NULL terminate the array */
            { NULL }
};

#define GET_OPT_V(x)  _options[x].szValue
#define GET_OPT_I(x)  _options[x].dwValue
#define GET_OPT_T(x)  _options[x].dwType

#define ST_DESCRIPTION      GET_OPT_T(0)
#define ST_DISPLAYNAME      GET_OPT_T(1)
#define ST_INSTALL          GET_OPT_T(2)
#define ST_SUSER            GET_OPT_T(3)
#define ST_SPASSWORD        GET_OPT_T(4)
#define ST_STARTUP          GET_OPT_T(5)
#define ST_TYPE             GET_OPT_T(6)

#define SO_DESCRIPTION      GET_OPT_V(0)
#define SO_DISPLAYNAME      GET_OPT_V(1)
#define SO_INSTALL          GET_OPT_V(2)
#define SO_SUSER            GET_OPT_V(3)
#define SO_SPASSWORD        GET_OPT_V(4)
#define SO_STARTUP          GET_OPT_V(5)
#define SO_TYPE             GET_OPT_V(6)

#define SO_DEPENDSON        GET_OPT_V(7)
#define SO_ENVIRONMENT      GET_OPT_V(8)

#define SO_USER             GET_OPT_V(9)
#define SO_PASSWORD         GET_OPT_V(10)
#define SO_LIBPATH          GET_OPT_V(11)

#define SO_JAVAHOME         GET_OPT_V(12)
#define SO_JVM              GET_OPT_V(13)
#define SO_JVMOPTIONS       GET_OPT_V(14)
#define SO_JVMOPTIONS9      GET_OPT_V(15)
#define SO_CLASSPATH        GET_OPT_V(16)
#define SO_JVMMS            GET_OPT_I(17)
#define SO_JVMMX            GET_OPT_I(18)
#define SO_JVMSS            GET_OPT_I(19)

#define SO_STOPIMAGE        GET_OPT_V(20)
#define SO_STOPPATH         GET_OPT_V(21)
#define SO_STOPCLASS        GET_OPT_V(22)
#define SO_STOPPARAMS       GET_OPT_V(23)
#define SO_STOPMETHOD       GET_OPT_V(24)
#define SO_STOPMODE         GET_OPT_V(25)
#define SO_STOPTIMEOUT      GET_OPT_I(26)

#define SO_STARTIMAGE       GET_OPT_V(27)
#define SO_STARTPATH        GET_OPT_V(28)
#define SO_STARTCLASS       GET_OPT_V(29)
#define SO_STARTPARAMS      GET_OPT_V(30)
#define SO_STARTMETHOD      GET_OPT_V(31)
#define SO_STARTMODE        GET_OPT_V(32)

#define SO_LOGPATH          GET_OPT_V(33)
#define SO_LOGPREFIX        GET_OPT_V(34)
#define SO_LOGLEVEL         GET_OPT_V(35)

#define SO_STDERROR         GET_OPT_V(36)
#define SO_STDOUTPUT        GET_OPT_V(37)
#define SO_JNIVFPRINTF      GET_OPT_I(38)
#define SO_PIDFILE          GET_OPT_V(39)
#define SO_LOGROTATE        GET_OPT_I(40)

static SERVICE_STATUS        _service_status;
static SERVICE_STATUS_HANDLE _service_status_handle = NULL;
/* Set if launched by SCM   */
static BOOL                  _service_mode = FALSE;
/* JVM used as worker       */
static BOOL                  _jni_startup  = FALSE;
/* JVM used for shutdown    */
static BOOL                  _jni_shutdown = FALSE;
/* Java used as worker       */
static BOOL                  _java_startup  = FALSE;
/* Java used for shutdown    */
static BOOL                  _java_shutdown = FALSE;
/* Global variables and objects */
static APXHANDLE    gPool;
static APXHANDLE    gWorker;
static APX_STDWRAP  gStdwrap;           /* stdio/stderr redirection */
static int          gExitval;
static LPWSTR       gStartPath;

static LPWSTR   _jni_jvmpath              = NULL;   /* Path to jvm dll */
static LPSTR    _jni_jvmoptions           = NULL;   /* jvm options */
static LPSTR    _jni_jvmoptions9          = NULL;   /* java 9+ options */

static LPSTR    _jni_classpath            = NULL;
static LPCWSTR  _jni_rparam               = NULL;    /* Startup  arguments */
static LPCWSTR  _jni_sparam               = NULL;    /* Shutdown arguments */
static LPSTR    _jni_rmethod              = NULL;    /* Startup  method */
static LPSTR    _jni_smethod              = NULL;    /* Shutdown method */
static LPSTR    _jni_rclass               = NULL;    /* Startup  class */
static LPSTR    _jni_sclass               = NULL;    /* Shutdown class */
static HANDLE gShutdownEvent = NULL;
static HANDLE gSignalEvent   = NULL;
static HANDLE gSignalThread  = NULL;
static HANDLE gPidfileHandle = NULL;
static LPWSTR gPidfileName   = NULL;
static BOOL   gSignalValid   = TRUE;
static APXJAVA_THREADARGS gRargs;
static APXJAVA_THREADARGS gSargs;

DWORD WINAPI eventThread(LPVOID lpParam)
{
    DWORD dwRotateCnt = SO_LOGROTATE;

    for (;;) {
        DWORD dw = WaitForSingleObject(gSignalEvent, 1000);
        if (dw == WAIT_TIMEOUT) {
            /* Do process maintenance */
            if (SO_LOGROTATE != 0 && --dwRotateCnt == 0) {
                /* Perform log rotation. */

                 dwRotateCnt = SO_LOGROTATE;
            }
            continue;
        }
        if (dw == WAIT_OBJECT_0 && gSignalValid) {
            if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)) {
                /* Invoke Thread dump */
                if (gWorker && _jni_startup)
                    apxJavaDumpAllStacks(gWorker);
            }
            ResetEvent(gSignalEvent);
            continue;
        }
        break;
    }
    ExitThread(0);
    return 0;
    UNREFERENCED_PARAMETER(lpParam);
}

/* redirect console stdout/stderr to files
 * so that Java messages can get logged
 * If stderrfile is not specified it will
 * go to stdoutfile.
 */
static BOOL redirectStdStreams(APX_STDWRAP *lpWrapper, LPAPXCMDLINE lpCmdline)
{
    BOOL aErr = FALSE;
    BOOL aOut = FALSE;

    /* Allocate console if we have none
     */
    if (GetConsoleWindow() == NULL) {
        HWND hc;
        AllocConsole();
        if ((hc = GetConsoleWindow()) != NULL)
            ShowWindow(hc, SW_HIDE);
    }
    /* redirect to file or console */
    if (lpWrapper->szStdOutFilename) {
        if (lstrcmpiW(lpWrapper->szStdOutFilename, PRSRV_AUTO) == 0) {
            WCHAR lsn[1024];
            aOut = TRUE;
            lstrlcpyW(lsn, 1020, lpCmdline->szApplication);
            lstrlcatW(lsn, 1020, L"-stdout");
            lstrlocaseW(lsn);
            lpWrapper->szStdOutFilename = apxLogFile(gPool,
                                                     lpWrapper->szLogPath,
                                                     lsn,
                                                     NULL, TRUE,
                                                     SO_LOGROTATE);
        }
        /* Delete the file if not in append mode
         * XXX: See if we can use the params instead of that.
         */
        if (!aOut)
            DeleteFileW(lpWrapper->szStdOutFilename);
        if ((lpWrapper->fpStdOutFile = _wfsopen(lpWrapper->szStdOutFilename,
                                               L"a",
                                               _SH_DENYNO))) {
            _dup2(_fileno(lpWrapper->fpStdOutFile), 1);
            *stdout = *lpWrapper->fpStdOutFile;
            setvbuf(stdout, NULL, _IONBF, 0);
        }
        else {
            lpWrapper->szStdOutFilename = NULL;
        }
    }
    if (lpWrapper->szStdErrFilename) {
        if (lstrcmpiW(lpWrapper->szStdErrFilename, PRSRV_AUTO) == 0) {
            WCHAR lsn[1024];
            aErr = TRUE;
            lstrlcpyW(lsn, 1020, lpCmdline->szApplication);
            lstrlcatW(lsn, 1020, L"-stderr");
            lstrlocaseW(lsn);
            lpWrapper->szStdErrFilename = apxLogFile(gPool,
                                                     lpWrapper->szLogPath,
                                                     lsn,
                                                     NULL, TRUE,
                                                     SO_LOGROTATE);
        }
        if (!aErr)
            DeleteFileW(lpWrapper->szStdErrFilename);
        if ((lpWrapper->fpStdErrFile = _wfsopen(lpWrapper->szStdErrFilename,
                                               L"a",
                                               _SH_DENYNO))) {
            _dup2(_fileno(lpWrapper->fpStdErrFile), 2);
            *stderr = *lpWrapper->fpStdErrFile;
            setvbuf(stderr, NULL, _IONBF, 0);
        }
        else {
            lpWrapper->szStdOutFilename = NULL;
        }
    }
    else if (lpWrapper->fpStdOutFile) {
        _dup2(_fileno(lpWrapper->fpStdOutFile), 2);
        *stderr = *lpWrapper->fpStdOutFile;
         setvbuf(stderr, NULL, _IONBF, 0);
    }
    return TRUE;
}

/* Debugging functions */
static void printUsage(LPAPXCMDLINE lpCmdline, BOOL isHelp)
{
    int i = 0;
    fwprintf(stderr, L"Usage: %s command [ServiceName] [--options]\n",
             lpCmdline->szExecutable);
    fwprintf(stderr, L"  Commands:\n");
    if (isHelp)
        fwprintf(stderr, L"  help                   This page\n");
    fwprintf(stderr, L"  install [ServiceName]  Install Service\n");
    fwprintf(stderr, L"  update  [ServiceName]  Update Service parameters\n");
    fwprintf(stderr, L"  delete  [ServiceName]  Delete Service\n");
    fwprintf(stderr, L"  start   [ServiceName]  Start Service\n");
    fwprintf(stderr, L"  stop    [ServiceName]  Stop Service\n");
    fwprintf(stderr, L"  run     [ServiceName]  Run Service as console application\n");
    fwprintf(stderr, L"  print   [ServiceName]  Display the command to (re-)create the current configuration\n");
    fwprintf(stderr, L"  pause   [Num Seconds]  Sleep for n Seconds (defaults to 60)\n");
    fwprintf(stderr, L"  version                Display version\n");
    fwprintf(stderr, L"  Options:\n");
    while (_options[i].szName) {
        fwprintf(stderr, L"  --%s\n", _options[i].szName);
        ++i;
    }
}

static void printVersion(void)
{
    fwprintf(stderr, L"Apache Commons Daemon Service Runner version %S/Win%d (%S)\n",
            PRG_VERSION, PRG_BITS, __DATE__);
    fwprintf(stderr, L"Copyright (c) 2000-2019 The Apache Software Foundation.\n\n"
                     L"For bug reporting instructions, please see:\n"
                     L"<URL:https://issues.apache.org/jira/browse/DAEMON>.");
}

/* Display comamnd line parameters */
static void dumpCmdline()
{
    int i = 0;
    while (_options[i].szName) {
        if (_options[i].dwType & APXCMDOPT_INT)
            fwprintf(stderr, L"--%-16s %d\n", _options[i].szName,
                     _options[i].dwValue);
        else if (_options[i].szValue)
            fwprintf(stderr, L"--%-16s %s\n", _options[i].szName,
                     _options[i].szValue);
        else
            fwprintf(stderr, L"--%-16s <NULL>\n", _options[i].szName);
        ++i;
    }
}

// TODO: Figure out a way to move apxSetInprocEnvironment from here and
// prunmgr.c to utils.c
void apxSetInprocEnvironment()
{
    LPWSTR p, e;
    HMODULE hmodUcrt;
    WPUTENV wputenv_ucrt = NULL;

    if (!SO_ENVIRONMENT)
        return;    /* Nothing to do */

    hmodUcrt = LoadLibraryExA("ucrtbase.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
    if (hmodUcrt != NULL) {
        wputenv_ucrt =  (WPUTENV) GetProcAddress(hmodUcrt, "_wputenv");
    }

    for (p = SO_ENVIRONMENT; *p; p++) {
        e = apxExpandStrW(gPool, p);
        _wputenv(e);
        if (wputenv_ucrt != NULL) {
            wputenv_ucrt(e);
        }
        apxFree(e);
        while (*p)
            p++;
    }
}

static void setInprocEnvironment9(LPCWSTR szOptions9)
{
    DWORD l, c;
    LPWSTR e, b;
    LPCWSTR p;

    l = __apxGetMultiSzLengthW(szOptions9, &c);

    if (!c)
        return;

    /* environment variable name */
    l += lstrlen(PRSV_JVMOPTS9);

    b = e = apxPoolCalloc(gPool, (l + 1) * sizeof(WCHAR));

    p = PRSV_JVMOPTS9;
    while (*p) {
        *b++ = *p++;
    }

    p = szOptions9;
    while (c > 0) {
        if (*p)
            *b++ = *p;
        else {
            *b++ = L' ';
            c--;
        }
        p++;
    }

    _wputenv(e);
    apxFree(e);
}

/* Sets environment variables required by some Java options
 * Currently only Native Memory Tracking
 */
static void setInprocEnvironmentOptions(LPCWSTR szOptions)
{
    LPCWSTR p;
    DWORD len;
    LPWSTR e;

    apxLogWrite(APXLOG_MARK_DEBUG "Checking Java options for environment variable requirements");

    p = szOptions;
    while (*p) {
        apxLogWrite(APXLOG_MARK_DEBUG "Checking '%S' for environment variable requirements", p);
        if (wcsncmp(p, L"-XX:NativeMemoryTracking=", 25) == 0) {
            apxLogWrite(APXLOG_MARK_DEBUG "Match found '%S'", p);
            /* Advance 25 characters to the start of the value */
            p += 25;
            apxLogWrite(APXLOG_MARK_DEBUG "Setting is '%S'", p);
            /* Ignore setting if it is off */
            if (wcsncmp(p, L"off", 3)) {
                apxLogWrite(APXLOG_MARK_DEBUG "Creating environment entry");
                /* Allocated space for the setting value */
                len = lstrlen(p);
                /* Expand space to include env var name less pid and '=' */
                len += 11;
                /* Expand spave to include pid (4 bytes, signed - up to 10 characters */
                len += 10;
                /* Expand space to include the null terminator */
                len++;

                /* Allocate the space */
                e = apxPoolCalloc(gPool, len * sizeof(WCHAR));

                /* Create the environment variable needed by NMT */
                swprintf_s(e, len, L"NMT_LEVEL_%d=%s", GetCurrentProcessId(), p);

                apxLogWrite(APXLOG_MARK_DEBUG "Created environment entry '%S'", e);
                /* Set the environment variable */
               _wputenv(e);

               apxFree(e);
            }
            return;
        }

        /* advance to the terminating null */
        while(*p) {
          p++;
        }

        /* advance to the start of the next entry
         * will be null if there are no more entries
         */
        p++;
    }
}

/* Load the configuration from Registry
 * loads only nonspecified items
 */
static BOOL loadConfiguration(LPAPXCMDLINE lpCmdline)
{
    APXHANDLE hRegistry;
    int i = 0;

    if (!lpCmdline->szApplication) {
        /* Handle empty service names */
        apxLogWrite(APXLOG_MARK_WARN "No service name provided.");
        return FALSE;
    }
    SetLastError(ERROR_SUCCESS);
    hRegistry = apxCreateRegistryW(gPool, KEY_READ | KREG_WOW6432,
                                   PRG_REGROOT,
                                   lpCmdline->szApplication,
                                   APXREG_SOFTWARE | APXREG_SERVICE);
    if (IS_INVALID_HANDLE(hRegistry)) {
        if (GetLastError() == ERROR_FILE_NOT_FOUND)
            apxLogWrite(APXLOG_MARK_WARN "The system cannot find the Registry key for service '%S'.",
                        lpCmdline->szApplication);
        else
            apxLogWrite(APXLOG_MARK_SYSERR);
        return FALSE;
    }
    /* browse through options */
    while (_options[i].szName) {
        DWORD dwFrom;

        dwFrom = (_options[i].dwType & APXCMDOPT_REG) ? APXREG_PARAMSOFTWARE : APXREG_SERVICE;
        if (!(_options[i].dwType & APXCMDOPT_FOUND)) {
            if (_options[i].dwType & APXCMDOPT_STR) {
                _options[i].szValue = apxRegistryGetStringW(hRegistry,
                                                            dwFrom,
                                                            _options[i].szSubkey,
                                                            _options[i].szRegistry);
                /* Expand environment variables */
                if (_options[i].szValue && (_options[i].dwType & APXCMDOPT_STE)) {
                    LPWSTR exp = apxExpandStrW(gPool, _options[i].szValue);
                    if (exp != _options[i].szValue)
                        apxFree(_options[i].szValue);
                    _options[i].szValue = exp;
                }
            }
            else if (_options[i].dwType & APXCMDOPT_INT) {
                _options[i].dwValue = apxRegistryGetNumberW(hRegistry,
                                                            dwFrom,
                                                            _options[i].szSubkey,
                                                            _options[i].szRegistry);
            }
            else if (_options[i].dwType & APXCMDOPT_MSZ) {
                _options[i].szValue = apxRegistryGetMzStrW(hRegistry,
                                                           dwFrom,
                                                           _options[i].szSubkey,
                                                           _options[i].szRegistry,
                                                           NULL,
                                                           &(_options[i].dwValue));
            }
        }
        /* Merge the command line options with registry */
        else if (_options[i].dwType & APXCMDOPT_ADD) {
            LPWSTR cv = _options[i].szValue;
            LPWSTR ov = NULL;
            if (_options[i].dwType & APXCMDOPT_MSZ) {
                ov = apxRegistryGetMzStrW(hRegistry, dwFrom,
                                          _options[i].szSubkey,
                                          _options[i].szRegistry,
                                          NULL,
                                          &(_options[i].dwValue));
                _options[i].szValue = apxMultiSzCombine(gPool, ov, cv,
                                                        &(_options[i].dwValue));
                if (ov)
                    apxFree(ov);
            }
        }
        ++i;
    }
    apxCloseHandle(hRegistry);
#ifdef _DEBUG
    dumpCmdline();
#endif
    return TRUE;
}

/* Save changed configuration to registry
 */
static BOOL saveConfiguration(LPAPXCMDLINE lpCmdline)
{
    APXHANDLE hRegistry;
    int i = 0;
    hRegistry = apxCreateRegistryW(gPool, KEY_WRITE | KREG_WOW6432,
                                   PRG_REGROOT,
                                   lpCmdline->szApplication,
                                   APXREG_SOFTWARE | APXREG_SERVICE);
    if (IS_INVALID_HANDLE(hRegistry))
        return FALSE;
    /* TODO: Use array size */
    while (_options[i].szName) {
        /* Skip the service params */
        if ((_options[i].dwType & APXCMDOPT_SRV) ||
            !(_options[i].dwType & APXCMDOPT_FOUND)) {
                /* Skip non-modified version */
        }
        /* Update only modified params */
        else if (_options[i].dwType & APXCMDOPT_STR)
            apxRegistrySetStrW(hRegistry, APXREG_PARAMSOFTWARE,
                               _options[i].szSubkey,
                               _options[i].szRegistry,
                               _options[i].szValue);
        else if (_options[i].dwType & APXCMDOPT_INT)
            apxRegistrySetNumW(hRegistry, APXREG_PARAMSOFTWARE,
                               _options[i].szSubkey,
                               _options[i].szRegistry,
                               _options[i].dwValue);
        else if (_options[i].dwType & APXCMDOPT_MSZ)
            apxRegistrySetMzStrW(hRegistry, APXREG_PARAMSOFTWARE,
                               _options[i].szSubkey,
                               _options[i].szRegistry,
                               _options[i].szValue,
                               _options[i].dwValue);
        ++i;
    }
    apxCloseHandle(hRegistry);
    return TRUE;
}

/* Display current configuration */
static BOOL printConfig(LPAPXCMDLINE lpCmdline)
{
    int i = 0;

    if (!loadConfiguration(lpCmdline)) {
		return FALSE;
	}

    fwprintf(stderr, L"%s.exe update ",lpCmdline->szExecutable);
    while (_options[i].szName) {
		if (_options[i].dwType & APXCMDOPT_INT) {
			fwprintf(stderr, L"--%s %d ", _options[i].szName, _options[i].dwValue);
		} else if (_options[i].dwType & APXCMDOPT_MSZ) {
			if (_options[i].szValue) {
				BOOL first = TRUE;
				LPCWSTR p = _options[i].szValue;
    	        fwprintf(stderr, L"--%s \"", _options[i].szName);

    	        while (*p) {
    	        	if (first) {
    	        		first = FALSE;
    	        	} else {
    	        		fwprintf(stderr, L"#");
    	        	}
    	        	// Skip to terminating NULL for this value
    	        	while (p[0]) {
    	        		if (p[0] == L'#') {
    	        			fwprintf(stderr, L"'%c'", p[0]);
    	        		} else {
    	        			fwprintf(stderr, L"%c", p[0]);
    	        		}
    	        		++p;
    	        	}
    	        	// Move to start of next value
    	        	++p;
    	        }
    	        fwprintf(stderr, L"\" ");
			}
        } else if (_options[i].szValue) {
            fwprintf(stderr, L"--%s \"%s\" ", _options[i].szName, _options[i].szValue);
        }
        // NULL options are ignored
        ++i;
    }
    return TRUE;
}

/* Operations */
static BOOL docmdInstallService(LPAPXCMDLINE lpCmdline)
{
    APXHANDLE hService;
    BOOL  rv;
    DWORD dwStart = SERVICE_DEMAND_START;
    DWORD dwType  = SERVICE_WIN32_OWN_PROCESS;
    WCHAR szImage[SIZ_HUGLEN];
    WCHAR szName[SIZ_BUFLEN];

    apxLogWrite(APXLOG_MARK_DEBUG "Installing service...");
    hService = apxCreateService(gPool, SC_MANAGER_CREATE_SERVICE, FALSE);
    if (IS_INVALID_HANDLE(hService)) {
        apxLogWrite(APXLOG_MARK_ERROR "Unable to open the Service Manager.");
        return FALSE;
    }
    /* Check the startup mode */
    if ((ST_STARTUP & APXCMDOPT_FOUND) &&
        lstrcmpiW(SO_STARTUP, PRSRV_AUTO) == 0)
        dwStart = SERVICE_AUTO_START;
    /* Check the service type */
    if ((ST_TYPE & APXCMDOPT_FOUND) &&
        lstrcmpiW(SO_TYPE, STYPE_INTERACTIVE) == 0) {

        // Need to run as LocalSystem to set the interactive flag
        LPCWSTR su = NULL;
        if (ST_SUSER & APXCMDOPT_FOUND) {
            su = SO_SUSER;
        }
        if (su && lstrcmpiW(su, L"LocalSystem") == 0) {
            dwType |= SERVICE_INTERACTIVE_PROCESS;
        } else {
            apxLogWrite(APXLOG_MARK_ERROR
                    "The parameter '--Type interactive' is only valid with '--ServiceUser LocalSystem'");
            return FALSE;
        }
    }

    /* Check if --Install is provided */
    if (!IS_VALID_STRING(SO_INSTALL)) {
        lstrlcpyW(szImage, SIZ_HUGLEN, lpCmdline->szExePath);
        lstrlcatW(szImage, SIZ_HUGLEN, L"\\");
        lstrlcatW(szImage, SIZ_HUGLEN, lpCmdline->szExecutable);
        lstrlcatW(szImage, SIZ_HUGLEN, L".exe");
    }
    else
        lstrlcpyW(szImage, SIZ_HUGLEN, SO_INSTALL);
    /* Replace not needed quotes */
    apxStrQuoteInplaceW(szImage);
    /* Add run-service command line option */
    lstrlcatW(szImage, SIZ_HUGLEN, L" ");
    lstrlcpyW(szName, SIZ_BUFLEN, L"//RS//");
    lstrlcatW(szName, SIZ_BUFLEN, lpCmdline->szApplication);
    apxStrQuoteInplaceW(szName);
    lstrlcatW(szImage, SIZ_HUGLEN, szName);
    SO_INSTALL = apxPoolStrdupW(gPool, szImage);
    /* Ensure that option gets saved in the registry */
    ST_INSTALL |= APXCMDOPT_FOUND;
#ifdef _DEBUG
    /* Display configured options */
    dumpCmdline();
#endif
    apxLogWrite(APXLOG_MARK_INFO "Installing service '%S' name '%S'.", lpCmdline->szApplication,
                SO_DISPLAYNAME);
    rv = apxServiceInstall(hService,
                          lpCmdline->szApplication,
                          SO_DISPLAYNAME,    /* --DisplayName  */
                          SO_INSTALL,
                          SO_DEPENDSON,      /* --DependendsOn */
                          dwType,
                          dwStart);
    /* Set the --Description */
    if (rv) {
        LPCWSTR sd = NULL;
        LPCWSTR su = NULL;
        LPCWSTR sp = NULL;
        if (ST_DESCRIPTION & APXCMDOPT_FOUND) {
            sd = SO_DESCRIPTION;
            apxLogWrite(APXLOG_MARK_DEBUG "Setting service description '%S'.",
                        SO_DESCRIPTION);
        }
        if (ST_SUSER & APXCMDOPT_FOUND) {
            su = SO_SUSER;
            apxLogWrite(APXLOG_MARK_DEBUG "Setting service user '%S'.",
                        SO_SUSER);
        }
        if (ST_SPASSWORD & APXCMDOPT_FOUND) {
            sp = SO_SPASSWORD;
            apxLogWrite(APXLOG_MARK_DEBUG "Setting service password '%S'.",
                        SO_SPASSWORD);
        }
        apxServiceSetNames(hService, NULL, NULL, sd, su, sp);
    }
    apxCloseHandle(hService);
    if (rv) {
        saveConfiguration(lpCmdline);
        apxLogWrite(APXLOG_MARK_INFO "Service '%S' installed.",
                    lpCmdline->szApplication);
    }
    else
        apxLogWrite(APXLOG_MARK_ERROR "Failed installing service '%S'.",
                    lpCmdline->szApplication);

    return rv;
}

static BOOL docmdDeleteService(LPAPXCMDLINE lpCmdline)
{
    APXHANDLE hService;
    BOOL  rv = FALSE;

    apxLogWrite(APXLOG_MARK_INFO "Deleting service...");
    hService = apxCreateService(gPool, SC_MANAGER_CONNECT, FALSE);
    if (IS_INVALID_HANDLE(hService)) {
        apxLogWrite(APXLOG_MARK_ERROR "Unable to open the Service Manager.");
        return FALSE;
    }
    /* Delete service will stop the service if running */
    if (apxServiceOpen(hService, lpCmdline->szApplication, SERVICE_ALL_ACCESS)) {
        WCHAR szWndManagerClass[SIZ_RESLEN];
        HANDLE hWndManager = NULL;
        lstrlcpyW(szWndManagerClass, SIZ_RESLEN, lpCmdline->szApplication);
        lstrlcatW(szWndManagerClass, SIZ_RESLEN, L"_CLASS");
        /* Close the monitor application if running */
        if ((hWndManager = FindWindowW(szWndManagerClass, NULL)) != NULL) {
            SendMessage(hWndManager, WM_CLOSE, 0, 0);
        }
        rv = apxServiceDelete(hService);
    }
    if (rv) {
        /* Delete all service registry settings */
        apxDeleteRegistryW(PRG_REGROOT, lpCmdline->szApplication, KREG_WOW6432, TRUE);
        apxLogWrite(APXLOG_MARK_DEBUG "Service '%S' deleted.",
                    lpCmdline->szApplication);
    }
    else {
        apxDisplayError(FALSE, NULL, 0, "Unable to delete service '%S'.",
                        lpCmdline->szApplication);
    }
    apxCloseHandle(hService);
    apxLogWrite(APXLOG_MARK_INFO "Delete service finished.");
    return rv;
}

static BOOL docmdStopService(LPAPXCMDLINE lpCmdline)
{
    APXHANDLE hService;
    BOOL  rv = FALSE;

    apxLogWrite(APXLOG_MARK_INFO "Stopping service '%S'...",
                lpCmdline->szApplication);
    hService = apxCreateService(gPool, GENERIC_ALL, FALSE);
    if (IS_INVALID_HANDLE(hService)) {
        apxLogWrite(APXLOG_MARK_ERROR "Unable to open the Service Manager.");
        return FALSE;
    }

    SetLastError(ERROR_SUCCESS);
    /* Open the service */
    if (apxServiceOpen(hService, lpCmdline->szApplication,
                       GENERIC_READ | GENERIC_EXECUTE)) {
        rv = apxServiceControl(hService,
                               SERVICE_CONTROL_STOP,
                               0,
                               NULL,
                               NULL);
        if (rv)
            apxLogWrite(APXLOG_MARK_INFO "Service '%S' stopped.",
                        lpCmdline->szApplication);
        else
            apxLogWrite(APXLOG_MARK_ERROR "Failed to stop service '%S'.",
                        lpCmdline->szApplication);

    }
    else
        apxDisplayError(FALSE, NULL, 0, "Unable to open service '%S'.",
                        lpCmdline->szApplication);
    apxCloseHandle(hService);
    apxLogWrite(APXLOG_MARK_INFO "Stop service finished.");
    return rv;
}

static BOOL docmdStartService(LPAPXCMDLINE lpCmdline)
{
    APXHANDLE hService;
    BOOL  rv = FALSE;

    apxLogWrite(APXLOG_MARK_INFO "Starting service '%S'...",
                lpCmdline->szApplication);
    hService = apxCreateService(gPool, GENERIC_ALL, FALSE);
    if (IS_INVALID_HANDLE(hService)) {
        apxLogWrite(APXLOG_MARK_ERROR "Unable to open the Service Manager.");
        return FALSE;
    }

    SetLastError(ERROR_SUCCESS);
    /* Open the service */
    if (apxServiceOpen(hService, lpCmdline->szApplication,
                       GENERIC_READ | GENERIC_EXECUTE)) {
        rv = apxServiceControl(hService,
                               SERVICE_CONTROL_CONTINUE,
                               0,
                               NULL,
                               NULL);
        if (rv)
            apxLogWrite(APXLOG_MARK_INFO "Started service '%S'.",
                        lpCmdline->szApplication);
        else
            apxLogWrite(APXLOG_MARK_ERROR "Failed to start service '%S'.",
                        lpCmdline->szApplication);

    }
    else
        apxDisplayError(FALSE, NULL, 0, "Unable to open service '%S'.",
                        lpCmdline->szApplication);
    apxCloseHandle(hService);
    apxLogWrite(APXLOG_MARK_INFO "Finished starting service '%S', returning %d.", lpCmdline->szApplication, rv);
    return rv;
}

static BOOL docmdUpdateService(LPAPXCMDLINE lpCmdline)
{
    APXHANDLE hService;
    BOOL  rv = TRUE;

    apxLogWrite(APXLOG_MARK_INFO "Updating service...");

    hService = apxCreateService(gPool, SC_MANAGER_CREATE_SERVICE, FALSE);
    if (IS_INVALID_HANDLE(hService)) {
        apxLogWrite(APXLOG_MARK_ERROR "Unable to open the Service Manager.");
        return FALSE;
    }
    SetLastError(0);
    /* Open the service */
    if (!apxServiceOpen(hService, lpCmdline->szApplication, SERVICE_ALL_ACCESS)) {
        /* Close the existing manager handler.
         * It will be reopened inside install.
         */
        apxCloseHandle(hService);
        /* In case service doesn't exist try to install it.
         * Install will fail if there is no minimum parameters required.
         */
        return docmdInstallService(lpCmdline);
    }
    else {
        DWORD dwStart = SERVICE_NO_CHANGE;
        BOOL  bDelayedStart = FALSE;
        DWORD dwType  = SERVICE_NO_CHANGE;
        LPCWSTR su = NULL;
        LPCWSTR sp = NULL;
        if (ST_SUSER & APXCMDOPT_FOUND) {
            su = SO_SUSER;
            apxLogWrite(APXLOG_MARK_DEBUG "Setting service user '%S'.",
                        SO_SUSER);
        }
        if (ST_SPASSWORD & APXCMDOPT_FOUND) {
            sp = SO_SPASSWORD;
            apxLogWrite(APXLOG_MARK_DEBUG "Setting service password '%S'.",
                        SO_SPASSWORD);
        }
        rv = (rv && apxServiceSetNames(hService,
                                       NULL,                /* Never update the ImagePath */
                                       SO_DISPLAYNAME,
                                       SO_DESCRIPTION,
                                       su,
                                       sp));
        /* Update the --Startup mode */
        if (ST_STARTUP & APXCMDOPT_FOUND) {
            if (!lstrcmpiW(SO_STARTUP, PRSRV_DELAYED)) {
                dwStart = SERVICE_AUTO_START;
                bDelayedStart = TRUE;
            }
            else if (!lstrcmpiW(SO_STARTUP, PRSRV_AUTO))
                dwStart = SERVICE_AUTO_START;
            else if (!lstrcmpiW(SO_STARTUP, PRSRV_MANUAL))
                dwStart = SERVICE_DEMAND_START;
        }
        if (ST_TYPE & APXCMDOPT_FOUND) {
            if (!lstrcmpiW(SO_TYPE, STYPE_INTERACTIVE))
                dwType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
        }
        rv = (rv && apxServiceSetOptions(hService,
                                         dwType,
                                         dwStart,
                                         bDelayedStart,
                                         SERVICE_NO_CHANGE));

        apxLogWrite(APXLOG_MARK_INFO "Updated service '%S'.",
                    lpCmdline->szApplication);

        rv = (rv && saveConfiguration(lpCmdline));
    }
    apxCloseHandle(hService);
    if (rv)
        apxLogWrite(APXLOG_MARK_INFO "Finished updating service '%S'.", lpCmdline->szApplication);
    else
        apxLogWrite(APXLOG_MARK_INFO "Failed updating service '%S'.",
                                     lpCmdline->szApplication);
    return rv;
}


/* Report the service status to the SCM, including service specific exit code
 */
static BOOL reportServiceStatusE(DWORD dwCurrentState,
                                 DWORD dwWin32ExitCode,
                                 DWORD dwWaitHint,
                                 DWORD dwServiceSpecificExitCode)
{
   static DWORD dwCheckPoint = 1;
   BOOL fResult = TRUE;

   apxLogWrite(APXLOG_MARK_DEBUG "reportServiceStatusE: dwCurrentState = %d, dwWin32ExitCode = %d, dwWaitHint = %d, dwServiceSpecificExitCode = %d.",
               dwCurrentState, dwWin32ExitCode, dwWaitHint, dwServiceSpecificExitCode);

   if (_service_mode && _service_status_handle) {
       if (dwCurrentState == SERVICE_RUNNING)
            _service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
        else
            _service_status.dwControlsAccepted = 0;

       _service_status.dwCurrentState  = dwCurrentState;
       _service_status.dwWin32ExitCode = dwWin32ExitCode;
       _service_status.dwWaitHint      = dwWaitHint;
       _service_status.dwServiceSpecificExitCode = dwServiceSpecificExitCode;

       if ((dwCurrentState == SERVICE_RUNNING) ||
           (dwCurrentState == SERVICE_STOPPED))
           _service_status.dwCheckPoint = 0;
       else
           _service_status.dwCheckPoint = dwCheckPoint++;
       fResult = SetServiceStatus(_service_status_handle, &_service_status);
       if (!fResult) {
           /* TODO: Deal with error */
           apxLogWrite(APXLOG_MARK_ERROR "Failed to set service status.");
       }
   }
   return fResult;
}

/* Report the service status to the SCM
 */
static BOOL reportServiceStatus(DWORD dwCurrentState,
                                DWORD dwWin32ExitCode,
                                DWORD dwWaitHint)
{
    return reportServiceStatusE(dwCurrentState, dwWin32ExitCode, dwWaitHint, 0);
}

static BOOL reportServiceStatusStopped(DWORD exitCode)
{
    if (exitCode) {
        return reportServiceStatusE(SERVICE_STOPPED, ERROR_SERVICE_SPECIFIC_ERROR, 0, exitCode);
    } else {
        return reportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
    }
}

BOOL child_callback(APXHANDLE hObject, UINT uMsg,
                    WPARAM wParam, LPARAM lParam)
{
    /* TODO: Make stdout and stderr buffers
     * to prevent streams intermixing when there
     * is no separate file for each stream
     */
    if (uMsg == WM_CHAR) {
        int ch = LOWORD(wParam);
        if (lParam)
            fputc(ch, stderr);
        else
            fputc(ch, stdout);
    }
    return TRUE;
    UNREFERENCED_PARAMETER(hObject);
}

static int onExitStop(void)
{
    if (_service_mode) {
        apxLogWrite(APXLOG_MARK_DEBUG "Stop exit hook called...");
        reportServiceStatusStopped(0);
    }
    return 0;
}

static int onExitStart(void)
{
    if (_service_mode) {
        apxLogWrite(APXLOG_MARK_DEBUG "Start exit hook called...");
        apxLogWrite(APXLOG_MARK_DEBUG "JVM exit code: %d.", apxGetVmExitCode());
        /* Reporting the service as stopped even with a non-zero exit code
         * will not cause recovery actions to be initiated, so don't report at all.
         * "A service is considered failed when it terminates without reporting a
         * status of SERVICE_STOPPED to the service controller"
         * http://msdn.microsoft.com/en-us/library/ms685939(VS.85).aspx
         */
        if (apxGetVmExitCode() == 0) {
            reportServiceStatusStopped(0);
        }
    }
    return 0;
}

/* Executed when the service receives stop event */
static DWORD WINAPI serviceStop(LPVOID lpParameter)
{
    APXHANDLE hWorker = NULL;
    DWORD  rv = 0;
    BOOL   wait_to_die = FALSE;
    DWORD  timeout     = SO_STOPTIMEOUT * 1000;
    DWORD  dwCtrlType  = (DWORD)((BYTE *)lpParameter - (BYTE *)0);

    apxLogWrite(APXLOG_MARK_INFO "Stopping service...");

    if (IS_INVALID_HANDLE(gWorker)) {
        apxLogWrite(APXLOG_MARK_INFO "Worker is not defined.");
        return TRUE;    /* Nothing to do */
    }
    if (_jni_shutdown) {
        if (!IS_VALID_STRING(SO_STARTPATH) && IS_VALID_STRING(SO_STOPPATH)) {
            /* If the Working path is specified change the current directory
             * but only if the start path wasn't specified already.
             */
            SetCurrentDirectoryW(SO_STOPPATH);
        }
        hWorker = apxCreateJava(gPool, _jni_jvmpath, SO_JAVAHOME);
        if (IS_INVALID_HANDLE(hWorker)) {
            apxLogWrite(APXLOG_MARK_ERROR "Failed creating Java '%S'.", _jni_jvmpath);
            return 1;
        }
        gSargs.hJava            = hWorker;
        gSargs.szClassPath      = _jni_classpath;
        gSargs.lpOptions        = _jni_jvmoptions;
        gSargs.lpOptions9       = _jni_jvmoptions9;
        gSargs.dwMs             = SO_JVMMS;
        gSargs.dwMx             = SO_JVMMX;
        gSargs.dwSs             = SO_JVMSS;
        gSargs.bJniVfprintf     = SO_JNIVFPRINTF;
        gSargs.szClassName      = _jni_sclass;
        gSargs.szMethodName     = _jni_smethod;
        gSargs.lpArguments      = _jni_sparam;
        gSargs.szStdErrFilename = NULL;
        gSargs.szStdOutFilename = NULL;
        gSargs.szLibraryPath    = SO_LIBPATH;
        /* Register onexit hook
         */
        _onexit(onExitStop);
        /* Create shutdown event */
        gShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!apxJavaStart(&gSargs)) {
            apxLogWrite(APXLOG_MARK_ERROR "Failed starting Java.");
            rv = 3;
        }
        else {
            if (lstrcmpA(_jni_sclass, "java/lang/System") == 0) {
                reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 20 * 1000);
                apxLogWrite(APXLOG_MARK_DEBUG "Forcing Java JNI System.exit() worker to finish...");
                return 0;
            }
            else {
                apxLogWrite(APXLOG_MARK_DEBUG "Waiting for Java JNI stop worker to finish for %s:%s...", _jni_sclass, _jni_smethod);
                apxJavaWait(hWorker, INFINITE, FALSE);
                apxLogWrite(APXLOG_MARK_DEBUG "Java JNI stop worker finished.");
            }
        }
        wait_to_die = TRUE;
    }
    else if (IS_VALID_STRING(SO_STOPMODE)) { /* Only in case we have a stop mode */
        DWORD nArgs;
        LPWSTR *pArgs;

        if (!IS_VALID_STRING(SO_STOPIMAGE)) {
            apxLogWrite(APXLOG_MARK_ERROR "Missing service ImageFile.");
            if (!_service_mode)
                apxDisplayError(FALSE, NULL, 0, "Service '%S' is missing the ImageFile.",
                                _service_name ? _service_name : L"unknown");
            return 1;
        }
        /* Redirect process */
        hWorker = apxCreateProcessW(gPool,
                                    0,
                                    child_callback,
                                    SO_USER,
                                    SO_PASSWORD,
                                    FALSE);
        if (IS_INVALID_HANDLE(hWorker)) {
            apxLogWrite(APXLOG_MARK_ERROR "Failed creating process.");
            return 1;
        }
        /* If the service process completes before the stop process does the
         * cleanup code below will free structures required by the stop process
         * which will, in all probability, trigger a crash. Wait for the stop
         * process to complete before cleaning up.
         */
        gShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!apxProcessSetExecutableW(hWorker, SO_STOPIMAGE)) {
            apxLogWrite(APXLOG_MARK_ERROR "Failed setting process executable '%S'.",
                        SO_STOPIMAGE);
            rv = 2;
            goto cleanup;
        }
        /* Assemble the command line */
        if (_java_shutdown) {
            nArgs = apxJavaCmdInitialize(gPool, SO_CLASSPATH, SO_STOPCLASS,
                                         SO_JVMOPTIONS, SO_JVMMS, SO_JVMMX,
                                         SO_JVMSS, SO_STOPPARAMS, &pArgs);
        }
        else {
            nArgs = apxMultiSzToArrayW(gPool, SO_STOPPARAMS, &pArgs);
        }

        /* Pass the argv to child process */
        if (!apxProcessSetCommandArgsW(hWorker, SO_STOPIMAGE,
                                       nArgs, pArgs)) {
            rv = 3;
            apxLogWrite(APXLOG_MARK_ERROR "Failed setting process arguments (argc=%d).",
                        nArgs);
            goto cleanup;
        }
        /* Set the working path */
        if (!apxProcessSetWorkingPathW(hWorker, SO_STOPPATH)) {
            rv = 4;
            apxLogWrite(APXLOG_MARK_ERROR "Failed setting process working path to '%S'.",
                        SO_STOPPATH);
            goto cleanup;
        }
        /* Finally execute the child process
         */
        if (!apxProcessExecute(hWorker)) {
            rv = 5;
            apxLogWrite(APXLOG_MARK_ERROR "Failed executing process.");
            goto cleanup;
        } else {
            apxLogWrite(APXLOG_MARK_DEBUG "Waiting for stop worker to finish...");
            apxHandleWait(hWorker, INFINITE, FALSE);
            apxLogWrite(APXLOG_MARK_DEBUG "Stop worker finished.");
        }
        wait_to_die = TRUE;
    }
cleanup:
    /* Close Java JNI handle or stop worker
     * If this is the single JVM instance it will unload
     * the JVM dll too.
     * The worker will be closed on service exit.
     */
    if (!IS_INVALID_HANDLE(hWorker))
        apxCloseHandle(hWorker);
    if (gSignalEvent) {
        gSignalValid = FALSE;
        SetEvent(gSignalEvent);
        WaitForSingleObject(gSignalThread, 1000);
        CloseHandle(gSignalEvent);
        CloseHandle(gSignalThread);
        gSignalEvent = NULL;
    }
    if (timeout > 0x7FFFFFFF)
        timeout = INFINITE;     /* If the timeout was '-1' wait forewer */
    if (wait_to_die && !timeout)
        timeout = 300 * 1000;   /* Use the 5 minute default shutdown */

    if (dwCtrlType == SERVICE_CONTROL_SHUTDOWN)
        timeout = MIN(timeout, apxGetMaxServiceTimeout(gPool));
    reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, timeout);

    if (timeout) {
        FILETIME fts, fte;
        ULARGE_INTEGER s, e;
        DWORD    nms;
        /* Wait to give it a chance to die naturally, then kill it. */
        apxLogWrite(APXLOG_MARK_DEBUG "Waiting for worker to die naturally...");
        GetSystemTimeAsFileTime(&fts);
        rv = apxHandleWait(gWorker, timeout, TRUE);
        GetSystemTimeAsFileTime(&fte);
        s.LowPart  = fts.dwLowDateTime;
        s.HighPart = fts.dwHighDateTime;
        e.LowPart  = fte.dwLowDateTime;
        e.HighPart = fte.dwHighDateTime;
        nms = (DWORD)((e.QuadPart - s.QuadPart) / 10000);
        if (rv == WAIT_OBJECT_0) {
            rv = 0;
            apxLogWrite(APXLOG_MARK_DEBUG "Worker finished gracefully in %d milliseconds.", nms);
        }
        else
            apxLogWrite(APXLOG_MARK_DEBUG "Worker was killed in %d milliseconds.", nms);
    }
    else {
        apxLogWrite(APXLOG_MARK_DEBUG "Sending WM_CLOSE to worker.");
        apxHandleSendMessage(gWorker, WM_CLOSE, 0, 0);
    }

    apxLogWrite(APXLOG_MARK_INFO "Service stop thread completed.");
    if (gShutdownEvent) {
        SetEvent(gShutdownEvent);
    }
    return rv;
}

/* Executed when the service receives start event */
static DWORD serviceStart()
{
    DWORD  rv = 0;
    DWORD  nArgs;
    LPWSTR *pArgs;
    FILETIME fts;

    apxLogWrite(APXLOG_MARK_INFO "Starting service...");

    if (!IS_INVALID_HANDLE(gWorker)) {
        apxLogWrite(APXLOG_MARK_INFO "Worker is not defined.");
        return TRUE;    /* Nothing to do */
    }
    if (IS_VALID_STRING(SO_PIDFILE)) {
        gPidfileName = apxLogFile(gPool, SO_LOGPATH, SO_PIDFILE, NULL, FALSE, 0);
        if (GetFileAttributesW(gPidfileName) !=  INVALID_FILE_ATTRIBUTES) {
            /* Pid file exists */
            if (!DeleteFileW(gPidfileName)) {
                /* Delete failed. Either no access or opened */
                apxLogWrite(APXLOG_MARK_ERROR "Pid file '%S' exists.",
                            gPidfileName);
                return 1;
            }
        }
    }
    GetSystemTimeAsFileTime(&fts);
    if (_jni_startup) {
        if (IS_EMPTY_STRING(SO_STARTPATH))
            SO_STARTPATH = gStartPath;
        if (IS_VALID_STRING(SO_STARTPATH)) {
            /* If the Working path is specified change the current directory */
            SetCurrentDirectoryW(SO_STARTPATH);
        }
        if (IS_VALID_STRING(SO_LIBPATH)) {
            /* Add LibraryPath to the PATH */
           apxAddToPathW(gPool, SO_LIBPATH);
        }
        /* Some options require additional environment settings to be in place
         * before Java is started
         */
        setInprocEnvironmentOptions(SO_JVMOPTIONS);
        /* Create the JVM global worker */
        gWorker = apxCreateJava(gPool, _jni_jvmpath, SO_JAVAHOME);
        if (IS_INVALID_HANDLE(gWorker)) {
            apxLogWrite(APXLOG_MARK_ERROR "Failed creating Java '%S'.", _jni_jvmpath);
            return 1;
        }
        gRargs.hJava            = gWorker;
        gRargs.szClassPath      = _jni_classpath;
        gRargs.lpOptions        = _jni_jvmoptions;
        gRargs.lpOptions9       = _jni_jvmoptions9;
        gRargs.dwMs             = SO_JVMMS;
        gRargs.dwMx             = SO_JVMMX;
        gRargs.dwSs             = SO_JVMSS;
        gRargs.bJniVfprintf     = SO_JNIVFPRINTF;
        gRargs.szClassName      = _jni_rclass;
        gRargs.szMethodName     = _jni_rmethod;
        gRargs.lpArguments      = _jni_rparam;
        gRargs.szStdErrFilename = gStdwrap.szStdErrFilename;
        gRargs.szStdOutFilename = gStdwrap.szStdOutFilename;
        gRargs.szLibraryPath    = SO_LIBPATH;
        /* Register onexit hook
         */
        _onexit(onExitStart);
        if (!apxJavaStart(&gRargs)) {
            rv = 4;
            apxLogWrite(APXLOG_MARK_ERROR "Failed to start Java");
            goto cleanup;
        }
        apxLogWrite(APXLOG_MARK_DEBUG "Java started '%s'.", _jni_rclass);
    }
    else {
        if (!IS_VALID_STRING(SO_STARTIMAGE)) {
            apxLogWrite(APXLOG_MARK_ERROR "Missing service ImageFile.");
            if (!_service_mode)
                apxDisplayError(FALSE, NULL, 0, "Service '%S' is missing the ImageFile.",
                                _service_name ? _service_name : L"unknown");
            return 1;
        }
        if (IS_VALID_STRING(SO_LIBPATH)) {
            /* Add LibraryPath to the PATH */
           apxAddToPathW(gPool, SO_LIBPATH);
        }
        /* Set the environment using putenv, so JVM can use it */
        apxSetInprocEnvironment();
        /* Java 9 specific options need to be set via an environment variable */
        setInprocEnvironment9(SO_JVMOPTIONS9);
        /* Redirect process */
        gWorker = apxCreateProcessW(gPool,
                                    0,
                                    child_callback,
                                    SO_USER,
                                    SO_PASSWORD,
                                    FALSE);
        if (IS_INVALID_HANDLE(gWorker)) {
            apxLogWrite(APXLOG_MARK_ERROR "Failed to create process.");
            return 1;
        }
        if (!apxProcessSetExecutableW(gWorker, SO_STARTIMAGE)) {
            apxLogWrite(APXLOG_MARK_ERROR "Failed setting process executable '%S'.",
                        SO_STARTIMAGE);
            rv = 2;
            goto cleanup;
        }
        /* Assemble the command line */
        if (_java_startup) {
            nArgs = apxJavaCmdInitialize(gPool, SO_CLASSPATH, SO_STARTCLASS,
                                         SO_JVMOPTIONS, SO_JVMMS, SO_JVMMX,
                                         SO_JVMSS, SO_STARTPARAMS, &pArgs);
        }
        else {
            nArgs = apxMultiSzToArrayW(gPool, SO_STARTPARAMS, &pArgs);
        }

        /* Pass the argv to child process */
        if (!apxProcessSetCommandArgsW(gWorker, SO_STARTIMAGE,
                                       nArgs, pArgs)) {
            rv = 3;
            apxLogWrite(APXLOG_MARK_ERROR "Failed setting process arguments (argc=%d).",
                        nArgs);
            goto cleanup;
        }
        /* Set the working path */
        if (!apxProcessSetWorkingPathW(gWorker, SO_STARTPATH)) {
            rv = 4;
            apxLogWrite(APXLOG_MARK_ERROR "Failed setting process working path to '%S'.",
                        SO_STARTPATH);
            goto cleanup;
        }
        /* Finally execute the child process
         */
        if (!apxProcessExecute(gWorker)) {
            rv = 5;
            apxLogWrite(APXLOG_MARK_ERROR "Failed to execute process.");
            goto cleanup;
        }
    }
    if (rv == 0) {
        FILETIME fte;
        ULARGE_INTEGER s, e;
        DWORD    nms;
        /* Create pidfile */
        if (gPidfileName) {
            char pids[32];
            gPidfileHandle = CreateFileW(gPidfileName,
                                         GENERIC_READ | GENERIC_WRITE,
                                         FILE_SHARE_READ,
                                         NULL,
                                         CREATE_NEW,
                                         FILE_ATTRIBUTE_NORMAL,
                                         NULL);

            if (gPidfileHandle != INVALID_HANDLE_VALUE) {
                DWORD wr = 0;
                if (_jni_startup)
                    _snprintf_s(pids, _countof(pids), 32, "%d\r\n", GetCurrentProcessId());
                else
                    _snprintf_s(pids, _countof(pids), 32, "%d\r\n", apxProcessGetPid(gWorker));
                WriteFile(gPidfileHandle, pids, (DWORD)strlen(pids), &wr, NULL);
                FlushFileBuffers(gPidfileName);
            }
        }
        GetSystemTimeAsFileTime(&fte);
        s.LowPart  = fts.dwLowDateTime;
        s.HighPart = fts.dwHighDateTime;
        e.LowPart  = fte.dwLowDateTime;
        e.HighPart = fte.dwHighDateTime;
        nms = (DWORD)((e.QuadPart - s.QuadPart) / 10000);
        apxLogWrite(APXLOG_MARK_INFO "Service started in %d milliseconds.", nms);
    }
    return rv;
cleanup:
    if (!IS_INVALID_HANDLE(gWorker))
        apxCloseHandle(gWorker);    /* Close the worker handle */
    gWorker = NULL;
    return rv;
}

/* Service control handler
 */
void WINAPI service_ctrl_handler(DWORD dwCtrlCode)
{
    DWORD  threadId;
    HANDLE stopThread;

    switch (dwCtrlCode) {
        case SERVICE_CONTROL_SHUTDOWN:
            apxLogWrite(APXLOG_MARK_INFO "Service SHUTDOWN signalled.");
        case SERVICE_CONTROL_STOP:
            if (SO_STOPTIMEOUT > 0) {
                reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, SO_STOPTIMEOUT * 1000);
            }
            else {
                reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 3 * 1000);
            }
            /* Stop the service asynchronously */
            stopThread = CreateThread(NULL, 0,
                                      serviceStop,
                                      (LPVOID)SERVICE_CONTROL_STOP,
                                      0, &threadId);
            CloseHandle(stopThread);
            return;
        case SERVICE_CONTROL_INTERROGATE:
            reportServiceStatus(_service_status.dwCurrentState,
                                _service_status.dwWin32ExitCode,
                                _service_status.dwWaitHint);
            return;
        default:
            break;
   }
}

/* Console control handler
 *
 */
BOOL WINAPI console_handler(DWORD dwCtrlType)
{
    switch (dwCtrlType) {
        case CTRL_BREAK_EVENT:
            apxLogWrite(APXLOG_MARK_INFO "Console CTRL+BREAK event signaled.");
            return FALSE;
        case CTRL_C_EVENT:
            apxLogWrite(APXLOG_MARK_INFO "Console CTRL+C event signaled.");
            serviceStop((LPVOID)SERVICE_CONTROL_STOP);
            return TRUE;
        case CTRL_CLOSE_EVENT:
            apxLogWrite(APXLOG_MARK_INFO "Console CTRL+CLOSE event signaled.");
            serviceStop((LPVOID)SERVICE_CONTROL_STOP);
            return TRUE;
        case CTRL_SHUTDOWN_EVENT:
            apxLogWrite(APXLOG_MARK_INFO "Console SHUTDOWN event signaled.");
            serviceStop((LPVOID)SERVICE_CONTROL_SHUTDOWN);
            return TRUE;
        case CTRL_LOGOFF_EVENT:
            apxLogWrite(APXLOG_MARK_INFO "Console LOGOFF event signaled.");
            if (!_service_mode) {
                serviceStop((LPVOID)SERVICE_CONTROL_STOP);
            }
            return TRUE;
        break;

   }
   return FALSE;
}

/* Main service execution loop */
void WINAPI serviceMain(DWORD argc, LPTSTR *argv)
{
    DWORD rc = 0;
    _service_status.dwServiceType      = SERVICE_WIN32_OWN_PROCESS;
    _service_status.dwCurrentState     = SERVICE_START_PENDING;
    _service_status.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE;
    _service_status.dwWin32ExitCode    = 0;
    _service_status.dwCheckPoint       = 0;
    _service_status.dwWaitHint         = 0;
    _service_status.dwServiceSpecificExitCode = 0;

    apxLogWrite(APXLOG_MARK_DEBUG "Inside ServiceMain...");

    if (IS_VALID_STRING(_service_name)) {
        WCHAR en[SIZ_HUGLEN];
        int i;
        PSECURITY_ATTRIBUTES sa = GetNullACL();
        lstrlcpyW(en, SIZ_DESLEN, L"Global\\");
        lstrlcatW(en, SIZ_DESLEN, _service_name);
        lstrlcatW(en, SIZ_DESLEN, PRSRV_SIGNAL);
        for (i = 7; i < lstrlenW(en); i++) {
            if (en[i] == L' ')
                en[i] = L'_';
            else
                en[i] = towupper(en[i]);
        }
        gSignalEvent = CreateEventW(sa, TRUE, FALSE, en);
        CleanNullACL((void *)sa);

        if (gSignalEvent) {
            DWORD tid;
            gSignalThread = CreateThread(NULL, 0, eventThread, NULL, 0, &tid);
        }
    }
    /* Check the StartMode */
    if (IS_VALID_STRING(SO_STARTMODE)) {
        if (!lstrcmpiW(SO_STARTMODE, PRSRV_JVM)) {
            _jni_startup = TRUE;
            if (IS_VALID_STRING(SO_STARTCLASS)) {
                _jni_rclass  = WideToANSI(SO_STARTCLASS);
                /* Exchange all dots with slashes */
                apxStrCharReplaceA(_jni_rclass, '.', '/');
            }
            else {
                /* Presume its main */
                _jni_rclass = WideToANSI(L"Main");
            }
            _jni_rparam = SO_STARTPARAMS;
        }
        else if (!lstrcmpiW(SO_STARTMODE, PRSRV_JAVA)) {
            LPWSTR jx = NULL, szJH = SO_JAVAHOME;
            if (!szJH)
                szJH = apxGetJavaSoftHome(gPool, FALSE);
            else if (!lstrcmpiW(szJH, PRSRV_JDK)) {
                /* Figure out the JDK JavaHome */
                szJH = apxGetJavaSoftHome(gPool, FALSE);
            }
            else if (!lstrcmpiW(szJH, PRSRV_JRE)) {
                /* Figure out the JRE JavaHome */
                szJH = apxGetJavaSoftHome(gPool, TRUE);
            }
            if (szJH) {
                jx = apxPoolAlloc(gPool, (lstrlenW(szJH) + 16) * sizeof(WCHAR));
                lstrcpyW(jx, szJH);
                lstrcatW(jx, PRSRV_JBIN);
                if (!SO_STARTPATH) {
                    /* Use JAVA_HOME/bin as start path */
                    LPWSTR szJP = apxPoolAlloc(gPool, (lstrlenW(szJH) + 8) * sizeof(WCHAR));
                    lstrcpyW(szJP, szJH);
                    lstrcatW(szJP, PRSRV_PBIN);
                    SO_STARTPATH = szJP;
                }
            }
            else {
                apxLogWrite(APXLOG_MARK_ERROR "Unable to find Java Runtime Environment.");
                goto cleanup;
            }
            _java_startup = TRUE;
            /* StartImage now contains the full path to the java.exe */
            SO_STARTIMAGE = jx;
        }
    }
    /* Check the StopMode */
    if (IS_VALID_STRING(SO_STOPMODE)) {
        if (!lstrcmpiW(SO_STOPMODE, PRSRV_JVM)) {
            _jni_shutdown = TRUE;
            if (IS_VALID_STRING(SO_STOPCLASS)) {
                _jni_sclass = WideToANSI(SO_STOPCLASS);
                apxStrCharReplaceA(_jni_sclass, '.', '/');
            }
            else {
                /* Defaults to Main */
                _jni_sclass = WideToANSI(L"Main");
            }
            _jni_sparam = SO_STOPPARAMS;
        }
        else if (!lstrcmpiW(SO_STOPMODE, PRSRV_JAVA)) {
            LPWSTR jx = NULL, szJH = SO_JAVAHOME;
            if (!szJH)
                szJH = apxGetJavaSoftHome(gPool, FALSE);
            else if (!lstrcmpiW(szJH, PRSRV_JDK)) {
                /* Figure out the JDK JavaHome */
                szJH = apxGetJavaSoftHome(gPool, FALSE);
            }
            else if (!lstrcmpiW(szJH, PRSRV_JRE)) {
                /* Figure out the JRE JavaHome */
                szJH = apxGetJavaSoftHome(gPool, TRUE);
            }
            if (szJH) {
                jx = apxPoolAlloc(gPool, (lstrlenW(szJH) + 16) * sizeof(WCHAR));
                lstrcpyW(jx, szJH);
                lstrcatW(jx, PRSRV_JBIN);
                if (!SO_STOPPATH) {
                    LPWSTR szJP = apxPoolAlloc(gPool, (lstrlenW(szJH) + 8) * sizeof(WCHAR));
                    lstrcpyW(szJP, szJH);
                    lstrcatW(szJP, PRSRV_PBIN);
                    /* Use JAVA_HOME/bin as stop path */
                    SO_STOPPATH = szJP;
                }
            }
            else {
                apxLogWrite(APXLOG_MARK_ERROR "Unable to find Java Runtime Environment.");
                goto cleanup;
            }
            _java_shutdown = TRUE;
            /* StopImage now contains the full path to the java.exe */
            SO_STOPIMAGE = jx;
        }
    }
    /* Find the classpath */
    if (_jni_shutdown || _jni_startup) {
        if (IS_VALID_STRING(SO_JVM)) {
            if (lstrcmpW(SO_JVM, PRSRV_AUTO))
                _jni_jvmpath = SO_JVM;
        }
        if (IS_VALID_STRING(SO_CLASSPATH))
            _jni_classpath = WideToANSI(SO_CLASSPATH);
        if (IS_VALID_STRING(SO_STARTMETHOD))
            _jni_rmethod   = WideToANSI(SO_STARTMETHOD);
        if (IS_VALID_STRING(SO_STOPMETHOD))
            _jni_smethod   = WideToANSI(SO_STOPMETHOD);
        _jni_jvmoptions    = MzWideToANSI(SO_JVMOPTIONS);
        _jni_jvmoptions9   = MzWideToANSI(SO_JVMOPTIONS9);
    }
    if (_service_mode) {
        /* Register Service Control handler */
        _service_status_handle = RegisterServiceCtrlHandlerW(_service_name,
                                                              service_ctrl_handler);
        if (IS_INVALID_HANDLE(_service_status_handle)) {
            apxLogWrite(APXLOG_MARK_ERROR "Failed to register Service Control for '%S'.",
                        _service_name);
            goto cleanup;
        }
        /* Allocate console so that events gets processed */
        if (!AttachConsole(ATTACH_PARENT_PROCESS) &&
             GetLastError() == ERROR_INVALID_HANDLE) {
            HWND hc;
            AllocConsole();
            if ((hc = GetConsoleWindow()) != NULL)
                ShowWindow(hc, SW_HIDE);
        }
    }
    reportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
    if ((rc = serviceStart()) == 0) {
        /* Service is started */
        reportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0);
        apxLogWrite(APXLOG_MARK_DEBUG "Waiting for worker to finish...");
        /* Set console handler to capture CTRL events */
        SetConsoleCtrlHandler((PHANDLER_ROUTINE)console_handler, TRUE);

        apxHandleWait(gWorker, INFINITE, FALSE);
        apxLogWrite(APXLOG_MARK_DEBUG "Worker finished.");
    }
    else {
        apxLogWrite(APXLOG_MARK_ERROR "ServiceStart returned %d.", rc);
        goto cleanup;
    }
    if (gShutdownEvent) {

        /* Ensure that shutdown thread exits before us */
        apxLogWrite(APXLOG_MARK_DEBUG "Waiting for ShutdownEvent.");
        reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, ONE_MINUTE);
        WaitForSingleObject(gShutdownEvent, ONE_MINUTE);
        apxLogWrite(APXLOG_MARK_DEBUG "ShutdownEvent signaled.");
        CloseHandle(gShutdownEvent);
        gShutdownEvent = NULL;

        /* This will cause to wait for all threads to exit
         */
        apxLogWrite(APXLOG_MARK_DEBUG "Waiting 1 minute for all threads to exit.");
        reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, ONE_MINUTE);
        apxDestroyJvm(ONE_MINUTE);
    }
    else {
        /* We came here without shutdown event
         * Probably because main() returned without ensuring all threads
         * have finished
         */
        apxLogWrite(APXLOG_MARK_DEBUG "Waiting for all threads to exit.");
        apxDestroyJvm(INFINITE);
        reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
    }
    apxLogWrite(APXLOG_MARK_DEBUG "JVM destroyed.");
    reportServiceStatusStopped(apxGetVmExitCode());

    return;
cleanup:
    /* Cleanup */
    reportServiceStatusStopped(rc);
    gExitval = rc;
    return;
    UNREFERENCED_PARAMETER(argc);
    UNREFERENCED_PARAMETER(argv);
}


/* Run the service in the debug mode */
BOOL docmdDebugService(LPAPXCMDLINE lpCmdline)
{
    _service_mode = FALSE;
    _service_name = lpCmdline->szApplication;
    apxLogWrite(APXLOG_MARK_INFO "Debugging '%S' service...", _service_name);
    serviceMain(0, NULL);
    apxLogWrite(APXLOG_MARK_INFO "Debug service finished with exit code %d.", gExitval);
    SAFE_CLOSE_HANDLE(gPidfileHandle);
    if (gPidfileName) {
        DeleteFileW(gPidfileName);
    }
    return gExitval == 0 ? TRUE : FALSE;
}

BOOL docmdRunService(LPAPXCMDLINE lpCmdline)
{
    BOOL rv;
    SERVICE_TABLE_ENTRYW dispatch_table[] = {
        { lpCmdline->szApplication, (LPSERVICE_MAIN_FUNCTIONW)serviceMain },
        { NULL, NULL }
    };
    _service_mode = TRUE;
    _service_name = lpCmdline->szApplication;
    apxLogWrite(APXLOG_MARK_INFO "Running Service '%S'...", _service_name);
    if (StartServiceCtrlDispatcherW(dispatch_table)) {
        apxLogWrite(APXLOG_MARK_INFO "Run service finished.");
        rv = TRUE;
    }
    else {
        apxLogWrite(APXLOG_MARK_ERROR "StartServiceCtrlDispatcher for '%S' failed.",
                    lpCmdline->szApplication);
        rv = FALSE;
    }
    SAFE_CLOSE_HANDLE(gPidfileHandle);
    if (gPidfileName) {
        DeleteFileW(gPidfileName);
    }
    return rv;
}

static const char *gSzProc[] = {
    "",
    "parse command line arguments",
    "load configuration",
    "run service as console application",
    "run service",
    "start service",
    "stop service",
    "update service parameters",
    "install service",
    "delete service",
    NULL
};

void __cdecl main(int argc, char **argv)
{
    UINT rv = 0;

    LPAPXCMDLINE lpCmdline;

    if (argc > 1) {
        DWORD ss = 0;
        if (strncmp(argv[1], "//PP", 4) == 0) {
            /* Handy sleep routine defaulting to 1 minute */
            if (argv[1][4] && argv[1][5] && argv[1][6]) {
                int us = atoi(argv[1] + 6);
                if (us > 0)
                    ss = (DWORD)us;
            }
            Sleep(ss * 1000);
            ExitProcess(0);
            return;
        }
        else if (strcmp(argv[1], "pause") == 0) {
            /* Handy sleep routine defaulting to 1 minute */
            if (argc > 2) {
                int us = atoi(argv[2]);
                if (us > 0)
                    ss = (DWORD)us;
            }
        }
        if (ss) {
            Sleep(ss * 1000);
            ExitProcess(0);
            return;
        }
    }
    apxHandleManagerInitialize();
    /* Create the main Pool */
    gPool = apxPoolCreate(NULL, 0);

    /* Parse the command line */
    if ((lpCmdline = apxCmdlineParse(gPool, _options, _commands, _altcmds)) == NULL) {
        apxLogWrite(APXLOG_MARK_ERROR "Invalid command line arguments.");
        rv = 1;
        goto cleanup;
    }
    apxCmdlineLoadEnvVars(lpCmdline);
    if (lpCmdline->dwCmdIndex < 6) {
        if (!loadConfiguration(lpCmdline) &&
            lpCmdline->dwCmdIndex < 5) {
            apxLogWrite(APXLOG_MARK_ERROR "Load configuration failed.");
            rv = 2;
            goto cleanup;
        }
    }

    apxLogOpen(gPool, SO_LOGPATH, SO_LOGPREFIX, SO_LOGROTATE);
    apxLogLevelSetW(NULL, SO_LOGLEVEL);
    apxLogWrite(APXLOG_MARK_DEBUG "Apache Commons Daemon procrun log initialized.");
    if (SO_LOGROTATE)
        apxLogWrite(APXLOG_MARK_DEBUG "Log will rotate each %d seconds.", SO_LOGROTATE);

    apxLogWrite(APXLOG_MARK_INFO "Apache Commons Daemon procrun (%s %d-bit) started.",
                PRG_VERSION, PRG_BITS);

    AplZeroMemory(&gStdwrap, sizeof(APX_STDWRAP));
    gStartPath = lpCmdline->szExePath;
    gStdwrap.szLogPath = SO_LOGPATH;
    /* In debug mode allways use console */
    if (lpCmdline->dwCmdIndex != 1) {
        gStdwrap.szStdOutFilename = SO_STDOUTPUT;
        gStdwrap.szStdErrFilename = SO_STDERROR;
    }
    redirectStdStreams(&gStdwrap, lpCmdline);
    if (lpCmdline->dwCmdIndex == 2) {
        SYSTEMTIME t;
        GetLocalTime(&t);
        fprintf(stdout, "\n%d-%02d-%02d %02d:%02d:%02d "
                        "Apache Commons Daemon procrun stdout initialized.\n",
                        t.wYear, t.wMonth, t.wDay,
                        t.wHour, t.wMinute, t.wSecond);
        fprintf(stderr, "\n%d-%02d-%02d %02d:%02d:%02d "
                        "Apache Commons Daemon procrun stderr initialized.\n",
                        t.wYear, t.wMonth, t.wDay,
                        t.wHour, t.wMinute, t.wSecond);
    }
    switch (lpCmdline->dwCmdIndex) {
        case 1: /* Run Service as console application */
            if (!docmdDebugService(lpCmdline))
                rv = 3;
        break;
        case 2: /* Run Service */
            if (!docmdRunService(lpCmdline))
                rv = 4;
        break;
        case 3: /* Start service */
            if (!docmdStartService(lpCmdline))
                rv = 5;
        break;
        case 4: /* Stop Service */
            if (!docmdStopService(lpCmdline))
                rv = 6;
        break;
        case 5: /* Update Service parameters */
            if (!docmdUpdateService(lpCmdline))
                rv = 7;
        break;
        case 6: /* Install Service */
            if (!docmdInstallService(lpCmdline))
                rv = 8;
        break;
        case 7: /* Delete Service */
            if (!docmdDeleteService(lpCmdline))
                rv = 9;
        break;
        case 8: /* Print Configuration and exit */
            printConfig(lpCmdline);
        break;
        case 9: /* Print Usage and exit */
            printUsage(lpCmdline, TRUE);
        break;
        case 10: /* Print version and exit */
            printVersion();
        break;
        default:
            /* Unknown command option */
            apxLogWrite(APXLOG_MARK_ERROR "Unknown command line option.");
            printUsage(lpCmdline, FALSE);
            rv = 99;
        break;
    }

cleanup:
    if (rv) {
        int ix = 0;
        if (rv > 0 && rv < 10)
            ix = rv;
        apxLogWrite(APXLOG_MARK_ERROR "Apache Commons Daemon procrun failed "
                                      "with exit value: %d (failed to %s).",
                                      rv, gSzProc[ix]);
        if (ix > 2 && !_service_mode) {
            /* Print something to the user console */
            apxDisplayError(FALSE, NULL, 0, "Failed to %s.", gSzProc[ix]);
        }
    }
    else
        apxLogWrite(APXLOG_MARK_INFO "Apache Commons Daemon procrun finished.");
    if (lpCmdline)
        apxCmdlineFree(lpCmdline);
    _service_status_handle = NULL;
    _service_mode = FALSE;
    _flushall();
    apxLogClose(NULL);
    apxHandleManagerDestroy();
    ExitProcess(rv);
}
