mturk 2004/04/07 04:21:43
Added: daemon/src/native/nt/procrun/apps/prunsrv prunsrv.vcproj
prunsrv.rc prunsrv.h prunsrv.c
Log:
Initial upload
Revision Changes Path
1.1
jakarta-commons/daemon/src/native/nt/procrun/apps/prunsrv/prunsrv.vcproj
Index: prunsrv.vcproj
===================================================================
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="prunsrv"
ProjectGUID="{DC1701B5-D480-461A-A16F-67E383AF376D}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\..\obj\Debug"
IntermediateDirectory="..\..\obj\Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\;..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="shlwapi.lib"
OutputFile="../../bin/prunsrvd.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/prunsrv.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="..\..\include"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\..\obj\Release"
IntermediateDirectory="..\..\obj\Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=".\;..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="shlwapi.lib"
OutputFile="../../bin/prunsrv.exe"
LinkIncremental="1"
GenerateDebugInformation="FALSE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
AdditionalIncludeDirectories="..\..\include"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\prunsrv.c">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\prunsrv.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
<File
RelativePath=".\prunsrv.rc">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
1.1
jakarta-commons/daemon/src/native/nt/procrun/apps/prunsrv/prunsrv.rc
Index: prunsrv.rc
===================================================================
/* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed 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.
*/
#include "apxwin.h"
#include "prunsrv.h"
#define RSTR_PRUNSRV "Service Runner"
IDI_MAINICON ICON "../../resources/procrunw.ico"
1 VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x3fL
#if defined(_DEBUG)
FILEFLAGS 0x03L
#else
FILEFLAGS 0x02L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Apache Software Foundation\0"
VALUE "FileDescription", RSTR_PRUNSRV "\0"
VALUE "FileVersion", PRG_VERSION
VALUE "InternalName", RSTR_PRUNSRV "\0"
VALUE "LegalCopyright", "Copyright � 2000-2003 The Apache Software
Foundation.\0"
VALUE "OriginalFilename", "prunsrv.exe\0"
VALUE "ProductName", RSTR_PRUNSRV "\0"
VALUE "ProductVersion", PRG_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
1.1
jakarta-commons/daemon/src/native/nt/procrun/apps/prunsrv/prunsrv.h
Index: prunsrv.h
===================================================================
/* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed 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.
*/
/* ====================================================================
* jar2exe -- convert .jar file to WIN32 executable.
* Contributed by Mladen Turk <[EMAIL PROTECTED]>
* 05 Aug 2003
* ====================================================================
*/
#ifndef _PRUNSRV_H
#define _PRUNSRV_H
#undef PRG_VERSION
#define PRG_VERSION "1.0.0.0"
#define PRG_REGROOT L"Apache Software Foundation\\Procrun 2.0"
#endif /* _PRUNSRV_H */
1.1
jakarta-commons/daemon/src/native/nt/procrun/apps/prunsrv/prunsrv.c
Index: prunsrv.c
===================================================================
/* Copyright 2000-2004 The Apache Software Foundation
*
* Licensed 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 <[EMAIL PROTECTED]>
* 05 Aug 2003
* ====================================================================
*/
/* Force the JNI vprintf functions */
#define _DEBUG_JNI 1
#include "apxwin.h"
#include "prunsrv.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <fcntl.h>
#include <io.h> /* _open_osfhandle */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
typedef struct APX_STDWRAP {
BOOL bAppend;
LPCWSTR szStdOutFilename;
LPCWSTR szStdErrFilename;
HANDLE hStdOutFile;
HANDLE hStdErrFile;
FILE *fpStdOutFile;
FILE *fpStdErrFile;
FILE fpStdOutSave;
FILE fpStdErrSave;
} 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_MANUAL = L"manual";
static LPCWSTR PRSRV_JBIN = L"\\bin\\java.exe";
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"SS", /* 3 Stop Service */
L"US", /* 4 Update Service parameters */
L"IS", /* 5 Install Service */
L"DS", /* 6 Delete Service */
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"Startup", L"Startup", NULL,
APXCMDOPT_STR | APXCMDOPT_SRV, NULL, 0},
/* 4 */ { L"DependsOn", L"DependsOn", NULL,
APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 5 */ { L"Environment", L"Environment", NULL,
APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 6 */ { L"User", L"User", NULL,
APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 7 */ { L"Password", L"Password", NULL,
APXCMDOPT_BIN | APXCMDOPT_REG, NULL, 0},
/* 8 */ { L"JavaHome", L"JavaHome", L"Java",
APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 9 */ { L"Jvm", L"Jvm", L"Java",
APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 10 */ { L"JvmOptions", L"Options", L"Java",
APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 11 */ { L"Classpath", L"Classpath", L"Java",
APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 12 */ { L"JvmMs", L"JvmMs", L"Java",
APXCMDOPT_INT | APXCMDOPT_REG, NULL, 0},
/* 13 */ { L"JvmMx", L"JvmMx", L"Java",
APXCMDOPT_INT | APXCMDOPT_REG, NULL, 0},
/* 14 */ { L"JvmSs", L"JvmSs", L"Java",
APXCMDOPT_INT | APXCMDOPT_REG, NULL, 0},
/* 15 */ { L"StopImage", L"Image", L"Stop",
APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 16 */ { L"StopPath", L"WorkingPath", L"Stop",
APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 17 */ { L"StopClass", L"Class", L"Stop",
APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 18 */ { L"StopParams", L"Params", L"Stop",
APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 19 */ { L"StopMethod", L"Method", L"Stop",
APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 20 */ { L"StopMode", L"Mode", L"Stop",
APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 21 */ { L"StopTimeout", L"Timeout", L"Stop",
APXCMDOPT_INT | APXCMDOPT_REG, NULL, 0},
/* 22 */ { L"StartImage", L"Image", L"Start",
APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 23 */ { L"StartPath", L"WorkingPath", L"Start",
APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 24 */ { L"StartClass", L"Class", L"Start",
APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 25 */ { L"StartParams", L"Params", L"Start",
APXCMDOPT_MSZ | APXCMDOPT_REG, NULL, 0},
/* 26 */ { L"StartMethod", L"Method", L"Start",
APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 27 */ { L"StartMode", L"Mode", L"Start",
APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 28 */ { L"LogPath", L"Path", L"Log",
APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 29 */ { L"LogPrefix", L"Prefix", L"Log",
APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 30 */ { L"LogLevel", L"Level", L"Log",
APXCMDOPT_STR | APXCMDOPT_REG, NULL, 0},
/* 31 */ { L"StdError", L"StdError", L"Log",
APXCMDOPT_STE | APXCMDOPT_REG, NULL, 0},
/* 32 */ { L"StdOutput", L"StdOutput", L"Log",
APXCMDOPT_STE | 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_STARTUP GET_OPT_T(3)
#define SO_DESCRIPTION GET_OPT_V(0)
#define SO_DISPLAYNAME GET_OPT_V(1)
#define SO_INSTALL GET_OPT_V(2)
#define SO_STARTUP GET_OPT_V(3)
#define SO_DEPENDSON GET_OPT_V(4)
#define SO_ENVIRONMENT GET_OPT_V(5)
#define SO_USER GET_OPT_V(6)
#define SO_PASSWORD GET_OPT_V(7)
#define SO_JAVAHOME GET_OPT_V(8)
#define SO_JVM GET_OPT_V(9)
#define SO_JVMOPTIONS GET_OPT_V(10)
#define SO_CLASSPATH GET_OPT_V(11)
#define SO_JVMMS GET_OPT_I(12)
#define SO_JVMMX GET_OPT_I(13)
#define SO_JVMSS GET_OPT_I(14)
#define SO_STOPIMAGE GET_OPT_V(15)
#define SO_STOPPATH GET_OPT_V(16)
#define SO_STOPCLASS GET_OPT_V(17)
#define SO_STOPPARAMS GET_OPT_V(18)
#define SO_STOPMETHOD GET_OPT_V(19)
#define SO_STOPMODE GET_OPT_V(20)
#define SO_STOPTIMEOUT GET_OPT_V(21)
#define SO_STARTIMAGE GET_OPT_V(22)
#define SO_STARTPATH GET_OPT_V(23)
#define SO_STARTCLASS GET_OPT_V(24)
#define SO_STARTPARAMS GET_OPT_V(25)
#define SO_STARTMETHOD GET_OPT_V(26)
#define SO_STARTMODE GET_OPT_V(27)
#define SO_LOGPATH GET_OPT_V(28)
#define SO_LOGPREFIX GET_OPT_V(29)
#define SO_LOGLEVEL GET_OPT_V(30)
#define SO_STDERROR GET_OPT_V(31)
#define SO_STDOUTPUT GET_OPT_V(32)
/* Main servic table entry
* filled at run-time
*/
static SERVICE_TABLE_ENTRYW _service_table[] = {
{NULL, NULL},
{NULL, NULL}
};
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;
/* Global variables and objects */
static APXHANDLE gPool;
static APXHANDLE gWorker;
static APX_STDWRAP gStdwrap; /* stdio/stderr redirection */
static LPWSTR _jni_jvmpath = NULL; /* Path to jvm dll */
static LPSTR _jni_jvmoptions = NULL; /* Path to jvm options */
static LPSTR _jni_classpath = NULL;
static LPSTR _jni_rparam = NULL; /* Startup arguments */
static LPSTR _jni_sparam = NULL; /* Shutdown arguments */
static LPSTR _jni_rmethod = NULL; /* Startup arguments */
static LPSTR _jni_smethod = NULL; /* Shutdown arguments */
static CHAR _jni_rclass[SIZ_RESLEN] = {'\0'}; /* Startup class */
static CHAR _jni_sclass[SIZ_RESLEN] = {'\0'}; /* Shutdown class */
/* 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)
{
/* Clear up the handles */
lpWrapper->fpStdErrFile = NULL;
lpWrapper->fpStdOutFile = NULL;
/* Save the original streams */
lpWrapper->fpStdOutSave = *stdout;
lpWrapper->fpStdErrSave = *stderr;
/* redirect to file or console */
if (lpWrapper->szStdOutFilename) {
if (*lpWrapper->szStdOutFilename == L'+') {
++lpWrapper->szStdOutFilename;
lpWrapper->bAppend = TRUE;
}
/* Delete the file if not in append mode
* XXX: See if we can use the params instead of that.
*/
if (!lpWrapper->bAppend)
DeleteFileW(lpWrapper->szStdOutFilename);
lpWrapper->hStdOutFile = CreateFileW(lpWrapper->szStdOutFilename,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (IS_INVALID_HANDLE(lpWrapper->hStdOutFile))
return FALSE;
/* Allways move to the end of file */
SetFilePointer(lpWrapper->hStdOutFile, 0, NULL, FILE_END);
}
else
return FALSE;
if (lpWrapper->szStdErrFilename) {
if (*lpWrapper->szStdErrFilename == L'+') {
++lpWrapper->szStdErrFilename;
lpWrapper->bAppend = TRUE;
}
if (!lpWrapper->bAppend)
DeleteFileW(lpWrapper->szStdOutFilename);
lpWrapper->hStdErrFile = CreateFileW(lpWrapper->szStdErrFilename,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (IS_INVALID_HANDLE(lpWrapper->hStdErrFile))
return FALSE;
SetFilePointer(lpWrapper->hStdErrFile, 0, NULL, FILE_END);
}
else if (lpWrapper->szStdOutFilename) {
/* Use the same file handle for stderr as for stdout */
lpWrapper->szStdErrFilename = lpWrapper->szStdOutFilename;
lpWrapper->hStdErrFile = lpWrapper->hStdOutFile;
}
else {
CloseHandle(lpWrapper->hStdOutFile);
return FALSE;
}
/* Open the stream buffers
* This will redirect all printf to go to the redirected files.
* It is used for JNI vprintf functionality.
*/
lpWrapper->fpStdOutFile = _fdopen(_open_osfhandle(
(intptr_t)lpWrapper->hStdOutFile,
_O_TEXT), "w");
lpWrapper->fpStdErrFile = _fdopen(_open_osfhandle(
(intptr_t)lpWrapper->hStdErrFile,
_O_TEXT), "w");
if (lpWrapper->fpStdOutFile) {
*stdout = *lpWrapper->fpStdOutFile;
setvbuf(stdout, NULL, _IONBF, 0);
}
if (lpWrapper->fpStdErrFile) {
*stderr = *lpWrapper->fpStdErrFile;
setvbuf(stderr, NULL, _IONBF, 0);
}
return TRUE;
}
static void cleanupStdStreams(APX_STDWRAP *lpWrapper)
{
/* Close the redirectied streams */
if (lpWrapper->fpStdOutFile)
fclose(lpWrapper->fpStdOutFile);
if (lpWrapper->fpStdErrFile)
fclose(lpWrapper->fpStdErrFile);
/* restore the original streams */
*stdout = lpWrapper->fpStdOutSave;
*stderr = lpWrapper->fpStdErrSave;
}
/* Debuging functions */
static void printUsage(LPAPXCMDLINE lpCmdline)
{
#ifdef _DEBUG
int i = 0;
fwprintf(stderr, L"Usage: %s //CMD//Servce [--options]\n",
lpCmdline->szExecutable);
fwprintf(stderr, L" Commands:\n");
fwprintf(stderr, L" //IS//ServiceName Install Service\n");
fwprintf(stderr, L" //US//ServiceName Update Service parameters\n");
fwprintf(stderr, L" //DS//ServiceName Delete Service\n");
fwprintf(stderr, L" //RS//ServiceName Run Service\n");
fwprintf(stderr, L" //SS//ServiceName Stop Service\n");
fwprintf(stderr,
L" //TS//ServiceName Run Service as console application\n");
fwprintf(stderr, L" Options:\n");
while (_options[i].szName) {
fwprintf(stderr, L" --%s\n", _options[i].szName);
++i;
}
#endif
}
/* Display configuration 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;
}
}
/* Load the configuration from Registry
* loads only nonspecified items
*/
static BOOL loadConfiguration(LPAPXCMDLINE lpCmdline)
{
APXHANDLE hRegistry;
int i = 0;
SetLastError(ERROR_SUCCESS);
hRegistry = apxCreateRegistryW(gPool, KEY_READ, PRG_REGROOT,
lpCmdline->szApplication,
APXREG_SOFTWARE | APXREG_SERVICE);
if (IS_INVALID_HANDLE(hRegistry)) {
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, 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;
}
/* Operations */
static BOOL docmdInstallService(LPAPXCMDLINE lpCmdline)
{
APXHANDLE hService;
BOOL rv;
DWORD dwStart = SERVICE_DEMAND_START;
WCHAR szImage[SIZ_HUGLEN];
apxLogWrite(APXLOG_MARK_DEBUG "Installing service...");
hService = apxCreateService(gPool, GENERIC_ALL, 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))
dwStart = SERVICE_AUTO_START;
/* Check if --Install is provided */
if (!SO_INSTALL) {
lstrcpyW(szImage, lpCmdline->szExePath);
lstrcatW(szImage, L"\\");
lstrcatW(szImage, lpCmdline->szExecutable);
lstrcatW(szImage, L".exe");
}
else
lstrcpyW(szImage, SO_INSTALL);
/* Replace not needed qoutes */
apxStrQuoteInplaceW(szImage);
/* Add run-service command line option */
lstrcatW(szImage, L" //RS//");
lstrcatW(szImage, lpCmdline->szApplication);
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 "Service %S name %S", lpCmdline->szApplication,
SO_DISPLAYNAME);
rv = apxServiceInstall(hService,
lpCmdline->szApplication,
SO_DISPLAYNAME, /* --DisplayName */
SO_INSTALL,
SO_DEPENDSON, /* --DependendsOn */
SERVICE_WIN32_OWN_PROCESS,
dwStart);
/* Set the --Description */
if (rv && (ST_DESCRIPTION & APXCMDOPT_FOUND)) {
apxLogWrite(APXLOG_MARK_DEBUG "Setting service description %S",
SO_DESCRIPTION);
apxServiceSetNames(hService, NULL, NULL, SO_DESCRIPTION,
NULL, NULL);
}
apxCloseHandle(hService);
if (rv) {
saveConfiguration(lpCmdline);
apxLogWrite(APXLOG_MARK_INFO "Service %S installed",
lpCmdline->szApplication);
}
else
apxLogWrite(APXLOG_MARK_ERROR "Failed installing %S service",
lpCmdline->szApplication);
return rv;
}
static BOOL docmdDeleteService(LPAPXCMDLINE lpCmdline)
{
APXHANDLE hService;
BOOL rv = FALSE;
apxLogWrite(APXLOG_MARK_INFO "Deleting service...");
hService = apxCreateService(gPool, GENERIC_ALL, 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))
rv = apxServiceDelete(hService);
if (rv) {
/* Delete all service registry settings */
apxDeleteRegistryW(PRG_REGROOT, lpCmdline->szApplication, TRUE);
apxLogWrite(APXLOG_MARK_DEBUG "Service %S deleted",
lpCmdline->szApplication);
}
else {
apxDisplayError(TRUE, NULL, 0, "Unable to delete %S service",
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...");
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)) {
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 %S service",
lpCmdline->szApplication);
}
else
apxDisplayError(TRUE, NULL, 0, "Unable to open %S service",
lpCmdline->szApplication);
apxCloseHandle(hService);
apxLogWrite(APXLOG_MARK_INFO "Stop service finished.");
return rv;
}
static BOOL docmdUpdateService(LPAPXCMDLINE lpCmdline)
{
APXHANDLE hService;
BOOL rv = FALSE;
apxLogWrite(APXLOG_MARK_INFO "Updating service...");
hService = apxCreateService(gPool, GENERIC_ALL, 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)) {
apxServiceSetNames(hService,
NULL, /* Never update the ImagePath */
SO_DISPLAYNAME,
SO_DESCRIPTION,
NULL,
NULL);
/* Update the --Startup mode */
if (ST_STARTUP & APXCMDOPT_FOUND) {
DWORD dwStart = SERVICE_NO_CHANGE;
if (!lstrcmpiW(SO_STARTUP, PRSRV_AUTO))
dwStart = SERVICE_AUTO_START;
else if (!lstrcmpiW(SO_STARTUP, PRSRV_MANUAL))
dwStart = SERVICE_DEMAND_START;
apxServiceSetOptions(hService,
SERVICE_NO_CHANGE,
dwStart,
SERVICE_NO_CHANGE);
}
apxLogWrite(APXLOG_MARK_INFO "Service %S updated",
lpCmdline->szApplication);
saveConfiguration(lpCmdline);
}
else
apxDisplayError(TRUE, NULL, 0, "Unable to open %S service",
lpCmdline->szApplication);
apxCloseHandle(hService);
apxLogWrite(APXLOG_MARK_INFO "Update service finished.");
return rv;
}
/* Report the service status to the SCM
*/
int reportServiceStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
BOOL fResult = TRUE;
if (_service_mode && _service_status_handle) {
if (dwCurrentState == SERVICE_START_PENDING)
_service_status.dwControlsAccepted = 0;
else
_service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
_service_status.dwCurrentState = dwCurrentState;
_service_status.dwWin32ExitCode = dwWin32ExitCode;
_service_status.dwWaitHint = dwWaitHint;
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 */
}
}
return fResult;
}
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;
}
/* Executed when the service receives stop event */
static DWORD serviceStop()
{
APXHANDLE hJava = NULL;
DWORD rv = 0;
apxLogWrite(APXLOG_MARK_INFO "Stopoping service...");
if (IS_INVALID_HANDLE(gWorker)) {
apxLogWrite(APXLOG_MARK_INFO "Worker is not defined");
return TRUE; /* Nothing to do */
}
if (_jni_shutdown) {
hJava = apxCreateJava(gPool, _jni_jvmpath);
if (IS_INVALID_HANDLE(hJava)) {
apxLogWrite(APXLOG_MARK_ERROR "Failed creating java %S", _jni_jvmpath);
return 1;
}
if (!apxJavaInitialize(hJava, _jni_classpath, _jni_jvmoptions,
SO_JVMMS, SO_JVMMX, SO_JVMSS)) {
rv = 2;
apxLogWrite(APXLOG_MARK_ERROR "Failed initializing java %s",
_jni_classpath);
goto cleanup;
}
if (!apxJavaLoadMainClass(hJava, _jni_sclass, _jni_smethod, _jni_sparam)) {
rv = 2;
apxLogWrite(APXLOG_MARK_ERROR "Failed loading main %s class %s",
_jni_rclass, _jni_classpath);
goto cleanup;
}
if (!apxJavaStart(hJava)) {
apxLogWrite(APXLOG_MARK_ERROR "Failed starting java");
rv = 3;
}
else {
apxLogWrite(APXLOG_MARK_DEBUG "Waitning java stop worker to finish...");
apxJavaWait(hJava, INFINITE, FALSE);
apxLogWrite(APXLOG_MARK_DEBUG "Java stop worker finished.");
}
}
cleanup:
/* Close Java JNI handle
* 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(hJava))
apxCloseHandle(hJava);
/* Simply send the WM_CLOSE to the worker */
apxLogWrite(APXLOG_MARK_DEBUG "Sending WM_CLOSE to worker");
apxHandleSendMessage(gWorker, WM_CLOSE, 0, 0);
apxLogWrite(APXLOG_MARK_INFO "Service stopped.");
return rv;
}
/* Executed when the service receives start event */
static DWORD serviceStart()
{
DWORD rv = 0;
DWORD nArgs;
LPWSTR *pArgs;
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 (_jni_startup) {
gWorker = apxCreateJava(gPool, _jni_jvmpath);
if (IS_INVALID_HANDLE(gWorker)) {
apxLogWrite(APXLOG_MARK_ERROR "Failed creating java %S", _jni_jvmpath);
return 1;
}
if (!apxJavaInitialize(gWorker, _jni_classpath, _jni_jvmoptions,
SO_JVMMS, SO_JVMMX, SO_JVMSS)) {
rv = 2;
apxLogWrite(APXLOG_MARK_ERROR "Failed initializing java %s",
_jni_classpath);
goto cleanup;
}
if (!apxJavaLoadMainClass(gWorker, _jni_rclass, _jni_rmethod, _jni_rparam)) {
rv = 3;
apxLogWrite(APXLOG_MARK_ERROR "Failed loading main %s class %s",
_jni_rclass, _jni_classpath);
goto cleanup;
}
apxJavaSetOut(gWorker, TRUE, gStdwrap.szStdErrFilename);
apxJavaSetOut(gWorker, FALSE, gStdwrap.szStdOutFilename);
if (!apxJavaStart(gWorker)) {
rv = 4;
apxLogWrite(APXLOG_MARK_ERROR "Failed starting Java");
goto cleanup;
}
apxLogWrite(APXLOG_MARK_DEBUG "Java started %s", _jni_rclass);
}
else {
/* Redirect process */
gWorker = apxCreateProcessW(gPool,
0,
child_callback,
SO_USER,
SO_PASSWORD,
FALSE);
if (IS_INVALID_HANDLE(gWorker)) {
apxLogWrite(APXLOG_MARK_ERROR "Failed creating process");
return 1;
}
if (!apxProcessSetExecutableW(gWorker, SO_STARTIMAGE)) {
apxLogWrite(APXLOG_MARK_ERROR "Failed seting process executable %S",
SO_STARTIMAGE);
rv = 2;
goto cleanup;
}
/* Assemble the command line */
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 seting process arguments
(argc=%d)",
nArgs);
goto cleanup;
}
/* Set the working path */
if (!apxProcessSetWorkingPathW(gWorker, SO_STARTPATH)) {
rv = 4;
apxLogWrite(APXLOG_MARK_ERROR "Failed seting process working path to %S",
SO_STARTPATH);
goto cleanup;
}
/* Finally execute the child process
*/
if (!apxProcessExecute(gWorker)) {
rv = 5;
apxLogWrite(APXLOG_MARK_ERROR "Failed executing process");
goto cleanup;
}
}
if (rv == 0) {
apxLogWrite(APXLOG_MARK_INFO "Service started.");
}
return rv;
cleanup:
if (!IS_INVALID_HANDLE(gWorker))
apxCloseHandle(gWorker); /* Close the worker handle */
gWorker = NULL;
return rv;
}
/* Service controll handler
*/
void WINAPI service_ctrl_handler(DWORD dwCtrlCode)
{
switch (dwCtrlCode) {
case SERVICE_CONTROL_STOP:
apxLogWrite(APXLOG_MARK_INFO "Service STOP signaled");
reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
/* Call the stop handler that will actualy stop the service */
serviceStop();
return;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
reportServiceStatus(_service_status.dwCurrentState, NO_ERROR, 0);
}
/* Console control handler
*
*/
BOOL WINAPI console_handler(DWORD dwCtrlType)
{
switch (dwCtrlType) {
case CTRL_BREAK_EVENT:
apxLogWrite(APXLOG_MARK_INFO "Console CTRL+BREAK event signaled");
serviceStop();
return TRUE;
case CTRL_C_EVENT:
apxLogWrite(APXLOG_MARK_INFO "Console CTRL+C event signaled");
serviceStop();
return TRUE;
case CTRL_CLOSE_EVENT:
apxLogWrite(APXLOG_MARK_INFO "Console CTRL+CLOSE event signaled");
serviceStop();
return TRUE;
case CTRL_SHUTDOWN_EVENT:
apxLogWrite(APXLOG_MARK_INFO "Console SHUTDOWN event signaled");
serviceStop();
return TRUE;
break;
}
return FALSE;
}
/* Main service execution loop */
void WINAPI serviceMain(DWORD argc, LPTSTR *argv)
{
DWORD rc;
_service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
_service_status.dwCurrentState = SERVICE_START_PENDING;
_service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE;
_service_status.dwWin32ExitCode = 0;
_service_status.dwCheckPoint = 0;
_service_status.dwWaitHint = 0;
_service_status.dwServiceSpecificExitCode = 0;
apxLogWrite(APXLOG_MARK_DEBUG "Inside ServiceMain...");
/* Check the StartMode */
if (SO_STARTMODE) {
if (!lstrcmpiW(SO_STARTMODE, PRSRV_JVM)) {
_jni_startup = TRUE;
WideToAscii(SO_STARTCLASS, _jni_rclass);
/* Exchange all dots with slashes */
apxStrCharReplaceA(_jni_rclass, '.', '/');
_jni_rparam = MzWideToAscii(SO_STARTPARAMS, (LPSTR)SO_STARTPARAMS);
}
else if (!lstrcmpiW(SO_STARTMODE, PRSRV_JAVA)) {
LPWSTR jx = NULL, szJH = apxGetJavaSoftHome(gPool, FALSE);
if (szJH) {
jx = apxPoolAlloc(gPool, (lstrlenW(szJH) + 16) * sizeof(WCHAR));
lstrcpyW(jx, szJH);
lstrcatW(jx, PRSRV_JBIN);
SO_STARTPATH = szJH;
}
/* StartImage now contains the full path to the java.exe */
SO_STARTIMAGE = jx;
}
}
/* Check the StopMode */
if (SO_STOPMODE) {
if (!lstrcmpiW(SO_STOPMODE, PRSRV_JVM)) {
_jni_shutdown = TRUE;
WideToAscii(SO_STOPCLASS, _jni_sclass);
apxStrCharReplaceA(_jni_sclass, '.', '/');
_jni_sparam = MzWideToAscii(SO_STOPPARAMS, (LPSTR)SO_STOPPARAMS);
}
else if (!lstrcmpiW(SO_STOPMODE, PRSRV_JAVA)) {
LPWSTR jx = NULL, szJH = apxGetJavaSoftHome(gPool, FALSE);
if (szJH) {
jx = apxPoolAlloc(gPool, (lstrlenW(szJH) + 16) * sizeof(WCHAR));
lstrcpyW(jx, szJH);
lstrcatW(jx, PRSRV_JBIN);
SO_STOPPATH = szJH;
}
/* StopImage now contains the full path to the java.exe */
SO_STOPIMAGE = jx;
}
}
/* Find the classpath */
if (_jni_shutdown || _jni_startup) {
if (SO_JVM) {
if (lstrcmpW(SO_JVM, PRSRV_AUTO))
_jni_jvmpath = SO_JVM;
}
if (SO_CLASSPATH)
_jni_classpath = WideToAscii(SO_CLASSPATH, (LPSTR)SO_CLASSPATH);
if (SO_STARTMETHOD)
_jni_rmethod = WideToAscii(SO_STARTMETHOD, (LPSTR)SO_STARTMETHOD);
if (SO_STOPMETHOD)
_jni_smethod = WideToAscii(SO_STOPMETHOD, (LPSTR)SO_STOPMETHOD);
if (SO_JVMOPTIONS) {
_jni_jvmoptions = MzWideToAscii(SO_JVMOPTIONS, (LPSTR)SO_JVMOPTIONS);
}
}
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;
}
}
reportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
if ((rc = serviceStart()) == 0) {
/* Service is started */
DWORD rv;
reportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0);
apxLogWrite(APXLOG_MARK_DEBUG "Waitning worker to finish...");
rv = apxHandleWait(gWorker, INFINITE, FALSE);
apxLogWrite(APXLOG_MARK_DEBUG "Worker finished.");
reportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
fflush(stdout);
}
else {
apxLogWrite(APXLOG_MARK_ERROR "ServiceStart returned %d", rc);
goto cleanup;
}
reportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
return;
cleanup:
/* Cleanup */
reportServiceStatus(SERVICE_STOPPED, ERROR_SERVICE_SPECIFIC_ERROR, 0);
return;
}
/* Run the service in the debug mode */
BOOL docmdDebugService(LPAPXCMDLINE lpCmdline)
{
BOOL rv = FALSE;
_service_mode = FALSE;
apxLogWrite(APXLOG_MARK_INFO "Debuging Service...");
serviceMain(0, NULL);
apxLogWrite(APXLOG_MARK_INFO "Debug service finished.");
return rv;
}
BOOL docmdRunService(LPAPXCMDLINE lpCmdline)
{
BOOL rv = FALSE;
_service_mode = TRUE;
apxLogWrite(APXLOG_MARK_INFO "Running Service...");
_service_name = lpCmdline->szApplication;
_service_table[0].lpServiceName = lpCmdline->szApplication;
_service_table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONW)serviceMain;
rv = (StartServiceCtrlDispatcherW(_service_table) == FALSE);
apxLogWrite(APXLOG_MARK_INFO "Run service finished.");
return rv;
}
void __cdecl main(int argc, char **argv)
{
LPAPXCMDLINE lpCmdline;
apxHandleManagerInitialize();
/* Create the main Pool */
gPool = apxPoolCreate(NULL, 0);
/* Parse the command line */
if ((lpCmdline = apxCmdlineParse(gPool, _options, _commands)) == NULL) {
apxLogWrite(APXLOG_MARK_ERROR "Invalid command line arguments");
goto cleanup;
}
apxCmdlineLoadEnvVars(lpCmdline);
if (lpCmdline->dwCmdIndex < 5 &&
!loadConfiguration(lpCmdline)) {
apxLogWrite(APXLOG_MARK_ERROR "Load configuration failed");
goto cleanup;
}
/* Set console handler to capture CTRL events */
SetConsoleCtrlHandler((PHANDLER_ROUTINE)console_handler, TRUE);
apxLogOpen(gPool, SO_LOGPATH, SO_LOGPREFIX);
apxLogLevelSetW(NULL, SO_LOGLEVEL);
apxLogWrite(APXLOG_MARK_DEBUG "Procrun log initialized");
AplZeroMemory(&gStdwrap, sizeof(APX_STDWRAP));
gStdwrap.szStdErrFilename = SO_STDERROR;
gStdwrap.szStdOutFilename = SO_STDOUTPUT;
redirectStdStreams(&gStdwrap);
switch (lpCmdline->dwCmdIndex) {
case 1: /* Run Service as console application */
docmdDebugService(lpCmdline);
break;
case 2: /* Run Service */
docmdRunService(lpCmdline);
break;
case 3: /* Stop Service */
docmdStopService(lpCmdline);
break;
case 4: /* Update Service parameters */
docmdUpdateService(lpCmdline);
break;
case 5: /* Install Service */
docmdInstallService(lpCmdline);
break;
case 6: /* Delete Service */
docmdDeleteService(lpCmdline);
break;
default:
/* Unknow command option */
apxLogWrite(APXLOG_MARK_ERROR "Unknown command line option");
printUsage(lpCmdline);
break;
}
cleanup:
apxLogWrite(APXLOG_MARK_INFO "Procrun finished.");
if (lpCmdline)
apxCmdlineFree(lpCmdline);
apxLogClose(NULL);
apxHandleManagerDestroy();
cleanupStdStreams(&gStdwrap);
ExitProcess(0);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]