in src/native/windows/apps/prunsrv/prunsrv.c [1419:1597]
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
*/
if (IS_VALID_STRING(SO_JVMOPTIONS)) {
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;
}