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;
}