- Implement ScmrChangeServiceConfigW stub.
- CreateServiceW calls ScmrCreateServiceW.
Modified: trunk/reactos/lib/advapi32/service/scm.c
Added: trunk/reactos/subsys/system/services/config.c
Modified: trunk/reactos/subsys/system/services/rpcserver.c
Modified: trunk/reactos/subsys/system/services/services.h
Modified: trunk/reactos/subsys/system/services/services.xml

Modified: trunk/reactos/lib/advapi32/service/scm.c
--- trunk/reactos/lib/advapi32/service/scm.c	2005-10-23 19:24:42 UTC (rev 18722)
+++ trunk/reactos/lib/advapi32/service/scm.c	2005-10-23 19:50:05 UTC (rev 18723)
@@ -106,26 +106,68 @@
 /**********************************************************************
  *  ChangeServiceConfigW
  *
- * @unimplemented
+ * @implemented
  */
-BOOL
-STDCALL
-ChangeServiceConfigW(
-    SC_HANDLE   hService,
-    DWORD       dwServiceType,
-    DWORD       dwStartType,
-    DWORD       dwErrorControl,
-    LPCWSTR     lpBinaryPathName,
-    LPCWSTR     lpLoadOrderGroup,
-    LPDWORD     lpdwTagId,
-    LPCWSTR     lpDependencies,
-    LPCWSTR     lpServiceStartName,
-    LPCWSTR     lpPassword,
-    LPCWSTR     lpDisplayName)
+BOOL STDCALL
+ChangeServiceConfigW(SC_HANDLE hService,
+                     DWORD dwServiceType,
+                     DWORD dwStartType,
+                     DWORD dwErrorControl,
+                     LPCWSTR lpBinaryPathName,
+                     LPCWSTR lpLoadOrderGroup,
+                     LPDWORD lpdwTagId,
+                     LPCWSTR lpDependencies,
+                     LPCWSTR lpServiceStartName,
+                     LPCWSTR lpPassword,
+                     LPCWSTR lpDisplayName)
 {
-    DPRINT1("ChangeServiceConfigW is unimplemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    DWORD dwError;
+    DWORD dwDependenciesLength = 0;
+    DWORD dwLength;
+    LPWSTR lpStr;
+
+    DPRINT1("ChangeServiceConfigW() called\n");
+
+    /* Calculate the Dependencies length*/
+    if (lpDependencies != NULL)
+    {
+        lpStr = (LPWSTR)lpDependencies;
+        while (*lpStr)
+        {
+            dwLength = wcslen(lpStr) + 1;
+            dwDependenciesLength += dwLength;
+            lpStr = lpStr + dwLength;
+        }
+        dwDependenciesLength++;
+    }
+
+    /* FIXME: Encrypt the password */
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrChangeServiceConfigW(BindingHandle,
+                                       (unsigned int)hService,
+                                       dwServiceType,
+                                       dwStartType,
+                                       dwErrorControl,
+                                       (LPWSTR)lpBinaryPathName,
+                                       (LPWSTR)lpLoadOrderGroup,
+                                       lpdwTagId,
+                                       (LPWSTR)lpDependencies,
+                                       dwDependenciesLength,
+                                       (LPWSTR)lpServiceStartName,
+                                       NULL,              /* FIXME: lpPassword */
+                                       0,                 /* FIXME: dwPasswordLength */
+                                       (LPWSTR)lpDisplayName);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 
@@ -243,7 +285,7 @@
 /**********************************************************************
  *  CreateServiceW
  *
- * @unimplemented
+ * @implemented
  */
 SC_HANDLE STDCALL
 CreateServiceW(SC_HANDLE hSCManager,
@@ -262,7 +304,6 @@
 {
     SC_HANDLE hService = NULL;
     DWORD dwError;
-    HKEY hEnumKey, hKey;
     DWORD dwDependenciesLength = 0;
     DWORD dwLength;
     LPWSTR lpStr;
@@ -284,7 +325,6 @@
 
     /* FIXME: Encrypt the password */
 
-#if 0
     HandleBind();
 
     /* Call to services.exe using RPC */
@@ -299,25 +339,12 @@
                                  (LPWSTR)lpBinaryPathName,
                                  (LPWSTR)lpLoadOrderGroup,
                                  lpdwTagId,
-                                 lpDependencies,
+                                 (LPWSTR)lpDependencies,
                                  dwDependenciesLength,
                                  (LPWSTR)lpServiceStartName,
                                  NULL,              /* FIXME: lpPassword */
                                  0,                 /* FIXME: dwPasswordLength */
                                  (unsigned int *)&hService);
-#else
-    RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, KEY_ENUMERATE_SUB_KEYS, &hEnumKey);
-    RegCreateKeyExW(hEnumKey, lpServiceName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL);
-    RegCloseKey(hEnumKey);
-    if (lpLoadOrderGroup)
-      RegSetValueExW(hKey, L"Group", 0, REG_SZ, (const BYTE*)lpLoadOrderGroup, (wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
-    RegSetValueExW(hKey, L"ImagePath", 0, REG_EXPAND_SZ, (const BYTE*)lpBinaryPathName, (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
-    RegSetValueExW(hKey, L"ErrorControl", 0, REG_DWORD, (const BYTE*)&dwErrorControl, sizeof(dwErrorControl));
-    RegSetValueExW(hKey, L"Start", 0, REG_DWORD, (const BYTE*)&dwStartType, sizeof(dwStartType));
-    RegSetValueExW(hKey, L"Type", 0, REG_DWORD, (const BYTE*)&dwStartType, sizeof(dwStartType));
-    RegCloseKey(hKey);
-    hService = INVALID_HANDLE_VALUE; dwError = ERROR_SUCCESS;
-#endif
     if (dwError != ERROR_SUCCESS)
     {
         DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError);

Added: trunk/reactos/subsys/system/services/config.c
--- trunk/reactos/subsys/system/services/config.c	2005-10-23 19:24:42 UTC (rev 18722)
+++ trunk/reactos/subsys/system/services/config.c	2005-10-23 19:50:05 UTC (rev 18723)
@@ -0,0 +1,103 @@
+/*
+ * config.c
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "services.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+DWORD
+ScmWriteDependencies(HKEY hServiceKey,
+                     LPWSTR lpDependencies,
+                     DWORD dwDependenciesLength)
+{
+    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwGroupLength = 0;
+    DWORD dwServiceLength = 0;
+    DWORD dwLength;
+    LPWSTR lpGroupDeps;
+    LPWSTR lpServiceDeps;
+    LPWSTR lpSrc;
+    LPWSTR lpDst;
+
+    if (*lpDependencies == 0)
+    {
+        RegDeleteValue(hServiceKey,
+                       L"DependOnService");
+        RegDeleteValue(hServiceKey,
+                       L"DependOnGroup");
+    }
+    else
+    {
+        lpGroupDeps = HeapAlloc(GetProcessHeap(),
+                                HEAP_ZERO_MEMORY,
+                                (dwDependenciesLength + 2) * sizeof(WCHAR));
+        if (lpGroupDeps == NULL)
+            return ERROR_NOT_ENOUGH_MEMORY;
+
+        lpSrc = lpDependencies;
+        lpDst = lpGroupDeps;
+        while (*lpSrc != 0)
+        {
+            dwLength = wcslen(lpSrc);
+            if (*lpSrc == SC_GROUP_IDENTIFIERW)
+            {
+                lpSrc++;
+                dwGroupLength += dwLength;
+                wcscpy(lpDst, lpSrc);
+                lpDst = lpDst + dwLength;
+            }
+
+            lpSrc = lpSrc + dwLength;
+        }
+        *lpDst = 0;
+        lpDst++;
+        dwGroupLength++;
+
+        lpSrc = lpDependencies;
+        lpServiceDeps = lpDst;
+        while (*lpSrc != 0)
+        {
+            dwLength = wcslen(lpSrc) + 1;
+            if (*lpSrc != SC_GROUP_IDENTIFIERW)
+            {
+                dwServiceLength += dwLength;
+                wcscpy(lpDst, lpSrc);
+                lpDst = lpDst + dwLength;
+            }
+
+            lpSrc = lpSrc + dwLength;
+        }
+        *lpDst = 0;
+        dwServiceLength++;
+
+        dwError = RegSetValueExW(hServiceKey,
+                                 L"DependOnGroup",
+                                 0,
+                                 REG_MULTI_SZ,
+                                 (LPBYTE)lpGroupDeps,
+                                 dwGroupLength * sizeof(WCHAR));
+
+        if (dwError == ERROR_SUCCESS)
+        {
+            dwError = RegSetValueExW(hServiceKey,
+                                     L"DependOnService",
+                                     0,
+                                     REG_MULTI_SZ,
+                                     (LPBYTE)lpServiceDeps,
+                                     dwServiceLength * sizeof(WCHAR));
+        }
+
+        HeapFree(GetProcessHeap(), 0, lpGroupDeps);
+    }
+
+    return dwError;
+}
+
+/* EOF */
+

Modified: trunk/reactos/subsys/system/services/rpcserver.c
--- trunk/reactos/subsys/system/services/rpcserver.c	2005-10-23 19:24:42 UTC (rev 18722)
+++ trunk/reactos/subsys/system/services/rpcserver.c	2005-10-23 19:50:05 UTC (rev 18723)
@@ -472,25 +472,32 @@
 
 
 /* Function 11 */
-#if 0
 unsigned long
-ScmrChangeServiceConfigW([in] handle_t BiningHandle,
-                         [in] SC_HANDLE hService,
-                         [in] DWORD dwServiceType,
-                         [in] DWORD dwStartType,
-                         [in] DWORD dwErrorControl,
-                         [in, string, unique] LPCWSTR lpBinaryPathName,
-                         [in, string, unique] LPCWSTR lpLoadOrderGroup,
-                         [in, out, unique] LPDWORD lpdwTagId,
-                         [in, size_is(dwDependenciesLength), unique] LPCWSTR lpDependencies,
-                         [in] DWORD dwDependenciesLength,
-                         [in, string, unique] LPCWSTR lpServiceStartName,
-                         [in, size_is(dwPasswordLength), unique] LPCWSTR lpPassword,
-                         [in] DWORD dwPasswordLength,
-                         [in, string, unique] LPCWSTR lpDisplayName)
+ScmrChangeServiceConfigW(handle_t BiningHandle,
+                         unsigned int hService,
+                         unsigned long dwServiceType,
+                         unsigned long dwStartType,
+                         unsigned long dwErrorControl,
+                         wchar_t *lpBinaryPathName,
+                         wchar_t *lpLoadOrderGroup,
+                         unsigned long *lpdwTagId, /* in, out, unique */
+                         wchar_t *lpDependencies,
+                         unsigned long dwDependenciesLength,
+                         wchar_t *lpServiceStartName,
+                         wchar_t *lpPassword,
+                         unsigned long dwPasswordLength,
+                         wchar_t *lpDisplayName)
 {
+    DPRINT1("ScmrChangeServiceConfigW() called\n");
+    DPRINT1("dwServiceType = %lu\n", dwServiceType);
+    DPRINT1("dwStartType = %lu\n", dwStartType);
+    DPRINT1("dwErrorControl = %lu\n", dwErrorControl);
+    DPRINT1("lpBinaryPathName = %S\n", lpBinaryPathName);
+    DPRINT1("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
+    DPRINT1("lpDisplayName = %S\n", lpDisplayName);
+
+    return ERROR_SUCCESS;
 }
-#endif
 
 
 static DWORD
@@ -710,9 +717,14 @@
         /* FIXME: Write tag */
     }
 
+    /* Write dependencies */
     if (lpDependencies != NULL && *lpDependencies != 0)
     {
-        /* FIXME: Write dependencies */
+        dwError = ScmWriteDependencies(hServiceKey,
+                                       lpDependencies,
+                                       dwDependenciesLength);
+        if (dwError != ERROR_SUCCESS)
+            goto done;
     }
 
     if (lpPassword != NULL)

Modified: trunk/reactos/subsys/system/services/services.h
--- trunk/reactos/subsys/system/services/services.h	2005-10-23 19:24:42 UTC (rev 18722)
+++ trunk/reactos/subsys/system/services/services.h	2005-10-23 19:50:05 UTC (rev 18723)
@@ -32,9 +32,11 @@
 } SERVICE, *PSERVICE;
 
 
-/* services.c */
+/* config.c */
 
-VOID PrintString(LPCSTR fmt, ...);
+DWORD ScmWriteDependencies(HKEY hServiceKey,
+                           LPWSTR lpDependencies,
+                           DWORD dwDependenciesLength);
 
 
 /* database.c */
@@ -54,5 +56,11 @@
 VOID ScmStartRpcServer(VOID);
 
 
+/* services.c */
+
+VOID PrintString(LPCSTR fmt, ...);
+
+
+
 /* EOF */
 

Modified: trunk/reactos/subsys/system/services/services.xml
--- trunk/reactos/subsys/system/services/services.xml	2005-10-23 19:24:42 UTC (rev 18722)
+++ trunk/reactos/subsys/system/services/services.xml	2005-10-23 19:50:05 UTC (rev 18723)
@@ -10,6 +10,7 @@
 	<library>user32</library>
 	<library>advapi32</library>
 	<library>rpcrt4</library>
+	<file>config.c</file>
 	<file>database.c</file>
 	<file>rpcserver.c</file>
 	<file>services.c</file>