static BOOL docmdInstallService()

in src/native/windows/apps/prunsrv/prunsrv.c [764:890]


static BOOL docmdInstallService(LPAPXCMDLINE lpCmdline)
{
    APXHANDLE hService;
    BOOL  rv;
    BOOL  bDelayedStart = FALSE;
    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) {
    	if (lstrcmpiW(SO_STARTUP, PRSRV_AUTO) == 0) {
    		dwStart = SERVICE_AUTO_START;
    	} else if (lstrcmpiW(SO_STARTUP, PRSRV_DELAYED) == 0) {
    		dwStart = SERVICE_AUTO_START;
    		bDelayedStart = TRUE;
    	}
    }
    /* 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);
    /* Configure as delayed start */
    if (rv & bDelayedStart) {
    	if (!apxServiceSetOptions(hService,
    	                          NULL,
                                  dwType,
                                  dwStart,
                                  bDelayedStart,
                                  SERVICE_NO_CHANGE)) {
            apxLogWrite(APXLOG_MARK_WARN "Failed to configure service for delayed startup");
        }
    }
    /* Set the --Description */
    if (rv) {
        LPCWSTR sd = NULL;
        LPCWSTR su = NULL;
        LPCWSTR sp = NULL;
        DWORD dwResult;

        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);
        dwResult = apxSecurityGrantFileAccessToUser(SO_LOGPATH, su);
        if (dwResult) {
            logGrantFileAccessFail(su, SO_LOGPATH, dwResult);
        }
    }
    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;
}