EnumDependentServicesA/W and EnumServicesStatusA/W don't fix up pointers if the servi...
[reactos.git] / reactos / dll / win32 / advapi32 / service / scm.c
index 82fcfc8..111bd0a 100644 (file)
 
 #include <advapi32.h>
 
-#define NDEBUG
-#include <debug.h>
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(advapi);
+
 
 /* FUNCTIONS *****************************************************************/
 
 handle_t BindingHandle = NULL;
 
-static VOID
+VOID
 HandleBind(VOID)
 {
     LPWSTR pszStringBinding;
@@ -38,7 +40,7 @@ HandleBind(VOID)
                                       &pszStringBinding);
     if (status)
     {
-        DPRINT1("RpcStringBindingCompose returned 0x%x\n", status);
+        TRACE("RpcStringBindingCompose returned 0x%x\n", status);
         return;
     }
 
@@ -47,13 +49,13 @@ HandleBind(VOID)
                                           &BindingHandle);
     if (status)
     {
-        DPRINT1("RpcBindingFromStringBinding returned 0x%x\n", status);
+        TRACE("RpcBindingFromStringBinding returned 0x%x\n", status);
     }
 
     status = RpcStringFreeW(&pszStringBinding);
     if (status)
     {
-        DPRINT1("RpcStringFree returned 0x%x\n", status);
+        TRACE("RpcStringFree returned 0x%x\n", status);
     }
 }
 
@@ -70,12 +72,32 @@ HandleUnbind(VOID)
     status = RpcBindingFree(&BindingHandle);
     if (status)
     {
-        DPRINT1("RpcBindingFree returned 0x%x\n", status);
+        TRACE("RpcBindingFree returned 0x%x\n", status);
     }
 }
 #endif
 
 
+DWORD
+ScmRpcStatusToWinError(RPC_STATUS Status)
+{
+    switch (Status)
+    {
+        case RPC_X_SS_IN_NULL_CONTEXT:
+            return ERROR_INVALID_HANDLE;
+
+        case RPC_X_NULL_REF_POINTER:
+            return ERROR_INVALID_PARAMETER;
+
+        case STATUS_ACCESS_VIOLATION:
+            return ERROR_INVALID_ADDRESS;
+
+        default:
+            return (DWORD)Status;
+    }
+}
+
+
 /**********************************************************************
  *  ChangeServiceConfig2A
  *
@@ -86,24 +108,25 @@ ChangeServiceConfig2A(SC_HANDLE hService,
                       DWORD dwInfoLevel,
                       LPVOID lpInfo)
 {
-    DWORD lpInfoSize;
+    SC_RPC_CONFIG_INFOA Info;
     DWORD dwError;
 
-    DPRINT("ChangeServiceConfig2A() called\n");
+    TRACE("ChangeServiceConfig2A() called\n");
 
-    /* Determine the length of the lpInfo parameter */
+    /* Fill relevent field of the Info structure */
+    Info.dwInfoLevel = dwInfoLevel;
     switch (dwInfoLevel)
     {
         case SERVICE_CONFIG_DESCRIPTION:
-            lpInfoSize = sizeof(SERVICE_DESCRIPTIONA);
+            Info.psd = (LPSERVICE_DESCRIPTIONA)&lpInfo;
             break;
 
         case SERVICE_CONFIG_FAILURE_ACTIONS:
-            lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONSA);
+            Info.psfa = (LPSERVICE_FAILURE_ACTIONSA)&lpInfo;
             break;
 
         default:
-            DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
+            WARN("Unknown info level 0x%lx\n", dwInfoLevel);
             SetLastError(ERROR_INVALID_PARAMETER);
             return FALSE;
     }
