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