Revert r18735 and add the missing definition to svcctl.idl.
[reactos.git] / reactos / lib / advapi32 / service / scm.c
index 566ead1..36a9285 100644 (file)
@@ -12,7 +12,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include "advapi32.h"
+#include <advapi32.h>
 #include "svcctl_c.h"
 
 #define NDEBUG
@@ -106,26 +106,68 @@ ChangeServiceConfigA(
 /**********************************************************************
  *  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;
 }
 
 
@@ -194,6 +236,25 @@ ControlService(SC_HANDLE        hService,
 }
 
 
+/**********************************************************************
+ *  ControlServiceEx
+ *
+ * @unimplemented
+ */
+BOOL STDCALL
+ControlServiceEx(IN SC_HANDLE hService,
+                 IN DWORD dwControl,
+                 IN DWORD dwInfoLevel,
+                 IN OUT PVOID pControlParams)
+{
+    DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
+            hService, dwControl, dwInfoLevel, pControlParams);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+
+
 /**********************************************************************
  *  CreateServiceA
  *
@@ -224,27 +285,74 @@ CreateServiceA(
 /**********************************************************************
  *  CreateServiceW
  *
- * @unimplemented
+ * @implemented
  */
-SC_HANDLE
-STDCALL
-CreateServiceW(
-    SC_HANDLE   hSCManager,
-    LPCWSTR     lpServiceName,
-    LPCWSTR     lpDisplayName,
-    DWORD       dwDesiredAccess,
-    DWORD       dwServiceType,
-    DWORD       dwStartType,
-    DWORD       dwErrorControl,
-    LPCWSTR     lpBinaryPathName,
-    LPCWSTR     lpLoadOrderGroup,
-    LPDWORD     lpdwTagId,
-    LPCWSTR     lpDependencies,
-    LPCWSTR     lpServiceStartName,
-    LPCWSTR     lpPassword)
+SC_HANDLE STDCALL
+CreateServiceW(SC_HANDLE hSCManager,
+               LPCWSTR lpServiceName,
+               LPCWSTR lpDisplayName,
+               DWORD dwDesiredAccess,
+               DWORD dwServiceType,
+               DWORD dwStartType,
+               DWORD dwErrorControl,
+               LPCWSTR lpBinaryPathName,
+               LPCWSTR lpLoadOrderGroup,
+               LPDWORD lpdwTagId,
+               LPCWSTR lpDependencies,
+               LPCWSTR lpServiceStartName,
+               LPCWSTR lpPassword)
 {
-    DPRINT1("CreateServiceW is unimplemented, but returning INVALID_HANDLE_VALUE instead of NULL\n");
-    return INVALID_HANDLE_VALUE;
+    SC_HANDLE hService = NULL;
+    DWORD dwError;
+    DWORD dwDependenciesLength = 0;
+    DWORD dwLength;
+    LPWSTR lpStr;
+
+    DPRINT1("CreateServiceW() 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 = ScmrCreateServiceW(BindingHandle,
+                                 (unsigned int)hSCManager,
+                                 (LPWSTR)lpServiceName,
+                                 (LPWSTR)lpDisplayName,
+                                 dwDesiredAccess,
+                                 dwServiceType,
+                                 dwStartType,
+                                 dwErrorControl,
+                                 (LPWSTR)lpBinaryPathName,
+                                 (LPWSTR)lpLoadOrderGroup,
+                                 lpdwTagId,
+                                 (LPWSTR)lpDependencies,
+                                 dwDependenciesLength,
+                                 (LPWSTR)lpServiceStartName,
+                                 NULL,              /* FIXME: lpPassword */
+                                 0,                 /* FIXME: dwPasswordLength */
+                                 (unsigned int *)&hService);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return INVALID_HANDLE_VALUE;
+    }
+
+    return hService;
 }
 
 
@@ -928,7 +1036,7 @@ UnlockServiceDatabase(SC_LOCK ScLock)
 {
   DWORD dwError;
 
-  DPRINT("UnlockServiceDatabase(%x)\n", hSCManager);
+  DPRINT("UnlockServiceDatabase(%x)\n", ScLock);
 
   HandleBind();
 
@@ -946,11 +1054,40 @@ UnlockServiceDatabase(SC_LOCK ScLock)
 }
 
 
+/**********************************************************************
+ *  NotifyBootConfigStatus
+ *
+ * @implemented
+ */
+BOOL STDCALL
+NotifyBootConfigStatus(BOOL BootAcceptable)
+{
+    DWORD dwError;
+
+    DPRINT1("NotifyBootConfigStatus()\n");
+
+    HandleBind();
+
+    /* Call to services.exe using RPC */
+    dwError = ScmrNotifyBootConfigStatus(BindingHandle,
+                                         BootAcceptable);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+
 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
 {
   return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
 }
 
+
 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
 {
   HeapFree(GetProcessHeap(), 0, ptr);