You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ma...@apache.org on 2019/06/13 10:07:46 UTC
[commons-daemon] 05/05: Fix
https://issues.apache.org/jira/browse/DAEMON-303
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-daemon.git
commit 840e29005da54f82ba7ca49332bfe67bbd6b9dd0
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Jun 13 11:06:43 2019 +0100
Fix https://issues.apache.org/jira/browse/DAEMON-303
Add an option to configure the service to start using the "Automatic
(Delayed Start)" mode.
---
src/changes/changes.xml | 6 +++-
src/native/windows/apps/prunmgr/prunmgr.c | 32 ++++++++++++-----
src/native/windows/apps/prunsrv/prunsrv.c | 9 ++++-
src/native/windows/include/service.h | 4 ++-
src/native/windows/src/service.c | 58 ++++++++++++++++++++++++++-----
src/site/xdoc/procrun.xml | 2 +-
6 files changed, 89 insertions(+), 22 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 19d0720..40c11e1 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -38,7 +38,7 @@
<title>Apache Commons Daemon Release Notes</title>
</properties>
<body>
- <release version="1.1.1" date="TBD" description="Bug fix release">
+ <release version="1.1.1" date="TBD" description="Feature and bug fix release">
<action type="fix" dev="markt" due-to="mturk" >
Procrun. Add to OPT_LFLAGS rather than overwrite OPT_LFLAGS when setting
/OPT:REF in the make file for Windows.
@@ -122,6 +122,10 @@
JNI to create the JVM as a workaround for startup error messages not
being visible on stdout or stderr.
</action>
+ <action issue="DAEMON-303" type="add" dev="markt">
+ Procrun. Add an option to configure the service to use the 'Automatic
+ (Delayed Start)' startup mode.
+ </action>
</release>
<release version="1.1.0" date="2017-11-15" description="Feature and bug fix release">
<action issue="DAEMON-368" type="add" dev="ggregory">
diff --git a/src/native/windows/apps/prunmgr/prunmgr.c b/src/native/windows/apps/prunmgr/prunmgr.c
index 0b520c6..afae8c7 100644
--- a/src/native/windows/apps/prunmgr/prunmgr.c
+++ b/src/native/windows/apps/prunmgr/prunmgr.c
@@ -51,6 +51,7 @@ LPAPXGUISTORE _gui_store = NULL;
#define LOGL_INFO L"Info"
#define LOGL_WARN L"Warn"
+#define START_DELAYED L"Automatic (Delayed Start)"
#define START_AUTO L"Automatic"
#define START_MANUAL L"Manual"
#define START_DISABLED L"Disabled"
@@ -298,6 +299,8 @@ BOOL __generalPropertySave(HWND hDlg)
WCHAR szN[SIZ_RESLEN];
WCHAR szD[SIZ_DESLEN];
DWORD dwStartType = SERVICE_NO_CHANGE;
+ BOOL bDelayedStart = FALSE;
+
int i;
if (!(TST_BIT_FLAG(_propertyChanged, 1)))
@@ -309,14 +312,18 @@ BOOL __generalPropertySave(HWND hDlg)
GetDlgItemTextW(hDlg, IDC_PPSGDISP, szN, SIZ_RESMAX);
GetDlgItemTextW(hDlg, IDC_PPSGDESC, szD, SIZ_DESMAX);
i = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_PPSGCMBST));
- if (i == 0)
+ if (i == 0) {
dwStartType = SERVICE_AUTO_START;
+ bDelayedStart = TRUE;
+ }
else if (i == 1)
- dwStartType = SERVICE_DEMAND_START;
+ dwStartType = SERVICE_AUTO_START;
else if (i == 2)
+ dwStartType = SERVICE_DEMAND_START;
+ else if (i == 3)
dwStartType = SERVICE_DISABLED;
apxServiceSetNames(hService, NULL, szN, szD, NULL, NULL);
- apxServiceSetOptions(hService, SERVICE_NO_CHANGE, dwStartType, SERVICE_NO_CHANGE);
+ apxServiceSetOptions(hService, SERVICE_NO_CHANGE, dwStartType, bDelayedStart, SERVICE_NO_CHANGE);
if (!(TST_BIT_FLAG(_propertyChanged, 2)))
PostMessage(_gui_store->hMainWnd, WM_COMMAND, MAKEWPARAM(IDMS_REFRESH, 0), 0);
@@ -355,12 +362,12 @@ BOOL __generalLogonSave(HWND hDlg)
if (IsDlgButtonChecked(hDlg, IDC_PPSLID) == BST_CHECKED) {
apxServiceSetOptions(hService,
_currentEntry->stServiceStatus.dwServiceType | SERVICE_INTERACTIVE_PROCESS,
- SERVICE_NO_CHANGE, SERVICE_NO_CHANGE);
+ SERVICE_NO_CHANGE, FALSE, SERVICE_NO_CHANGE);
}
else {
apxServiceSetOptions(hService,
_currentEntry->stServiceStatus.dwServiceType & ~SERVICE_INTERACTIVE_PROCESS,
- SERVICE_NO_CHANGE, SERVICE_NO_CHANGE);
+ SERVICE_NO_CHANGE, FALSE, SERVICE_NO_CHANGE);
}
} else {
if (szP[0] != L' ' && szC[0] != L' ' && !lstrcmpW(szP, szC)) {
@@ -607,15 +614,22 @@ LRESULT CALLBACK __generalProperty(HWND hDlg,
SendMessage(GetDlgItem(hDlg, IDC_PPSGDISP), EM_LIMITTEXT, SIZ_RESMAX, 0);
SendMessage(GetDlgItem(hDlg, IDC_PPSGDESC), EM_LIMITTEXT, SIZ_DESMAX, 0);
+ ComboBox_AddStringW(GetDlgItem(hDlg, IDC_PPSGCMBST), START_DELAYED);
ComboBox_AddStringW(GetDlgItem(hDlg, IDC_PPSGCMBST), START_AUTO);
ComboBox_AddStringW(GetDlgItem(hDlg, IDC_PPSGCMBST), START_MANUAL);
ComboBox_AddStringW(GetDlgItem(hDlg, IDC_PPSGCMBST), START_DISABLED);
- if (_currentEntry->lpConfig->dwStartType == SERVICE_AUTO_START)
- ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_PPSGCMBST), 0);
+ if (_currentEntry->lpConfig->dwStartType == SERVICE_AUTO_START) {
+ if (_currentEntry->bDelayedStart) {
+ ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_PPSGCMBST), 0);
+ }
+ else {
+ ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_PPSGCMBST), 1);
+ }
+ }
else if (_currentEntry->lpConfig->dwStartType == SERVICE_DEMAND_START)
- ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_PPSGCMBST), 1);
- else if (_currentEntry->lpConfig->dwStartType == SERVICE_DISABLED)
ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_PPSGCMBST), 2);
+ else if (_currentEntry->lpConfig->dwStartType == SERVICE_DISABLED)
+ ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_PPSGCMBST), 3);
SetDlgItemTextW(hDlg, IDC_PPSGNAME, _currentEntry->szServiceName);
SetDlgItemTextW(hDlg, IDC_PPSGDISP, _currentEntry->lpConfig->lpDisplayName);
diff --git a/src/native/windows/apps/prunsrv/prunsrv.c b/src/native/windows/apps/prunsrv/prunsrv.c
index dab90e5..cf1ef48 100644
--- a/src/native/windows/apps/prunsrv/prunsrv.c
+++ b/src/native/windows/apps/prunsrv/prunsrv.c
@@ -64,6 +64,7 @@ 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";
@@ -834,6 +835,7 @@ static BOOL docmdUpdateService(LPAPXCMDLINE lpCmdline)
}
else {
DWORD dwStart = SERVICE_NO_CHANGE;
+ BOOL bDelayedStart = FALSE;
DWORD dwType = SERVICE_NO_CHANGE;
LPCWSTR su = NULL;
LPCWSTR sp = NULL;
@@ -855,7 +857,11 @@ static BOOL docmdUpdateService(LPAPXCMDLINE lpCmdline)
sp));
/* Update the --Startup mode */
if (ST_STARTUP & APXCMDOPT_FOUND) {
- if (!lstrcmpiW(SO_STARTUP, PRSRV_AUTO))
+ 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;
@@ -867,6 +873,7 @@ static BOOL docmdUpdateService(LPAPXCMDLINE lpCmdline)
rv = (rv && apxServiceSetOptions(hService,
dwType,
dwStart,
+ bDelayedStart,
SERVICE_NO_CHANGE));
apxLogWrite(APXLOG_MARK_INFO "Service '%S' updated",
diff --git a/src/native/windows/include/service.h b/src/native/windows/include/service.h
index faebef4..8da60f4 100644
--- a/src/native/windows/include/service.h
+++ b/src/native/windows/include/service.h
@@ -24,6 +24,7 @@ typedef struct APXSERVENTRY {
WCHAR szObjectName[SIZ_RESLEN];
WCHAR szServiceDescription[SIZ_DESLEN];
LPQUERY_SERVICE_CONFIGW lpConfig;
+ BOOL bDelayedStart;
SERVICE_STATUS stServiceStatus;
SERVICE_STATUS_PROCESS stStatusProcess;
@@ -41,7 +42,8 @@ BOOL apxServiceSetNames(APXHANDLE hService, LPCWSTR szImagePath,
LPCWSTR szUsername, LPCWSTR szPassword);
BOOL apxServiceSetOptions(APXHANDLE hService, DWORD dwServiceType,
- DWORD dwStartType, DWORD dwErrorControl);
+ DWORD dwStartType, BOOL bDelayedStart,
+ DWORD dwErrorControl);
BOOL apxServiceControl(APXHANDLE hService, DWORD dwControl, UINT uMsg,
LPAPXFNCALLBACK fnControlCallback,
diff --git a/src/native/windows/src/service.c b/src/native/windows/src/service.c
index 1fcc1c3..6317d58 100644
--- a/src/native/windows/src/service.c
+++ b/src/native/windows/src/service.c
@@ -107,6 +107,7 @@ apxServiceOpen(APXHANDLE hService, LPCWSTR szServiceName, DWORD dwOptions)
{
LPAPXSERVICE lpService;
DWORD dwNeeded;
+ LPSERVICE_DELAYED_AUTO_START_INFO lpDelayedInfo;
if (hService->dwType != APXHANDLE_TYPE_SERVICE)
return FALSE;
@@ -157,11 +158,36 @@ apxServiceOpen(APXHANDLE hService, LPCWSTR szServiceName, DWORD dwOptions)
apxLogWrite(APXLOG_MARK_SYSERR);
}
}
- lpService->stServiceEntry.lpConfig = (LPQUERY_SERVICE_CONFIGW)apxPoolAlloc(hService->hPool,
- dwNeeded);
- return QueryServiceConfigW(lpService->hService,
- lpService->stServiceEntry.lpConfig,
- dwNeeded, &dwNeeded);
+ lpService->stServiceEntry.lpConfig = (LPQUERY_SERVICE_CONFIGW)apxPoolAlloc(hService->hPool,
+ dwNeeded);
+ if (!QueryServiceConfigW(lpService->hService,
+ lpService->stServiceEntry.lpConfig,
+ dwNeeded, &dwNeeded)) {
+ return FALSE;
+ }
+
+ if (!QueryServiceConfig2W(lpService->hService, SERVICE_CONFIG_DELAYED_AUTO_START_INFO,
+ NULL, 0, &dwNeeded)) {
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ // This is expected. The call is expected to fail with the required
+ // buffer size set in dwNeeded.
+ // Clear the last error to prevent it being logged if a genuine
+ // error occurs
+ SetLastError(ERROR_SUCCESS);
+ } else {
+ apxLogWrite(APXLOG_MARK_SYSERR);
+ }
+ }
+ lpDelayedInfo = (LPSERVICE_DELAYED_AUTO_START_INFO) apxPoolAlloc(hService->hPool, dwNeeded);
+
+ if (!QueryServiceConfig2W(lpService->hService, SERVICE_CONFIG_DELAYED_AUTO_START_INFO,
+ (LPBYTE) lpDelayedInfo, dwNeeded, &dwNeeded)) {
+ return FALSE;
+ }
+
+ lpService->stServiceEntry.bDelayedStart = lpDelayedInfo->fDelayedAutostart;
+ apxFree(lpDelayedInfo);
+ return TRUE;
}
LPAPXSERVENTRY
@@ -240,9 +266,11 @@ BOOL
apxServiceSetOptions(APXHANDLE hService,
DWORD dwServiceType,
DWORD dwStartType,
+ BOOL bDelayedStart,
DWORD dwErrorControl)
{
LPAPXSERVICE lpService;
+ SERVICE_DELAYED_AUTO_START_INFO sDelayedInfo;
if (hService->dwType != APXHANDLE_TYPE_SERVICE)
return FALSE;
@@ -254,10 +282,22 @@ apxServiceSetOptions(APXHANDLE hService,
/* Check if the ServixeOpen has been called */
if (IS_INVALID_HANDLE(lpService->hService))
return FALSE;
- return ChangeServiceConfig(lpService->hService, dwServiceType,
- dwStartType, dwErrorControl,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL);
+
+ if (!ChangeServiceConfig(lpService->hService, dwServiceType,
+ dwStartType, dwErrorControl,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL)) {
+ return FALSE;
+ }
+
+ if (dwStartType == SERVICE_AUTO_START) {
+ sDelayedInfo.fDelayedAutostart = bDelayedStart;
+ return ChangeServiceConfig2A(lpService->hService,
+ SERVICE_CONFIG_DELAYED_AUTO_START_INFO,
+ &sDelayedInfo);
+ }
+
+ return TRUE;
}
static BOOL
diff --git a/src/site/xdoc/procrun.xml b/src/site/xdoc/procrun.xml
index 5838b24..9a49b81 100644
--- a/src/site/xdoc/procrun.xml
+++ b/src/site/xdoc/procrun.xml
@@ -312,7 +312,7 @@ will add the new value(s) to any existing value(s).
<tr>
<td>--Startup</td>
<td>manual</td>
- <td>Service startup mode can be either <b>auto</b> or <b>manual</b></td>
+ <td>Service startup mode can be either <b>delayed</b>, <b>auto</b> or <b>manual</b></td>
</tr>
<tr>
<td>--Type</td>