Alexandre Julliard : advapi32: Reimplemented ChangeServiceConfig2W in services.exe.

Alexandre Julliard julliard at winehq.org
Fri Nov 28 07:16:26 CST 2008


Module: wine
Branch: master
Commit: 3249b40f70d73241f35bc948b31a9d56d656f316
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3249b40f70d73241f35bc948b31a9d56d656f316

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Nov 26 14:35:30 2008 +0100

advapi32: Reimplemented ChangeServiceConfig2W in services.exe.

---

 dlls/advapi32/service.c |   31 +++++++++++++------------------
 include/wine/svcctl.idl |   18 ++++++++++++++++--
 programs/services/rpc.c |   44 +++++++++++++++++++++++++++++++++++++-------
 3 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c
index da2b81f..0724035 100644
--- a/dlls/advapi32/service.c
+++ b/dlls/advapi32/service.c
@@ -2112,8 +2112,8 @@ BOOL WINAPI ChangeServiceConfig2A( SC_HANDLE hService, DWORD dwInfoLevel,
 BOOL WINAPI ChangeServiceConfig2W( SC_HANDLE hService, DWORD dwInfoLevel, 
     LPVOID lpInfo)
 {
-    HKEY hKey;
     struct sc_service *hsvc;
+    DWORD err;
 
     hsvc = sc_handle_get_handle_data(hService, SC_HTYPE_SERVICE);
     if (!hsvc)
@@ -2121,26 +2121,21 @@ BOOL WINAPI ChangeServiceConfig2W( SC_HANDLE hService, DWORD dwInfoLevel,
         SetLastError( ERROR_INVALID_HANDLE );
         return FALSE;
     }
-    hKey = hsvc->hkey;
 
-    if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
+    __TRY
     {
-        static const WCHAR szDescription[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
-        LPSERVICE_DESCRIPTIONW sd = (LPSERVICE_DESCRIPTIONW)lpInfo;
-        if (sd->lpDescription)
-        {
-            TRACE("Setting Description to %s\n",debugstr_w(sd->lpDescription));
-            if (sd->lpDescription[0] == 0)
-                RegDeleteValueW(hKey,szDescription);
-            else
-                RegSetValueExW(hKey, szDescription, 0, REG_SZ,
-                                        (LPVOID)sd->lpDescription,
-                                 sizeof(WCHAR)*(strlenW(sd->lpDescription)+1));
-        }
+        err = svcctl_ChangeServiceConfig2W( hsvc->hdr.server_handle, dwInfoLevel, lpInfo );
     }
-    else   
-        FIXME("STUB: %p %d %p\n",hService, dwInfoLevel, lpInfo);
-    return TRUE;
+    __EXCEPT(rpc_filter)
+    {
+        err = map_exception_code(GetExceptionCode());
+    }
+    __ENDTRY
+
+    if (err != ERROR_SUCCESS)
+        SetLastError(err);
+
+    return err == ERROR_SUCCESS;
 }
 
 /******************************************************************************
diff --git a/include/wine/svcctl.idl b/include/wine/svcctl.idl
index 7e5a0a6..66abd30 100644
--- a/include/wine/svcctl.idl
+++ b/include/wine/svcctl.idl
@@ -89,8 +89,19 @@ typedef struct _SERVICE_STATUS {
 typedef enum _SC_STATUS_TYPE {
   SC_STATUS_PROCESS_INFO      = 0
 } SC_STATUS_TYPE;
+
+typedef struct _SERVICE_DESCRIPTIONW {
+   LPWSTR lpDescription;
+} SERVICE_DESCRIPTIONW,*LPSERVICE_DESCRIPTIONW;
+
+#define SERVICE_CONFIG_DESCRIPTION 1
+
 cpp_quote("#endif")
 
+typedef [switch_type(DWORD)] union
+{
+  [case (SERVICE_CONFIG_DESCRIPTION)] SERVICE_DESCRIPTIONW descr;
+} SERVICE_CONFIG2W;
 
     /* Compatible with Windows function 0x00 */
     DWORD svcctl_CloseServiceHandle(
@@ -276,8 +287,11 @@ cpp_quote("#endif")
     /* Not compatible with Windows function 0x24 */
     DWORD svcctl_ChangeServiceConfig2A(/* FIXME */);
 
-    /* Not compatible with Windows function 0x25 */
-    DWORD svcctl_ChangeServiceConfig2W(/* FIXME */);
+    /* Untested with Windows function 0x25 */
+    DWORD svcctl_ChangeServiceConfig2W(
+        [in] SC_RPC_HANDLE hService,
+        [in] DWORD InfoLevel,
+        [in,switch_is(InfoLevel)] SERVICE_CONFIG2W *config );
 
     /* Not compatible with Windows function 0x26 */
     DWORD svcctl_QueryServiceConfig2A(/* FIXME */);
diff --git a/programs/services/rpc.c b/programs/services/rpc.c
index 6cc2e4a..b6ca9f2 100644
--- a/programs/services/rpc.c
+++ b/programs/services/rpc.c
@@ -609,6 +609,43 @@ DWORD svcctl_SetServiceStatus(
     return ERROR_SUCCESS;
 }
 
+DWORD svcctl_ChangeServiceConfig2W( SC_RPC_HANDLE hService, DWORD level, SERVICE_CONFIG2W *config )
+{
+    struct sc_service_handle *service;
+    DWORD err;
+
+    if ((err = validate_service_handle(hService, SERVICE_CHANGE_CONFIG, &service)) != 0)
+        return err;
+
+    switch (level)
+    {
+    case SERVICE_CONFIG_DESCRIPTION:
+        {
+            WCHAR *descr = NULL;
+
+            if (config->descr.lpDescription[0])
+            {
+                if (!(descr = strdupW( config->descr.lpDescription )))
+                    return ERROR_NOT_ENOUGH_MEMORY;
+            }
+
+            WINE_TRACE( "changing service %p descr to %s\n", service, wine_dbgstr_w(descr) );
+            service_lock_exclusive( service->service_entry );
+            HeapFree( GetProcessHeap(), 0, service->service_entry->description );
+            service->service_entry->description = descr;
+            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;
+        break;
+    }
+    return err;
+}
+
 DWORD svcctl_QueryServiceStatusEx(
     SC_RPC_HANDLE hService,
     SC_STATUS_TYPE InfoLevel,
@@ -1097,13 +1134,6 @@ DWORD svcctl_ChangeServiceConfig2A(
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
-DWORD svcctl_ChangeServiceConfig2W(
-    void)
-{
-    WINE_FIXME("\n");
-    return ERROR_CALL_NOT_IMPLEMENTED;
-}
-
 DWORD svcctl_QueryServiceConfig2A(
     void)
 {




More information about the wine-cvs mailing list