@@ -113,14 +136,21 @@ ChangeServiceConfig2A(SC_HANDLE hService,
 
     HandleBind();
 
-    dwError = ScmrChangeServiceConfig2A(BindingHandle,
-                                        (unsigned int)hService,
-                                        dwInfoLevel,
-                                        lpInfo,
-                                        lpInfoSize);
+    _SEH_TRY
+    {
+        dwError = RChangeServiceConfig2A(BindingHandle,
+                                         (SC_RPC_HANDLE)hService,
+                                         Info);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrChangeServiceConfig2A() failed (Error %lu)\n", dwError);
+        ERR("RChangeServiceConfig2A() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -139,24 +169,27 @@ ChangeServiceConfig2W(SC_HANDLE hService,
                       DWORD dwInfoLevel,
                       LPVOID lpInfo)
 {
-    DWORD lpInfoSize;
+    SC_RPC_CONFIG_INFOW Info;
     DWORD dwError;
 
-    DPRINT("ChangeServiceConfig2W() called\n");
+    TRACE("ChangeServiceConfig2W() called\n");
 
-    /* Determine the length of the lpInfo parameter */
+    /* Fill relevent field of the Info structure */
+    Info.dwInfoLevel = dwInfoLevel;
     switch (dwInfoLevel)
     {
         case SERVICE_CONFIG_DESCRIPTION:
-            lpInfoSize = sizeof(SERVICE_DESCRIPTIONW);
+        {
+            Info.psd = (LPSERVICE_DESCRIPTIONW)&lpInfo;
             break;
+        }
 
         case SERVICE_CONFIG_FAILURE_ACTIONS:
-            lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONSW);
+            Info.psfa = (LPSERVICE_FAILURE_ACTIONSW)&lpInfo;
             break;
 
         default:
-            DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
+            WARN("Unknown info level 0x%lx\n", dwInfoLevel);
             SetLastError(ERROR_INVALID_PARAMETER);
             return FALSE;
     }
@@ -166,14 +199,21 @@ ChangeServiceConfig2W(SC_HANDLE hService,
 
     HandleBind();
 
-    dwError = ScmrChangeServiceConfig2W(BindingHandle,
-                                        (unsigned int)hService,
-                                        dwInfoLevel,
-                                        lpInfo,
-                                        lpInfoSize);
+    _SEH_TRY
+    {
+        dwError = RChangeServiceConfig2W(BindingHandle,
+                                         (SC_RPC_HANDLE)hService,
+                                         Info);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrChangeServiceConfig2W() failed (Error %lu)\n", dwError);
+        ERR("RChangeServiceConfig2W() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -205,7 +245,7 @@ ChangeServiceConfigA(SC_HANDLE hService,
     DWORD dwLength;
     LPSTR lpStr;
 
-    DPRINT("ChangeServiceConfigA() called\n");
+    TRACE("ChangeServiceConfigA() called\n");
 
     /* Calculate the Dependencies length*/
     if (lpDependencies != NULL)
@@ -224,24 +264,33 @@ ChangeServiceConfigA(SC_HANDLE hService,
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrChangeServiceConfigA(BindingHandle,
-                                       (unsigned int)hService,
-                                       dwServiceType,
-                                       dwStartType,
-                                       dwErrorControl,
-                                       (LPSTR)lpBinaryPathName,
-                                       (LPSTR)lpLoadOrderGroup,
-                                       lpdwTagId,
-                                       (LPSTR)lpDependencies,
-                                       dwDependenciesLength,
-                                       (LPSTR)lpServiceStartName,
-                                       NULL,              /* FIXME: lpPassword */
-                                       0,                 /* FIXME: dwPasswordLength */
-                                       (LPSTR)lpDisplayName);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RChangeServiceConfigA(BindingHandle,
+                                        (SC_RPC_HANDLE)hService,
+                                        dwServiceType,
+                                        dwStartType,
+                                        dwErrorControl,
+                                        (LPSTR)lpBinaryPathName,
+                                        (LPSTR)lpLoadOrderGroup,
+                                        lpdwTagId,
+                                        (LPSTR)lpDependencies,
+                                        dwDependenciesLength,
+                                        (LPSTR)lpServiceStartName,
+                                        NULL,              /* FIXME: lpPassword */
+                                        0,                 /* FIXME: dwPasswordLength */
+                                        (LPSTR)lpDisplayName);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrChangeServiceConfigA() failed (Error %lu)\n", dwError);
+        ERR("RChangeServiceConfigA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -273,7 +322,7 @@ ChangeServiceConfigW(SC_HANDLE hService,
     DWORD dwLength;
     LPWSTR lpStr;
 
-    DPRINT("ChangeServiceConfigW() called\n");
+    TRACE("ChangeServiceConfigW() called\n");
 
     /* Calculate the Dependencies length*/
     if (lpDependencies != NULL)
@@ -292,24 +341,33 @@ ChangeServiceConfigW(SC_HANDLE hService,
 
     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);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RChangeServiceConfigW(BindingHandle,
+                                        (SC_RPC_HANDLE)hService,
+                                        dwServiceType,
+                                        dwStartType,
+                                        dwErrorControl,
+                                        (LPWSTR)lpBinaryPathName,
+                                        (LPWSTR)lpLoadOrderGroup,
+                                        lpdwTagId,
+                                        (LPBYTE)lpDependencies,
+                                        dwDependenciesLength,
+                                        (LPWSTR)lpServiceStartName,
+                                        NULL,              /* FIXME: lpPassword */
+                                        0,                 /* FIXME: dwPasswordLength */
+                                        (LPWSTR)lpDisplayName);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError);
+        ERR("RChangeServiceConfigW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -328,21 +386,30 @@ CloseServiceHandle(SC_HANDLE hSCObject)
 {
     DWORD dwError;
 
-    DPRINT("CloseServiceHandle() called\n");
+    TRACE("CloseServiceHandle() called\n");
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrCloseServiceHandle(BindingHandle,
-                                     (unsigned int)hSCObject);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RCloseServiceHandle(BindingHandle,
+                                      (LPSC_RPC_HANDLE)&hSCObject);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError)
     {
-        DPRINT1("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError);
+        ERR("RCloseServiceHandle() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    DPRINT("CloseServiceHandle() done\n");
+    TRACE("CloseServiceHandle() done\n");
 
     return TRUE;
 }
@@ -360,24 +427,33 @@ ControlService(SC_HANDLE hService,
 {
     DWORD dwError;
 
-    DPRINT("ControlService(%x, %x, %p)\n",
+    TRACE("ControlService(%x, %x, %p)\n",
            hService, dwControl, lpServiceStatus);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrControlService(BindingHandle,
-                                 (unsigned int)hService,
-                                 dwControl,
-                                 lpServiceStatus);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RControlService(BindingHandle,
+                                  (SC_RPC_HANDLE)hService,
+                                  dwControl,
+                                  lpServiceStatus);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrControlService() failed (Error %lu)\n", dwError);
+        ERR("RControlService() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    DPRINT("ControlService() done\n");
+    TRACE("ControlService() done\n");
 
     return TRUE;
 }
@@ -394,14 +470,13 @@ ControlServiceEx(IN SC_HANDLE hService,
                  IN DWORD dwInfoLevel,
                  IN OUT PVOID pControlParams)
 {
-    DPRINT1("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
+    FIXME("ControlServiceEx(0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
             hService, dwControl, dwInfoLevel, pControlParams);
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
 
 
-
 /**********************************************************************
  *  CreateServiceA
  *
@@ -468,7 +543,7 @@ CreateServiceA(SC_HANDLE hSCManager,
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
             goto cleanup;
         }
-        MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpBinaryPathNameW, len);
+        MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
     }
 
     if (lpLoadOrderGroup)
@@ -500,13 +575,13 @@ CreateServiceA(SC_HANDLE hSCManager,
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
             goto cleanup;
         }
-        MultiByteToWideChar(CP_ACP, 0, lpDependencies, -1, lpDependenciesW, dwDependenciesLength);
+        MultiByteToWideChar(CP_ACP, 0, lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
     }
 
     if (lpServiceStartName)
     {
         len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
-        lpServiceStartName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        lpServiceStartNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
         if (!lpServiceStartNameW)
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -593,7 +668,7 @@ CreateServiceW(SC_HANDLE hSCManager,
     DWORD dwLength;
     LPWSTR lpStr;
 
-    DPRINT("CreateServiceW() called\n");
+    TRACE("CreateServiceW() called\n");
 
     /* Calculate the Dependencies length*/
     if (lpDependencies != NULL)
@@ -606,33 +681,44 @@ CreateServiceW(SC_HANDLE hSCManager,
             lpStr = lpStr + dwLength;
         }
         dwDependenciesLength++;
+
+        dwDependenciesLength *= sizeof(WCHAR);
     }
 
     /* 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);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RCreateServiceW(BindingHandle,
+                                  (SC_RPC_HANDLE)hSCManager,
+                                  (LPWSTR)lpServiceName,
+                                  (LPWSTR)lpDisplayName,
+                                  dwDesiredAccess,
+                                  dwServiceType,
+                                  dwStartType,
+                                  dwErrorControl,
+                                  (LPWSTR)lpBinaryPathName,
+                                  (LPWSTR)lpLoadOrderGroup,
+                                  lpdwTagId,
+                                  (LPBYTE)lpDependencies,
+                                  dwDependenciesLength,
+                                  (LPWSTR)lpServiceStartName,
+                                  NULL,              /* FIXME: lpPassword */
+                                  0,                 /* FIXME: dwPasswordLength */
+                                  (SC_RPC_HANDLE *)&hService);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT("ScmrCreateServiceW() failed (Error %lu)\n", dwError);
+        ERR("RCreateServiceW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
@@ -651,16 +737,25 @@ DeleteService(SC_HANDLE hService)
 {
     DWORD dwError;
 
-    DPRINT("DeleteService(%x)\n", hService);
+    TRACE("DeleteService(%x)\n", hService);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrDeleteService(BindingHandle,
-                                (unsigned int)hService);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RDeleteService(BindingHandle,
+                                 (SC_RPC_HANDLE)hService);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrDeleteService() failed (Error %lu)\n", dwError);
+        ERR("RDeleteService() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -683,20 +778,35 @@ EnumDependentServicesA(SC_HANDLE hService,
                        LPDWORD lpServicesReturned)
 {
     LPENUM_SERVICE_STATUSA lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
-    DPRINT("EnumServicesStatusA() called\n");
+    TRACE("EnumServicesStatusA() called\n");
 
     HandleBind();
 
-    dwError = ScmrEnumDependentServicesA(BindingHandle,
-                                         (unsigned int)hService,
-                                         dwServiceState,
-                                         (unsigned char *)lpServices,
-                                         cbBufSize,
-                                         pcbBytesNeeded,
-                                         lpServicesReturned);
+    _SEH_TRY
+    {
+        dwError = REnumDependentServicesA(BindingHandle,
+                                          (SC_RPC_HANDLE)hService,
+                                          dwServiceState,
+                                          (LPBYTE)lpServices,
+                                          cbBufSize,
+                                          pcbBytesNeeded,
+                                          lpServicesReturned);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
+    if (dwError != ERROR_SUCCESS)
+    {
+        ERR("REnumDependentServicesA() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
 
     lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
     for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
@@ -712,14 +822,7 @@ EnumDependentServicesA(SC_HANDLE hService,
         lpStatusPtr++;
     }
 
-    if (dwError != ERROR_SUCCESS)
-    {
-        DPRINT("ScmrEnumDependentServicesA() failed (Error %lu)\n", dwError);
-        SetLastError(dwError);
-        return FALSE;
-    }
-
-    DPRINT("EnumDependentServicesA() done\n");
+    TRACE("EnumDependentServicesA() done\n");
 
     return TRUE;
 }
@@ -739,20 +842,35 @@ EnumDependentServicesW(SC_HANDLE hService,
                        LPDWORD lpServicesReturned)
 {
     LPENUM_SERVICE_STATUSW lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
-    DPRINT("EnumServicesStatusW() called\n");
+    TRACE("EnumServicesStatusW() called\n");
 
     HandleBind();
 
-    dwError = ScmrEnumDependentServicesW(BindingHandle,
-                                         (unsigned int)hService,
-                                         dwServiceState,
-                                         (unsigned char *)lpServices,
-                                         cbBufSize,
-                                         pcbBytesNeeded,
-                                         lpServicesReturned);
+    _SEH_TRY
+    {
+        dwError = REnumDependentServicesW(BindingHandle,
+                                          (SC_RPC_HANDLE)hService,
+                                          dwServiceState,
+                                          (LPBYTE)lpServices,
+                                          cbBufSize,
+                                          pcbBytesNeeded,
+                                          lpServicesReturned);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
+    if (dwError != ERROR_SUCCESS)
+    {
+        ERR("REnumDependentServicesW() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
 
     lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
     for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
@@ -768,14 +886,7 @@ EnumDependentServicesW(SC_HANDLE hService,
         lpStatusPtr++;
     }
 
-    if (dwError != ERROR_SUCCESS)
-    {
-        DPRINT("ScmrEnumDependentServicesW() failed (Error %lu)\n", dwError);
-        SetLastError(dwError);
-        return FALSE;
-    }
-
-    DPRINT("EnumDependentServicesW() done\n");
+    TRACE("EnumDependentServicesW() done\n");
 
     return TRUE;
 }
@@ -799,7 +910,7 @@ EnumServiceGroupW(
     LPDWORD                 lpResumeHandle,
     LPCWSTR                 lpGroup)
 {
-    DPRINT1("EnumServiceGroupW is unimplemented\n");
+    FIXME("EnumServiceGroupW is unimplemented\n");
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return FALSE;
 }
@@ -821,22 +932,37 @@ EnumServicesStatusA(SC_HANDLE hSCManager,
                     LPDWORD lpResumeHandle)
 {
     LPENUM_SERVICE_STATUSA lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
-    DPRINT("EnumServicesStatusA() called\n");
+    TRACE("EnumServicesStatusA() called\n");
 
     HandleBind();
 
-    dwError = ScmrEnumServicesStatusA(BindingHandle,
-                                      (unsigned int)hSCManager,
-                                      dwServiceType,
-                                      dwServiceState,
-                                      (unsigned char *)lpServices,
-                                      cbBufSize,
-                                      pcbBytesNeeded,
-                                      lpServicesReturned,
-                                      lpResumeHandle);
+    _SEH_TRY
+    {
+        dwError = REnumServicesStatusA(BindingHandle,
+                                       (SC_RPC_HANDLE)hSCManager,
+                                       dwServiceType,
+                                       dwServiceState,
+                                       (LPBYTE)lpServices,
+                                       cbBufSize,
+                                       pcbBytesNeeded,
+                                       lpServicesReturned,
+                                       lpResumeHandle);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
+    if (dwError != ERROR_SUCCESS)
+    {
+        ERR("REnumServicesStatusA() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
 
     lpStatusPtr = (LPENUM_SERVICE_STATUSA)lpServices;
     for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
@@ -852,14 +978,7 @@ EnumServicesStatusA(SC_HANDLE hSCManager,
         lpStatusPtr++;
     }
 
-    if (dwError != ERROR_SUCCESS)
-    {
-        DPRINT("ScmrEnumServicesStatusA() failed (Error %lu)\n", dwError);
-        SetLastError(dwError);
-        return FALSE;
-    }
-
-    DPRINT("EnumServicesStatusA() done\n");
+    TRACE("EnumServicesStatusA() done\n");
 
     return TRUE;
 }
@@ -881,22 +1000,37 @@ EnumServicesStatusW(SC_HANDLE hSCManager,
                     LPDWORD lpResumeHandle)
 {
     LPENUM_SERVICE_STATUSW lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
-    DPRINT("EnumServicesStatusW() called\n");
+    TRACE("EnumServicesStatusW() called\n");
 
     HandleBind();
 
-    dwError = ScmrEnumServicesStatusW(BindingHandle,
-                                      (unsigned int)hSCManager,
-                                      dwServiceType,
-                                      dwServiceState,
-                                      (unsigned char *)lpServices,
-                                      cbBufSize,
-                                      pcbBytesNeeded,
-                                      lpServicesReturned,
-                                      lpResumeHandle);
+    _SEH_TRY
+    {
+        dwError = REnumServicesStatusW(BindingHandle,
+                                       (SC_RPC_HANDLE)hSCManager,
+                                       dwServiceType,
+                                       dwServiceState,
+                                       (LPBYTE)lpServices,
+                                       cbBufSize,
+                                       pcbBytesNeeded,
+                                       lpServicesReturned,
+                                       lpResumeHandle);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
+    if (dwError != ERROR_SUCCESS)
+    {
+        ERR("REnumServicesStatusW() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return FALSE;
+    }
 
     lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
     for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
@@ -912,14 +1046,7 @@ EnumServicesStatusW(SC_HANDLE hSCManager,
         lpStatusPtr++;
     }
 
-    if (dwError != ERROR_SUCCESS)
-    {
-        DPRINT("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError);
-        SetLastError(dwError);
-        return FALSE;
-    }
-
-    DPRINT("EnumServicesStatusW() done\n");
+    TRACE("EnumServicesStatusW() done\n");
 
     return TRUE;
 }
@@ -943,47 +1070,63 @@ EnumServicesStatusExA(SC_HANDLE hSCManager,
                       LPCSTR pszGroupName)
 {
     LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
-    DPRINT("EnumServicesStatusExA() called\n");
+    TRACE("EnumServicesStatusExA() called\n");
 
     HandleBind();
 
-    dwError = ScmrEnumServicesStatusExA(BindingHandle,
-                                        (unsigned int)hSCManager,
-                                        (unsigned long)InfoLevel,
-                                        dwServiceType,
-                                        dwServiceState,
-                                        (unsigned char *)lpServices,
-                                        cbBufSize,
-                                        pcbBytesNeeded,
-                                        lpServicesReturned,
-                                        lpResumeHandle,
-                                        (char *)pszGroupName);
+    _SEH_TRY
+    {
+        dwError = REnumServicesStatusExA(BindingHandle,
+                                         (SC_RPC_HANDLE)hSCManager,
+                                         InfoLevel,
+                                         dwServiceType,
+                                         dwServiceState,
+                                         (LPBYTE)lpServices,
+                                         cbBufSize,
+                                         pcbBytesNeeded,
+                                         lpServicesReturned,
+                                         lpResumeHandle,
+                                         (LPSTR)pszGroupName);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
 
-    lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices;
-    for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
+    if (dwError == ERROR_MORE_DATA)
     {
-        if (lpStatusPtr->lpServiceName)
-            lpStatusPtr->lpServiceName =
-                (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
+        WARN("Required buffer size %ul\n", *pcbBytesNeeded);
+        SetLastError(dwError);
+        return FALSE;
+    }
+    else if (dwError == ERROR_SUCCESS)
+    {
+        lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSA)lpServices;
+        for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
+        {
+            if (lpStatusPtr->lpServiceName)
+                lpStatusPtr->lpServiceName =
+                    (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
 
-        if (lpStatusPtr->lpDisplayName)
-            lpStatusPtr->lpDisplayName =
-                (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
+            if (lpStatusPtr->lpDisplayName)
+                lpStatusPtr->lpDisplayName =
+                    (LPSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
 
-        lpStatusPtr++;
+            lpStatusPtr++;
+        }
     }
-
-    if (dwError != ERROR_SUCCESS)
+    else
     {
-        DPRINT1("ScmrEnumServicesStatusExA() failed (Error %lu)\n", dwError);
+        ERR("REnumServicesStatusExA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    DPRINT("EnumServicesStatusExA() done\n");
+    TRACE("EnumServicesStatusExA() done\n");
 
     return TRUE;
 }
@@ -1007,48 +1150,63 @@ EnumServicesStatusExW(SC_HANDLE hSCManager,
                       LPCWSTR pszGroupName)
 {
     LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
-    DPRINT("EnumServicesStatusExW() called\n");
+    TRACE("EnumServicesStatusExW() called\n");
 
     HandleBind();
 
-    dwError = ScmrEnumServicesStatusExW(BindingHandle,
-                                        (unsigned int)hSCManager,
-                                        (unsigned long)InfoLevel,
-                                        dwServiceType,
-                                        dwServiceState,
-                                        (unsigned char *)lpServices,
-                                        cbBufSize,
-                                        pcbBytesNeeded,
-                                        lpServicesReturned,
-                                        lpResumeHandle,
-                                        (wchar_t *)pszGroupName);
+    _SEH_TRY
+    {
+        dwError = REnumServicesStatusExW(BindingHandle,
+                                         (SC_RPC_HANDLE)hSCManager,
+                                         InfoLevel,
+                                         dwServiceType,
+                                         dwServiceState,
+                                         (LPBYTE)lpServices,
+                                         cbBufSize,
+                                         pcbBytesNeeded,
+                                         lpServicesReturned,
+                                         lpResumeHandle,
+                                         (LPWSTR)pszGroupName);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
 
-    lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
-    for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
+    if (dwError == ERROR_MORE_DATA)
     {
-        if (lpStatusPtr->lpServiceName)
-            lpStatusPtr->lpServiceName =
-                (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
+        WARN("Required buffer size %ul\n", *pcbBytesNeeded);
+        SetLastError(dwError);
+        return FALSE;
+    }
+    else if (dwError == ERROR_SUCCESS)
+    {
+        lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
+        for (dwCount = 0; dwCount < *lpServicesReturned; dwCount++)
+        {
+            if (lpStatusPtr->lpServiceName)
+                lpStatusPtr->lpServiceName =
+                    (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpServiceName);
 
-        if (lpStatusPtr->lpDisplayName)
-            lpStatusPtr->lpDisplayName =
-                (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
+            if (lpStatusPtr->lpDisplayName)
+                lpStatusPtr->lpDisplayName =
+                    (LPWSTR)((ULONG_PTR)lpServices + (ULONG_PTR)lpStatusPtr->lpDisplayName);
 
-        lpStatusPtr++;
+            lpStatusPtr++;
+        }
     }
-
-    if (dwError != ERROR_SUCCESS &&
-        dwError != ERROR_MORE_DATA)
+    else
     {
-        DPRINT1("ScmrEnumServicesStatusExW() failed (Error %lu)\n", dwError);
+        ERR("REnumServicesStatusExW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    DPRINT("EnumServicesStatusExW() done\n");
+    TRACE("EnumServicesStatusExW() done\n");
 
     return TRUE;
 }
@@ -1067,24 +1225,37 @@ GetServiceDisplayNameA(SC_HANDLE hSCManager,
 {
     DWORD dwError;
 
-    DPRINT("GetServiceDisplayNameA() called\n");
+    TRACE("GetServiceDisplayNameA() called\n");
+
+    if (!lpDisplayName)
+        *lpcchBuffer = 0;
 
     HandleBind();
 
-    dwError = ScmrGetServiceDisplayNameA(BindingHandle,
-                                         (unsigned int)hSCManager,
-                                         (LPSTR)lpServiceName,
-                                         lpDisplayName,
-                                         lpcchBuffer);
+    _SEH_TRY
+    {
+        dwError = RGetServiceDisplayNameA(BindingHandle,
+                                          (SC_RPC_HANDLE)hSCManager,
+                                          (LPSTR)lpServiceName,
+                                          lpDisplayName,
+                                          lpcchBuffer);
+    }
+    _SEH_HANDLE
+    {
+        /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+
+
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
+        ERR("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    (*lpcchBuffer)--;
-
     return TRUE;
 }
 
@@ -1102,24 +1273,34 @@ GetServiceDisplayNameW(SC_HANDLE hSCManager,
 {
     DWORD dwError;
 
-    DPRINT("GetServiceDisplayNameW() called\n");
+    TRACE("GetServiceDisplayNameW() called\n");
+
+    if (!lpDisplayName)
+        *lpcchBuffer = 0;
 
     HandleBind();
 
-    dwError = ScmrGetServiceDisplayNameW(BindingHandle,
-                                         (unsigned int)hSCManager,
-                                         (LPWSTR)lpServiceName,
-                                         lpDisplayName,
-                                         lpcchBuffer);
+    _SEH_TRY
+    {
+        dwError = RGetServiceDisplayNameW(BindingHandle,
+                                          (SC_RPC_HANDLE)hSCManager,
+                                          (LPWSTR)lpServiceName,
+                                          lpDisplayName,
+                                          lpcchBuffer);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
+        ERR("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    (*lpcchBuffer)--;
-
     return TRUE;
 }
 
@@ -1137,24 +1318,34 @@ GetServiceKeyNameA(SC_HANDLE hSCManager,
 {
     DWORD dwError;
 
-    DPRINT("GetServiceKeyNameA() called\n");
+    TRACE("GetServiceKeyNameA() called\n");
+
+    if (!lpServiceName)
+        *lpcchBuffer = 0;
 
     HandleBind();
 
-    dwError = ScmrGetServiceKeyNameA(BindingHandle,
-                                     (unsigned int)hSCManager,
-                                     (LPSTR)lpDisplayName,
-                                     lpServiceName,
-                                     lpcchBuffer);
+    _SEH_TRY
+    {
+        dwError = RGetServiceKeyNameA(BindingHandle,
+                                      (SC_RPC_HANDLE)hSCManager,
+                                      (LPSTR)lpDisplayName,
+                                      lpServiceName,
+                                      lpcchBuffer);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrGetServiceKeyNameA() failed (Error %lu)\n", dwError);
+        ERR("RGetServiceKeyNameA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    (*lpcchBuffer)--;
-
     return TRUE;
 }
 
@@ -1172,24 +1363,34 @@ GetServiceKeyNameW(SC_HANDLE hSCManager,
 {
     DWORD dwError;
 
-    DPRINT("GetServiceKeyNameW() called\n");
+    TRACE("GetServiceKeyNameW() called\n");
+
+    if (!lpDisplayName)
+        *lpcchBuffer = 0;
 
     HandleBind();
 
-    dwError = ScmrGetServiceKeyNameW(BindingHandle,
-                                     (unsigned int)hSCManager,
-                                     (LPWSTR)lpDisplayName,
-                                     lpServiceName,
-                                     lpcchBuffer);
+    _SEH_TRY
+    {
+        dwError = RGetServiceKeyNameW(BindingHandle,
+                                      (SC_RPC_HANDLE)hSCManager,
+                                      (LPWSTR)lpDisplayName,
+                                      lpServiceName,
+                                      lpcchBuffer);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError);
+        ERR("RGetServiceKeyNameW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    (*lpcchBuffer)--;
-
     return TRUE;
 }
 
@@ -1205,22 +1406,31 @@ LockServiceDatabase(SC_HANDLE hSCManager)
     SC_LOCK hLock;
     DWORD dwError;
 
-    DPRINT("LockServiceDatabase(%x)\n", hSCManager);
+    TRACE("LockServiceDatabase(%x)\n", hSCManager);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrLockServiceDatabase(BindingHandle,
-                                      (unsigned int)hSCManager,
-                                      (unsigned int *)&hLock);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RLockServiceDatabase(BindingHandle,
+                                       (SC_RPC_HANDLE)hSCManager,
+                                       (SC_RPC_LOCK *)&hLock);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError);
+        ERR("RLockServiceDatabase() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
 
-    DPRINT("hLock = %p\n", hLock);
+    TRACE("hLock = %p\n", hLock);
 
     return hLock;
 }
@@ -1231,12 +1441,12 @@ WaitForSCManager(VOID)
 {
     HANDLE hEvent;
 
-    DPRINT("WaitForSCManager() called\n");
+    TRACE("WaitForSCManager() called\n");
 
     /* Try to open the existing event */
     hEvent = OpenEventW(SYNCHRONIZE,
                         FALSE,
-                        L"SvcctrlStartEvent_A3725DX");
+                        L"SvcctrlStartEvent_A3752DX");
     if (hEvent == NULL)
     {
         if (GetLastError() != ERROR_FILE_NOT_FOUND)
@@ -1246,13 +1456,13 @@ WaitForSCManager(VOID)
         hEvent = CreateEventW(NULL,
                               TRUE,
                               FALSE,
-                              L"SvcctrlStartEvent_A3725DX");
+                              L"SvcctrlStartEvent_A3752DX");
         if (hEvent == NULL)
         {
             /* Try to open the existing event again */
             hEvent = OpenEventW(SYNCHRONIZE,
                                 FALSE,
-                                L"SvcctrlStartEvent_A3725DX");
+                                L"SvcctrlStartEvent_A3752DX");
             if (hEvent == NULL)
                 return;
         }
@@ -1262,7 +1472,7 @@ WaitForSCManager(VOID)
     WaitForSingleObject(hEvent, 180000);
     CloseHandle(hEvent);
 
-    DPRINT("ScmWaitForSCManager() done\n");
+    TRACE("ScmWaitForSCManager() done\n");
 }
 
 
@@ -1279,27 +1489,36 @@ OpenSCManagerA(LPCSTR lpMachineName,
     SC_HANDLE hScm = NULL;
     DWORD dwError;
 
-    DPRINT("OpenSCManagerA(%s, %s, %lx)\n",
+    TRACE("OpenSCManagerA(%s, %s, %lx)\n",
            lpMachineName, lpDatabaseName, dwDesiredAccess);
 
     WaitForSCManager();
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrOpenSCManagerA(BindingHandle,
-                                 (LPSTR)lpMachineName,
-                                 (LPSTR)lpDatabaseName,
-                                 dwDesiredAccess,
-                                 (unsigned int*)&hScm);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = ROpenSCManagerA(BindingHandle,
+                                  (LPSTR)lpMachineName,
+                                  (LPSTR)lpDatabaseName,
+                                  dwDesiredAccess,
+                                  (SC_RPC_HANDLE *)&hScm);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError);
+        ERR("ROpenSCManagerA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
 
-    DPRINT("hScm = %p\n", hScm);
+    TRACE("hScm = %p\n", hScm);
 
     return hScm;
 }
@@ -1318,27 +1537,36 @@ OpenSCManagerW(LPCWSTR lpMachineName,
     SC_HANDLE hScm = NULL;
     DWORD dwError;
 
-    DPRINT("OpenSCManagerW(%S, %S, %lx)\n",
+    TRACE("OpenSCManagerW(%S, %S, %lx)\n",
            lpMachineName, lpDatabaseName, dwDesiredAccess);
 
     WaitForSCManager();
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrOpenSCManagerW(BindingHandle,
-                                 (LPWSTR)lpMachineName,
-                                 (LPWSTR)lpDatabaseName,
-                                 dwDesiredAccess,
-                                 (unsigned int*)&hScm);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = ROpenSCManagerW(BindingHandle,
+                                  (LPWSTR)lpMachineName,
+                                  (LPWSTR)lpDatabaseName,
+                                  dwDesiredAccess,
+                                  (SC_RPC_HANDLE *)&hScm);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError);
+        ERR("ROpenSCManagerW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
 
-    DPRINT("hScm = %p\n", hScm);
+    TRACE("hScm = %p\n", hScm);
 
     return hScm;
 }
@@ -1357,25 +1585,34 @@ OpenServiceA(SC_HANDLE hSCManager,
     SC_HANDLE hService = NULL;
     DWORD dwError;
 
-    DPRINT("OpenServiceA(%p, %s, %lx)\n",
+    TRACE("OpenServiceA(%p, %s, %lx)\n",
            hSCManager, lpServiceName, dwDesiredAccess);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrOpenServiceA(BindingHandle,
-                               (unsigned int)hSCManager,
-                               (LPSTR)lpServiceName,
-                               dwDesiredAccess,
-                               (unsigned int*)&hService);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = ROpenServiceA(BindingHandle,
+                                (SC_RPC_HANDLE)hSCManager,
+                                (LPSTR)lpServiceName,
+                                dwDesiredAccess,
+                                (SC_RPC_HANDLE *)&hService);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrOpenServiceA() failed (Error %lu)\n", dwError);
+        ERR("ROpenServiceA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
 
-    DPRINT("hService = %p\n", hService);
+    TRACE("hService = %p\n", hService);
 
     return hService;
 }
@@ -1394,25 +1631,37 @@ OpenServiceW(SC_HANDLE hSCManager,
     SC_HANDLE hService = NULL;
     DWORD dwError;
 
-    DPRINT("OpenServiceW(%p, %S, %lx)\n",
+    TRACE("OpenServiceW(%p, %S, %lx)\n",
            hSCManager, lpServiceName, dwDesiredAccess);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrOpenServiceW(BindingHandle,
-                               (unsigned int)hSCManager,
-                               (LPWSTR)lpServiceName,
-                               dwDesiredAccess,
-                               (unsigned int*)&hService);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = ROpenServiceW(BindingHandle,
+                                (SC_RPC_HANDLE)hSCManager,
+                                (LPWSTR)lpServiceName,
+                                dwDesiredAccess,
+                                (SC_RPC_HANDLE *)&hService);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT("ScmrOpenServiceW() failed (Error %lu)\n", dwError);
+        if (dwError == ERROR_SERVICE_DOES_NOT_EXIST)
+            WARN("ROpenServiceW() failed (Error %lu)\n", dwError);
+        else
+            ERR("ROpenServiceW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
 
-    DPRINT("hService = %p\n", hService);
+    TRACE("hService = %p\n", hService);
 
     return hService;
 }
@@ -1431,20 +1680,29 @@ QueryServiceConfigA(SC_HANDLE hService,
 {
     DWORD dwError;
 
-    DPRINT("QueryServiceConfigA(%p, %p, %lu, %p)\n",
+    TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
            hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceConfigA(BindingHandle,
-                                      (unsigned int)hService,
-                                      (unsigned char *)lpServiceConfig,
-                                      cbBufSize,
-                                      pcbBytesNeeded);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceConfigA(BindingHandle,
+                                       (SC_RPC_HANDLE)hService,
+                                       (LPBYTE)lpServiceConfig,
+                                       cbBufSize,
+                                       pcbBytesNeeded);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT("ScmrQueryServiceConfigA() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceConfigA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1475,7 +1733,7 @@ QueryServiceConfigA(SC_HANDLE hService,
            (LPSTR)((ULONG_PTR)lpServiceConfig +
                    (ULONG_PTR)lpServiceConfig->lpDisplayName);
 
-    DPRINT("QueryServiceConfigA() done\n");
+    TRACE("QueryServiceConfigA() done\n");
 
     return TRUE;
 }
@@ -1494,20 +1752,32 @@ QueryServiceConfigW(SC_HANDLE hService,
 {
     DWORD dwError;
 
-    DPRINT("QueryServiceConfigW(%p, %p, %lu, %p)\n",
+    TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
            hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceConfigW(BindingHandle,
-                                      (unsigned int)hService,
-                                      (unsigned char *)lpServiceConfig,
-                                      cbBufSize,
-                                      pcbBytesNeeded);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceConfigW(BindingHandle,
+                                       (SC_RPC_HANDLE)hService,
+                                       (LPBYTE)lpServiceConfig,
+                                       cbBufSize,
+                                       pcbBytesNeeded);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT("ScmrQueryServiceConfigW() failed (Error %lu)\n", dwError);
+        if (dwError == ERROR_INSUFFICIENT_BUFFER)
+            WARN("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
+        else
+            ERR("RQueryServiceConfigW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1538,7 +1808,7 @@ QueryServiceConfigW(SC_HANDLE hService,
            (LPWSTR)((ULONG_PTR)lpServiceConfig +
                     (ULONG_PTR)lpServiceConfig->lpDisplayName);
 
-    DPRINT("QueryServiceConfigW() done\n");
+    TRACE("QueryServiceConfigW() done\n");
 
     return TRUE;
 }
@@ -1558,21 +1828,44 @@ QueryServiceConfig2A(SC_HANDLE hService,
 {
     DWORD dwError;
 
-    DPRINT("QueryServiceConfig2A(%p, %lu, %p, %lu, %p)\n",
+    TRACE("QueryServiceConfig2A(%p, %lu, %p, %lu, %p)\n",
            hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
 
+    if (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
+        dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
+    {
+        SetLastError(ERROR_INVALID_LEVEL);
+        return FALSE;
+    }
+
+    if ((lpBuffer == NULL && cbBufSize != 0) ||
+        pcbBytesNeeded == NULL)
+    {
+        SetLastError(ERROR_INVALID_ADDRESS);
+        return FALSE;
+    }
+
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceConfig2A(BindingHandle,
-                                       (unsigned int)hService,
-                                       dwInfoLevel,
-                                       (unsigned char *)lpBuffer,
-                                       cbBufSize,
-                                       pcbBytesNeeded);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceConfig2A(BindingHandle,
+                                        (SC_RPC_HANDLE)hService,
+                                        dwInfoLevel,
+                                        lpBuffer,
+                                        cbBufSize,
+                                        pcbBytesNeeded);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT("ScmrQueryServiceConfig2A() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1608,12 +1901,12 @@ QueryServiceConfig2A(SC_HANDLE hService,
             break;
 
         default:
-            DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
+            ERR("Unknown info level 0x%lx\n", dwInfoLevel);
             SetLastError(ERROR_INVALID_PARAMETER);
             return FALSE;
     }
 
-    DPRINT("QueryServiceConfig2A() done\n");
+    TRACE("QueryServiceConfig2A() done\n");
 
     return TRUE;
 }
@@ -1633,21 +1926,44 @@ QueryServiceConfig2W(SC_HANDLE hService,
 {
     DWORD dwError;
 
-    DPRINT("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
+    TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
            hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
 
+    if (dwInfoLevel != SERVICE_CONFIG_DESCRIPTION &&
+        dwInfoLevel != SERVICE_CONFIG_FAILURE_ACTIONS)
+    {
+        SetLastError(ERROR_INVALID_LEVEL);
+        return FALSE;
+    }
+
+    if ((lpBuffer == NULL && cbBufSize != 0) ||
+        pcbBytesNeeded == NULL)
+    {
+        SetLastError(ERROR_INVALID_ADDRESS);
+        return FALSE;
+    }
+
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceConfig2W(BindingHandle,
-                                       (unsigned int)hService,
-                                       dwInfoLevel,
-                                       (unsigned char *)lpBuffer,
-                                       cbBufSize,
-                                       pcbBytesNeeded);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceConfig2W(BindingHandle,
+                                        (SC_RPC_HANDLE)hService,
+                                        dwInfoLevel,
+                                        lpBuffer,
+                                        cbBufSize,
+                                        pcbBytesNeeded);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT("ScmrQueryServiceConfig2W() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1683,12 +1999,12 @@ QueryServiceConfig2W(SC_HANDLE hService,
             break;
 
         default:
-            DPRINT1("Unknown info level 0x%lx\n", dwInfoLevel);
+            WARN("Unknown info level 0x%lx\n", dwInfoLevel);
             SetLastError(ERROR_INVALID_PARAMETER);
             return FALSE;
     }
 
-    DPRINT("QueryServiceConfig2W() done\n");
+    TRACE("QueryServiceConfig2W() done\n");
 
     return TRUE;
 }
@@ -1707,19 +2023,28 @@ QueryServiceLockStatusA(SC_HANDLE hSCManager,
 {
     DWORD dwError;
 
-    DPRINT("QueryServiceLockStatusA() called\n");
+    TRACE("QueryServiceLockStatusA() called\n");
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceLockStatusA(BindingHandle,
-                                          (unsigned int)hSCManager,
-                                          (unsigned char *)lpLockStatus,
-                                          cbBufSize,
-                                          pcbBytesNeeded);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceLockStatusA(BindingHandle,
+                                           (SC_RPC_HANDLE)hSCManager,
+                                           lpLockStatus,
+                                           cbBufSize,
+                                           pcbBytesNeeded);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT("ScmrQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1730,7 +2055,7 @@ QueryServiceLockStatusA(SC_HANDLE hSCManager,
             (LPSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
     }
 
-    DPRINT("QueryServiceLockStatusA() done\n");
+    TRACE("QueryServiceLockStatusA() done\n");
 
     return TRUE;
 }
@@ -1749,19 +2074,28 @@ QueryServiceLockStatusW(SC_HANDLE hSCManager,
 {
     DWORD dwError;
 
-    DPRINT("QueryServiceLockStatusW() called\n");
+    TRACE("QueryServiceLockStatusW() called\n");
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceLockStatusW(BindingHandle,
-                                          (unsigned int)hSCManager,
-                                          (unsigned char *)lpLockStatus,
-                                          cbBufSize,
-                                          pcbBytesNeeded);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceLockStatusW(BindingHandle,
+                                           (SC_RPC_HANDLE)hSCManager,
+                                           lpLockStatus,
+                                           cbBufSize,
+                                           pcbBytesNeeded);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT("ScmrQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1772,7 +2106,7 @@ QueryServiceLockStatusW(SC_HANDLE hSCManager,
             (LPWSTR)((UINT_PTR)lpLockStatus + (UINT_PTR)lpLockStatus->lpLockOwner);
     }
 
-    DPRINT("QueryServiceLockStatusW() done\n");
+    TRACE("QueryServiceLockStatusW() done\n");
 
     return TRUE;
 }
@@ -1792,21 +2126,30 @@ QueryServiceObjectSecurity(SC_HANDLE hService,
 {
     DWORD dwError;
 
-    DPRINT("QueryServiceObjectSecurity(%p, %lu, %p)\n",
+    TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
            hService, dwSecurityInformation, lpSecurityDescriptor);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceObjectSecurity(BindingHandle,
-                                             (unsigned int)hService,
-                                             dwSecurityInformation,
-                                             (unsigned char *)lpSecurityDescriptor,
-                                             cbBufSize,
-                                             pcbBytesNeeded);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceObjectSecurity(BindingHandle,
+                                              (SC_RPC_HANDLE)hService,
+                                              dwSecurityInformation,
+                                              (LPBYTE)lpSecurityDescriptor,
+                                              cbBufSize,
+                                              pcbBytesNeeded);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
+        ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1814,30 +2157,70 @@ QueryServiceObjectSecurity(SC_HANDLE hService,
     return TRUE;
 }
 
-
 /**********************************************************************
- *  QueryServiceStatus
+ *  SetServiceObjectSecurity
  *
  * @implemented
  */
 BOOL STDCALL
-QueryServiceStatus(SC_HANDLE hService,
-                   LPSERVICE_STATUS lpServiceStatus)
+SetServiceObjectSecurity(SC_HANDLE hService,
+                         SECURITY_INFORMATION dwSecurityInformation,
+                         PSECURITY_DESCRIPTOR lpSecurityDescriptor)
 {
+    PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
+    ULONG Length;
+    NTSTATUS Status;
     DWORD dwError;
 
-    DPRINT("QueryServiceStatus(%p, %p)\n",
-           hService, lpServiceStatus);
+    Length = 0;
+    Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
+                                   SelfRelativeSD,
+                                   &Length);
+    if (Status != STATUS_BUFFER_TOO_SMALL)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
+    if (SelfRelativeSD == NULL)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+
+    Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
+                                   SelfRelativeSD,
+                                   &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
+        SetLastError(RtlNtStatusToDosError(Status));
+        return FALSE;
+    }
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceStatus(BindingHandle,
-                                     (unsigned int)hService,
-                                     lpServiceStatus);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RSetServiceObjectSecurity(BindingHandle,
+                                            (SC_RPC_HANDLE)hService,
+                                            dwSecurityInformation,
+                                            (LPBYTE)SelfRelativeSD,
+                                            Length);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
+    HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
+        ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1847,33 +2230,37 @@ QueryServiceStatus(SC_HANDLE hService,
 
 
 /**********************************************************************
- *  QueryServiceStatusEx
+ *  QueryServiceStatus
  *
  * @implemented
  */
 BOOL STDCALL
-QueryServiceStatusEx(SC_HANDLE hService,
-                     SC_STATUS_TYPE InfoLevel,
-                     LPBYTE lpBuffer,
-                     DWORD cbBufSize,
-                     LPDWORD pcbBytesNeeded)
+QueryServiceStatus(SC_HANDLE hService,
+                   LPSERVICE_STATUS lpServiceStatus)
 {
     DWORD dwError;
 
-    DPRINT("QueryServiceStatusEx() called\n");
+    TRACE("QueryServiceStatus(%p, %p)\n",
+           hService, lpServiceStatus);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceStatusEx(BindingHandle,
-                                       (unsigned int)hService,
-                                       InfoLevel,
-                                       lpBuffer,
-                                       cbBufSize,
-                                       pcbBytesNeeded);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceStatus(BindingHandle,
+                                      (SC_RPC_HANDLE)hService,
+                                      lpServiceStatus);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1883,61 +2270,42 @@ QueryServiceStatusEx(SC_HANDLE hService,
 
 
 /**********************************************************************
- *  SetServiceObjectSecurity
+ *  QueryServiceStatusEx
  *
  * @implemented
  */
 BOOL STDCALL
-SetServiceObjectSecurity(SC_HANDLE hService,
-                         SECURITY_INFORMATION dwSecurityInformation,
-                         PSECURITY_DESCRIPTOR lpSecurityDescriptor)
+QueryServiceStatusEx(SC_HANDLE hService,
+                     SC_STATUS_TYPE InfoLevel,
+                     LPBYTE lpBuffer,
+                     DWORD cbBufSize,
+                     LPDWORD pcbBytesNeeded)
 {
-    PSECURITY_DESCRIPTOR SelfRelativeSD = NULL;
-    ULONG Length;
-    NTSTATUS Status;
     DWORD dwError;
 
-    Length = 0;
-    Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
-                                   SelfRelativeSD,
-                                   &Length);
-    if (Status != STATUS_BUFFER_TOO_SMALL)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
+    TRACE("QueryServiceStatusEx() called\n");
 
-    SelfRelativeSD = HeapAlloc(GetProcessHeap(), 0, Length);
-    if (SelfRelativeSD == NULL)
+    HandleBind();
+
+    _SEH_TRY
     {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceStatusEx(BindingHandle,
+                                        (SC_RPC_HANDLE)hService,
+                                        InfoLevel,
+                                        lpBuffer,
+                                        cbBufSize,
+                                        pcbBytesNeeded);
     }
-
-    Status = RtlMakeSelfRelativeSD(lpSecurityDescriptor,
-                                   SelfRelativeSD,
-                                   &Length);
-    if (!NT_SUCCESS(Status))
+    _SEH_HANDLE
     {
-        HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
-        SetLastError(RtlNtStatusToDosError(Status));
-        return FALSE;
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
     }
-
-    HandleBind();
-
-    /* Call to services.exe using RPC */
-    dwError = ScmrSetServiceObjectSecurity(BindingHandle,
-                                           (unsigned int)hService,
-                                           dwSecurityInformation,
-                                           (unsigned char *)SelfRelativeSD,
-                                           Length);
-
-    HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
+    _SEH_END;
 
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrServiceObjectSecurity() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1956,46 +2324,26 @@ StartServiceA(SC_HANDLE hService,
               DWORD dwNumServiceArgs,
               LPCSTR *lpServiceArgVectors)
 {
-    LPSTR lpBuffer;
-    LPSTR lpStr;
     DWORD dwError;
-    DWORD dwBufSize;
-    DWORD i;
 
-    dwBufSize = 0;
-    for (i = 0; i < dwNumServiceArgs; i++)
-    {
-        dwBufSize += (strlen(lpServiceArgVectors[i]) + 1);
-    }
-    dwBufSize++;
-    DPRINT1("dwBufSize: %lu\n", dwBufSize);
+    HandleBind();
 
-    lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize);
-    if (lpBuffer == NULL)
+    _SEH_TRY
     {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
+        dwError = RStartServiceA(BindingHandle,
+                                 (SC_RPC_HANDLE)hService,
+                                 dwNumServiceArgs,
+                                 (LPSTRING_PTRSA)lpServiceArgVectors);
     }
-
-    lpStr = lpBuffer;
-    for (i = 0; i < dwNumServiceArgs; i++)
+    _SEH_HANDLE
     {
-        strcpy(lpStr, lpServiceArgVectors[i]);
-        lpStr += (strlen(lpServiceArgVectors[i]) + 1);
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
     }
-    *lpStr = 0;
-
-    dwError = ScmrStartServiceA(BindingHandle,
-                                (unsigned int)hService,
-                                dwNumServiceArgs,
-                                (unsigned char *)lpBuffer,
-                                dwBufSize);
-
-    HeapFree(GetProcessHeap(), 0, lpBuffer);
+    _SEH_END;
 
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrStartServiceA() failed (Error %lu)\n", dwError);
+        ERR("RStartServiceA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -2014,46 +2362,26 @@ StartServiceW(SC_HANDLE hService,
               DWORD dwNumServiceArgs,
               LPCWSTR *lpServiceArgVectors)
 {
-    LPWSTR lpBuffer;
-    LPWSTR lpStr;
     DWORD dwError;
-    DWORD dwBufSize;
-    DWORD i;
 
-    dwBufSize = 0;
-    for (i = 0; i < dwNumServiceArgs; i++)
-    {
-        dwBufSize += ((wcslen(lpServiceArgVectors[i]) + 1) * sizeof(WCHAR));
-    }
-    dwBufSize += sizeof(WCHAR);
-    DPRINT("dwBufSize: %lu\n", dwBufSize);
+    HandleBind();
 
-    lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize);
-    if (lpBuffer == NULL)
+    _SEH_TRY
     {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
+        dwError = RStartServiceW(BindingHandle,
+                                 (SC_RPC_HANDLE)hService,
+                                 dwNumServiceArgs,
+                                 (LPSTRING_PTRSW)lpServiceArgVectors);
     }
-
-    lpStr = lpBuffer;
-    for (i = 0; i < dwNumServiceArgs; i++)
+    _SEH_HANDLE
     {
-        wcscpy(lpStr, lpServiceArgVectors[i]);
-        lpStr += (wcslen(lpServiceArgVectors[i]) + 1);
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
     }
-    *lpStr = 0;
-
-    dwError = ScmrStartServiceW(BindingHandle,
-                                (unsigned int)hService,
-                                dwNumServiceArgs,
-                                (unsigned char *)lpBuffer,
-                                dwBufSize);
-
-    HeapFree(GetProcessHeap(), 0, lpBuffer);
+    _SEH_END;
 
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrStartServiceW() failed (Error %lu)\n", dwError);
+        ERR("RStartServiceW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -2072,16 +2400,25 @@ UnlockServiceDatabase(SC_LOCK ScLock)
 {
     DWORD dwError;
 
-    DPRINT("UnlockServiceDatabase(%x)\n", ScLock);
+    TRACE("UnlockServiceDatabase(%x)\n", ScLock);
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrUnlockServiceDatabase(BindingHandle,
-                                        (unsigned int)ScLock);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RUnlockServiceDatabase(BindingHandle,
+                                         (SC_RPC_LOCK)ScLock);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError);
+        ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -2100,16 +2437,26 @@ NotifyBootConfigStatus(BOOL BootAcceptable)
 {
     DWORD dwError;
 
-    DPRINT1("NotifyBootConfigStatus()\n");
+    TRACE("NotifyBootConfigStatus()\n");
 
     HandleBind();
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrNotifyBootConfigStatus(BindingHandle,
-                                         BootAcceptable);
+    _SEH_TRY
+    {
+        /* Call to services.exe using RPC */
+        dwError = RNotifyBootConfigStatus(BindingHandle,
+                                          NULL,
+                                          BootAcceptable);
+    }
+    _SEH_HANDLE
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    _SEH_END;
+
     if (dwError != ERROR_SUCCESS)
     {
-        DPRINT1("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
+        ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -2117,16 +2464,4 @@ NotifyBootConfigStatus(BOOL BootAcceptable)
     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);
-}
-
 /* EOF */