Piotr Caban : services: Added support for SERVICE_CONFIG_PRESHUTDOWN_INFO.
Alexandre Julliard
julliard at winehq.org
Wed Nov 30 14:19:21 CST 2011
Module: wine
Branch: master
Commit: b8704a4929a9325242ad1fa2f5791734d5e84a80
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b8704a4929a9325242ad1fa2f5791734d5e84a80
Author: Piotr Caban <piotr at codeweavers.com>
Date: Wed Nov 30 15:28:26 2011 +0100
services: Added support for SERVICE_CONFIG_PRESHUTDOWN_INFO.
---
include/wine/svcctl.idl | 5 +++++
programs/services/rpc.c | 20 ++++++++++++++++++++
programs/services/services.c | 8 +++++++-
programs/services/services.h | 1 +
4 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/include/wine/svcctl.idl b/include/wine/svcctl.idl
index 895ee2e..f261702 100644
--- a/include/wine/svcctl.idl
+++ b/include/wine/svcctl.idl
@@ -114,6 +114,10 @@ typedef struct _SERVICE_FAILURE_ACTIONSW {
[size_is(cActions)] SC_ACTION *lpsaActions;
} SERVICE_FAILURE_ACTIONSW,*LPSERVICE_FAILURE_ACTIONSW;
+typedef struct _SERVICE_PRESHUTDOWN_INFO {
+ DWORD dwPreshutdownTimeout;
+} SERVICE_PRESHUTDOWN_INFO,*LPSERVICE_PRESHUTDOWN_INFO;
+
#define SERVICE_CONFIG_DESCRIPTION 1
#define SERVICE_CONFIG_FAILURE_ACTIONS 2
#define SERVICE_CONFIG_DELAYED_AUTO_START_INFO 3
@@ -134,6 +138,7 @@ typedef [switch_type(DWORD)] union
{
[case (SERVICE_CONFIG_DESCRIPTION)] SERVICE_DESCRIPTIONW descr;
[case (SERVICE_CONFIG_FAILURE_ACTIONS)] SERVICE_FAILURE_ACTIONSW actions;
+ [case (SERVICE_CONFIG_PRESHUTDOWN_INFO)] SERVICE_PRESHUTDOWN_INFO preshutdown;
} SERVICE_CONFIG2W;
/* Compatible with Windows function 0x00 */
diff --git a/programs/services/rpc.c b/programs/services/rpc.c
index 2d853c0..66bd17b 100644
--- a/programs/services/rpc.c
+++ b/programs/services/rpc.c
@@ -737,6 +737,14 @@ DWORD __cdecl svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, DWORD level,
wine_dbgstr_w(config->actions.lpRebootMsg),
wine_dbgstr_w(config->actions.lpCommand) );
break;
+ case SERVICE_CONFIG_PRESHUTDOWN_INFO:
+ WINE_TRACE( "changing service %p preshutdown timeout to %d\n",
+ service, config->preshutdown.dwPreshutdownTimeout );
+ service_lock_exclusive( service->service_entry );
+ service->service_entry->preshutdown_timeout = config->preshutdown.dwPreshutdownTimeout;
+ save_service_config( service->service_entry );
+ service_unlock( service->service_entry );
+ break;
default:
WINE_FIXME("level %u not implemented\n", level);
err = ERROR_INVALID_LEVEL;
@@ -781,6 +789,18 @@ DWORD __cdecl svcctl_QueryServiceConfig2W( SC_RPC_HANDLE hService, DWORD level,
}
break;
+ case SERVICE_CONFIG_PRESHUTDOWN_INFO:
+ service_lock_shared(service->service_entry);
+
+ *needed = sizeof(SERVICE_PRESHUTDOWN_INFO);
+ if (size >= *needed)
+ ((LPSERVICE_PRESHUTDOWN_INFO)buffer)->dwPreshutdownTimeout =
+ service->service_entry->preshutdown_timeout;
+ else err = ERROR_INSUFFICIENT_BUFFER;
+
+ service_unlock(service->service_entry);
+ break;
+
default:
WINE_FIXME("level %u not implemented\n", level);
err = ERROR_INVALID_LEVEL;
diff --git a/programs/services/services.c b/programs/services/services.c
index 94b4747..ba6b697 100644
--- a/programs/services/services.c
+++ b/programs/services/services.c
@@ -41,6 +41,7 @@ struct scmdatabase *active_database;
DWORD service_pipe_timeout = 10000;
DWORD service_kill_timeout = 20000;
+static DWORD default_preshutdown_timeout = 180000;
static void *env = NULL;
static const int is_win64 = (sizeof(void *) > sizeof(int));
@@ -64,6 +65,7 @@ static const WCHAR SZ_DEPEND_ON_GROUP[] = {'D','e','p','e','n','d','O','n','G'
static const WCHAR SZ_OBJECT_NAME[] = {'O','b','j','e','c','t','N','a','m','e',0};
static const WCHAR SZ_TAG[] = {'T','a','g',0};
static const WCHAR SZ_DESCRIPTION[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
+static const WCHAR SZ_PRESHUTDOWN[] = {'P','r','e','s','h','u','t','d','o','w','n','T','i','m','e','o','u','t',0};
DWORD service_create(LPCWSTR name, struct service_entry **entry)
@@ -80,6 +82,7 @@ DWORD service_create(LPCWSTR name, struct service_entry **entry)
(*entry)->control_pipe = INVALID_HANDLE_VALUE;
(*entry)->status.dwCurrentState = SERVICE_STOPPED;
(*entry)->status.dwWin32ExitCode = ERROR_SERVICE_NEVER_STARTED;
+ (*entry)->preshutdown_timeout = default_preshutdown_timeout;
/* all other fields are zero */
return ERROR_SUCCESS;
}
@@ -130,6 +133,8 @@ static DWORD load_service_config(HKEY hKey, struct service_entry *entry)
return err;
if ((err = load_reg_dword(hKey, SZ_TAG, &entry->config.dwTagId)) != 0)
return err;
+ if ((err = load_reg_dword(hKey, SZ_PRESHUTDOWN, &entry->preshutdown_timeout)) != 0)
+ return err;
WINE_TRACE("Image path = %s\n", wine_dbgstr_w(entry->config.lpBinaryPathName) );
WINE_TRACE("Group = %s\n", wine_dbgstr_w(entry->config.lpLoadOrderGroup) );
@@ -206,9 +211,10 @@ DWORD save_service_config(struct service_entry *entry)
goto cleanup;
if ((err = RegSetValueExW(hKey, SZ_ERROR, 0, REG_DWORD, (LPBYTE)&entry->config.dwErrorControl, sizeof(DWORD))) != 0)
goto cleanup;
-
if ((err = RegSetValueExW(hKey, SZ_TYPE, 0, REG_DWORD, (LPBYTE)&entry->config.dwServiceType, sizeof(DWORD))) != 0)
goto cleanup;
+ if ((err = RegSetValueExW(hKey, SZ_PRESHUTDOWN, 0, REG_DWORD, (LPBYTE)&entry->preshutdown_timeout, sizeof(DWORD))) != 0)
+ goto cleanup;
if (entry->config.dwTagId)
err = RegSetValueExW(hKey, SZ_TAG, 0, REG_DWORD, (LPBYTE)&entry->config.dwTagId, sizeof(DWORD));
diff --git a/programs/services/services.h b/programs/services/services.h
index 448ddfa..d5fcf77 100644
--- a/programs/services/services.h
+++ b/programs/services/services.h
@@ -39,6 +39,7 @@ struct service_entry
LPWSTR name;
SERVICE_STATUS_PROCESS status;
QUERY_SERVICE_CONFIGW config;
+ DWORD preshutdown_timeout;
LPWSTR description;
LPWSTR dependOnServices;
LPWSTR dependOnGroups;
More information about the wine-cvs
mailing list