- Implement RCreateServiceA.
[reactos.git] / reactos / dll / win32 / advapi32 / service / scm.c
index 1e62ced..9aa422c 100644 (file)
@@ -21,16 +21,124 @@ WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
 /* FUNCTIONS *****************************************************************/
 
-handle_t BindingHandle = NULL;
+handle_t __RPC_USER
+SVCCTL_HANDLEA_bind(SVCCTL_HANDLEA szMachineName)
+{
+    handle_t hBinding = NULL;
+    UCHAR *pszStringBinding;
+    RPC_STATUS status;
+
+    TRACE("SVCCTL_HANDLEA_bind() called\n");
+
+    status = RpcStringBindingComposeA(NULL,
+                                      (UCHAR *)"ncacn_np",
+                                      (UCHAR *)szMachineName,
+                                      (UCHAR *)"\\pipe\\ntsvcs",
+                                      NULL,
+                                      (UCHAR **)&pszStringBinding);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcStringBindingCompose returned 0x%x\n", status);
+        return NULL;
+    }
+
+    /* Set the binding handle that will be used to bind to the server. */
+    status = RpcBindingFromStringBindingA(pszStringBinding,
+                                          &hBinding);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
+    }
+
+    status = RpcStringFreeA(&pszStringBinding);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcStringFree returned 0x%x\n", status);
+    }
+
+    return hBinding;
+}
+
 
-VOID
-HandleBind(VOID)
+void __RPC_USER
+SVCCTL_HANDLEA_unbind(SVCCTL_HANDLEA szMachineName,
+                      handle_t hBinding)
 {
+    RPC_STATUS status;
+
+    TRACE("SVCCTL_HANDLEA_unbind() called\n");
+
+    status = RpcBindingFree(&hBinding);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcBindingFree returned 0x%x\n", status);
+    }
+}
+
+
+handle_t __RPC_USER
+SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW szMachineName)
+{
+    handle_t hBinding = NULL;
     LPWSTR pszStringBinding;
     RPC_STATUS status;
 
-    if (BindingHandle != NULL)
-        return;
+    TRACE("SVCCTL_HANDLEW_bind() called\n");
+
+    status = RpcStringBindingComposeW(NULL,
+                                      L"ncacn_np",
+                                      szMachineName,
+                                      L"\\pipe\\ntsvcs",
+                                      NULL,
+                                      &pszStringBinding);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcStringBindingCompose returned 0x%x\n", status);
+        return NULL;
+    }
+
+    /* Set the binding handle that will be used to bind to the server. */
+    status = RpcBindingFromStringBindingW(pszStringBinding,
+                                          &hBinding);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
+    }
+
+    status = RpcStringFreeW(&pszStringBinding);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcStringFree returned 0x%x\n", status);
+    }
+
+    return hBinding;
+}
+
+
+void __RPC_USER
+SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName,
+                      handle_t hBinding)
+{
+    RPC_STATUS status;
+
+    TRACE("SVCCTL_HANDLEW_unbind() called\n");
+
+    status = RpcBindingFree(&hBinding);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcBindingFree returned 0x%x\n", status);
+    }
+}
+
+
+handle_t __RPC_USER
+RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus)
+{
+    handle_t hBinding = NULL;
+    LPWSTR pszStringBinding;
+    RPC_STATUS status;
+
+    TRACE("RPC_SERVICE_STATUS_HANDLE_bind() called\n");
 
     status = RpcStringBindingComposeW(NULL,
                                       L"ncacn_np",
@@ -38,44 +146,66 @@ HandleBind(VOID)
                                       L"\\pipe\\ntsvcs",
                                       NULL,
                                       &pszStringBinding);
-    if (status)
+    if (status != RPC_S_OK)
     {
-        TRACE("RpcStringBindingCompose returned 0x%x\n", status);
-        return;
+        ERR("RpcStringBindingCompose returned 0x%x\n", status);
+        return NULL;
     }
 
     /* Set the binding handle that will be used to bind to the server. */
     status = RpcBindingFromStringBindingW(pszStringBinding,
-                                          &BindingHandle);
-    if (status)
+                                          &hBinding);
+    if (status != RPC_S_OK)
     {
-        TRACE("RpcBindingFromStringBinding returned 0x%x\n", status);
+        ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
     }
 
     status = RpcStringFreeW(&pszStringBinding);
-    if (status)
+    if (status != RPC_S_OK)
     {
-        TRACE("RpcStringFree returned 0x%x\n", status);
+        ERR("RpcStringFree returned 0x%x\n", status);
     }
+
+    return hBinding;
 }
 
 
-#if 0
-static VOID
-HandleUnbind(VOID)
+void __RPC_USER
+RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus,
+                                 handle_t hBinding)
 {
     RPC_STATUS status;
 
-    if (BindingHandle == NULL)
-        return;
+    TRACE("RPC_SERVICE_STATUS_HANDLE_unbind() called\n");
+
+    status = RpcBindingFree(&hBinding);
+    if (status != RPC_S_OK)
+    {
+        ERR("RpcBindingFree returned 0x%x\n", status);
+    }
+}
+
 
-    status = RpcBindingFree(&BindingHandle);
-    if (status)
+DWORD
+ScmRpcStatusToWinError(RPC_STATUS Status)
+{
+    switch (Status)
     {
-        TRACE("RpcBindingFree returned 0x%x\n", status);
+        case RPC_S_INVALID_BINDING:
+        case RPC_X_SS_IN_NULL_CONTEXT:
+            return ERROR_INVALID_HANDLE;
+
+        case RPC_X_ENUM_VALUE_OUT_OF_RANGE:
+        case RPC_X_BYTE_COUNT_TOO_SMALL:
+            return ERROR_INVALID_PARAMETER;
+
+        case RPC_X_NULL_REF_POINTER:
+            return ERROR_INVALID_ADDRESS;
+
+        default:
+            return (DWORD)Status;
     }
 }
-#endif
 
 
 /**********************************************************************
@@ -88,20 +218,22 @@ ChangeServiceConfig2A(SC_HANDLE hService,
                       DWORD dwInfoLevel,
                       LPVOID lpInfo)
 {
-    DWORD lpInfoSize;
+    SC_RPC_CONFIG_INFOA Info;
     DWORD dwError;
 
     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;
+            Info.lpDescription = ((LPSERVICE_DESCRIPTIONA)lpInfo)->lpDescription; //HACK
             break;
 
         case SERVICE_CONFIG_FAILURE_ACTIONS:
-            lpInfoSize = sizeof(SERVICE_FAILURE_ACTIONSA);
+            Info.psfa = (LPSERVICE_FAILURE_ACTIONSA)lpInfo;
             break;
 
         default:
@@ -113,16 +245,20 @@ ChangeServiceConfig2A(SC_HANDLE hService,
     if (lpInfo == NULL)
         return TRUE;
 
-    HandleBind();
+    RpcTryExcept
+    {
+        dwError = RChangeServiceConfig2A((SC_RPC_HANDLE)hService,
+                                         Info);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    dwError = ScmrChangeServiceConfig2A(BindingHandle,
-                                        (unsigned int)hService,
-                                        dwInfoLevel,
-                                        lpInfo,
-                                        lpInfoSize);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrChangeServiceConfig2A() failed (Error %lu)\n", dwError);
+        ERR("RChangeServiceConfig2A() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -141,42 +277,21 @@ ChangeServiceConfig2W(SC_HANDLE hService,
                       DWORD dwInfoLevel,
                       LPVOID lpInfo)
 {
-    LPBYTE lpSendData = NULL;
-    DWORD dwInfoSize;
+    SC_RPC_CONFIG_INFOW Info;
     DWORD dwError;
 
     TRACE("ChangeServiceConfig2W() called\n");
 
+    /* Fill relevent field of the Info structure */
+    Info.dwInfoLevel = dwInfoLevel;
     switch (dwInfoLevel)
     {
         case SERVICE_CONFIG_DESCRIPTION:
-        {
-            LPSERVICE_DESCRIPTIONW lpServiceDescription = lpInfo;
-            DWORD dwStringSize;
-
-            dwInfoSize = sizeof(SERVICE_DESCRIPTIONW);
-            dwStringSize = (wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR);
-            dwInfoSize += dwStringSize;
-
-            lpSendData = HeapAlloc(GetProcessHeap(), 0, dwInfoSize);
-            if (lpSendData)
-            {
-                LPBYTE pt = lpSendData;
-
-                CopyMemory(pt, lpInfo, sizeof(SERVICE_DESCRIPTIONW));
-                pt += sizeof(SERVICE_DESCRIPTIONW);
-                CopyMemory(pt, lpServiceDescription->lpDescription, dwStringSize);
-            }
-            else
-            {
-                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                return FALSE;
-            }
+            Info.psd = (LPSERVICE_DESCRIPTIONW)&lpInfo;
             break;
-        }
 
         case SERVICE_CONFIG_FAILURE_ACTIONS:
-            dwInfoSize = sizeof(SERVICE_FAILURE_ACTIONSW);
+            Info.psfa = (LPSERVICE_FAILURE_ACTIONSW)&lpInfo;
             break;
 
         default:
@@ -186,28 +301,26 @@ ChangeServiceConfig2W(SC_HANDLE hService,
     }
 
     if (lpInfo == NULL)
-        goto done;
+        return TRUE;
 
-    HandleBind();
+    RpcTryExcept
+    {
+        dwError = RChangeServiceConfig2W((SC_RPC_HANDLE)hService,
+                                         Info);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    dwError = ScmrChangeServiceConfig2W(BindingHandle,
-                                        (unsigned int)hService,
-                                        dwInfoLevel,
-                                        lpSendData,
-                                        dwInfoSize);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrChangeServiceConfig2W() failed (Error %lu)\n", dwError);
+        ERR("RChangeServiceConfig2W() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-done:
-    if (lpSendData != NULL)
-        HeapFree(GetProcessHeap(), 0, lpSendData);
-
-    TRACE("ChangeServiceConfig2W() done\n");
-
     return TRUE;
 }
 
@@ -217,7 +330,7 @@ done:
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 ChangeServiceConfigA(SC_HANDLE hService,
                      DWORD dwServiceType,
                      DWORD dwStartType,
@@ -252,26 +365,32 @@ ChangeServiceConfigA(SC_HANDLE hService,
 
     /* FIXME: Encrypt the password */
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RChangeServiceConfigA((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);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* 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);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrChangeServiceConfigA() failed (Error %lu)\n", dwError);
+        ERR("RChangeServiceConfigA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -285,7 +404,7 @@ ChangeServiceConfigA(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 ChangeServiceConfigW(SC_HANDLE hService,
                      DWORD dwServiceType,
                      DWORD dwStartType,
@@ -320,26 +439,32 @@ ChangeServiceConfigW(SC_HANDLE hService,
 
     /* FIXME: Encrypt the password */
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RChangeServiceConfigW((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);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* 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)
     {
-        ERR("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError);
+        ERR("RChangeServiceConfigW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -353,21 +478,33 @@ ChangeServiceConfigW(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 CloseServiceHandle(SC_HANDLE hSCObject)
 {
     DWORD dwError;
 
     TRACE("CloseServiceHandle() called\n");
 
-    HandleBind();
+    if (!hSCObject)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RCloseServiceHandle((LPSC_RPC_HANDLE)&hSCObject);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrCloseServiceHandle(BindingHandle,
-                                     (unsigned int)hSCObject);
     if (dwError)
     {
-        ERR("ScmrCloseServiceHandle() failed (Error %lu)\n", dwError);
+        ERR("RCloseServiceHandle() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -383,7 +520,7 @@ CloseServiceHandle(SC_HANDLE hSCObject)
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 ControlService(SC_HANDLE hService,
                DWORD dwControl,
                LPSERVICE_STATUS lpServiceStatus)
@@ -393,16 +530,22 @@ ControlService(SC_HANDLE hService,
     TRACE("ControlService(%x, %x, %p)\n",
            hService, dwControl, lpServiceStatus);
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RControlService((SC_RPC_HANDLE)hService,
+                                  dwControl,
+                                  lpServiceStatus);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrControlService(BindingHandle,
-                                 (unsigned int)hService,
-                                 dwControl,
-                                 lpServiceStatus);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrControlService() failed (Error %lu)\n", dwError);
+        ERR("RControlService() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -418,7 +561,7 @@ ControlService(SC_HANDLE hService,
  *
  * @unimplemented
  */
-BOOL STDCALL
+BOOL WINAPI
 ControlServiceEx(IN SC_HANDLE hService,
                  IN DWORD dwControl,
                  IN DWORD dwInfoLevel,
@@ -431,13 +574,12 @@ ControlServiceEx(IN SC_HANDLE hService,
 }
 
 
-
 /**********************************************************************
  *  CreateServiceA
  *
  * @implemented
  */
-SC_HANDLE STDCALL
+SC_HANDLE WINAPI
 CreateServiceA(SC_HANDLE hSCManager,
                LPCSTR lpServiceName,
                LPCSTR lpDisplayName,
@@ -452,68 +594,24 @@ CreateServiceA(SC_HANDLE hSCManager,
                LPCSTR lpServiceStartName,
                LPCSTR lpPassword)
 {
-    SC_HANDLE RetVal = NULL;
-    LPWSTR lpServiceNameW = NULL;
-    LPWSTR lpDisplayNameW = NULL;
-    LPWSTR lpBinaryPathNameW = NULL;
-    LPWSTR lpLoadOrderGroupW = NULL;
-    LPWSTR lpDependenciesW = NULL;
-    LPWSTR lpServiceStartNameW = NULL;
-    LPWSTR lpPasswordW = NULL;
+    SC_HANDLE hService = NULL;
     DWORD dwDependenciesLength = 0;
+    DWORD dwError;
     DWORD dwLength;
-    int len;
     LPSTR lpStr;
 
-    if (lpServiceName)
-    {
-        len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
-        lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        if (!lpServiceNameW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            goto cleanup;
-        }
-        MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
-    }
+    TRACE("CreateServiceA() called\n");
+    TRACE("%p %s %s\n", hSCManager, 
+          lpServiceName, lpDisplayName);
 
-    if (lpDisplayName)
+    if (!hSCManager)
     {
-        len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
-        lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        if (!lpDisplayNameW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            goto cleanup;
-        }
-        MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
-    }
-
-    if (lpBinaryPathName)
-    {
-        len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
-        lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        if (!lpBinaryPathNameW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            goto cleanup;
-        }
-        MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
-    }
-
-    if (lpLoadOrderGroup)
-    {
-        len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
-        lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        if (!lpLoadOrderGroupW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            goto cleanup;
-        }
-        MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
+        SetLastError(ERROR_INVALID_HANDLE);
+        return NULL;
     }
 
-    if (lpDependencies)
+    /* Calculate the Dependencies length*/
+    if (lpDependencies != NULL)
     {
         lpStr = (LPSTR)lpDependencies;
         while (*lpStr)
@@ -523,77 +621,44 @@ CreateServiceA(SC_HANDLE hSCManager,
             lpStr = lpStr + dwLength;
         }
         dwDependenciesLength++;
-
-        lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
-        if (!lpDependenciesW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            goto cleanup;
-        }
-        MultiByteToWideChar(CP_ACP, 0, lpDependencies, -1, lpDependenciesW, dwDependenciesLength);
     }
 
-    if (lpServiceStartName)
+    /* FIXME: Encrypt the password */
+
+    RpcTryExcept
     {
-        len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
-        lpServiceStartName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        if (!lpServiceStartNameW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            goto cleanup;
-        }
-        MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
+        /* Call to services.exe using RPC */
+        dwError = RCreateServiceA((SC_RPC_HANDLE)hSCManager,
+                                  (LPSTR)lpServiceName,
+                                  (LPSTR)lpDisplayName,
+                                  dwDesiredAccess,
+                                  dwServiceType,
+                                  dwStartType,
+                                  dwErrorControl,
+                                  (LPSTR)lpBinaryPathName,
+                                  (LPSTR)lpLoadOrderGroup,
+                                  lpdwTagId,
+                                  (LPBYTE)lpDependencies,
+                                  dwDependenciesLength,
+                                  (LPSTR)lpServiceStartName,
+                                  NULL,              /* FIXME: lpPassword */
+                                  0,                 /* FIXME: dwPasswordLength */
+                                  (SC_RPC_HANDLE *)&hService);
     }
-
-    if (lpPassword)
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
-        len = MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, NULL, 0);
-        lpPasswordW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        if (!lpPasswordW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            goto cleanup;
-        }
-        MultiByteToWideChar(CP_ACP, 0, lpPassword, -1, lpPasswordW, len);
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
     }
+    RpcEndExcept;
 
-    RetVal = CreateServiceW(hSCManager,
-                            lpServiceNameW,
-                            lpDisplayNameW,
-                            dwDesiredAccess,
-                            dwServiceType,
-                            dwStartType,
-                            dwErrorControl,
-                            lpBinaryPathNameW,
-                            lpLoadOrderGroupW,
-                            lpdwTagId,
-                            lpDependenciesW,
-                            lpServiceStartNameW,
-                            lpPasswordW);
-
-cleanup:
-    if (lpServiceNameW !=NULL)
-        HeapFree(GetProcessHeap(), 0, lpServiceNameW);
-
-    if (lpDisplayNameW != NULL)
-        HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
-
-    if (lpBinaryPathNameW != NULL)
-        HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
-
-    if (lpLoadOrderGroupW != NULL)
-        HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
-
-    if (lpDependenciesW != NULL)
-        HeapFree(GetProcessHeap(), 0, lpDependenciesW);
-
-    if (lpServiceStartNameW != NULL)
-        HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
-
-    if (lpPasswordW != NULL)
-        HeapFree(GetProcessHeap(), 0, lpPasswordW);
+    if (dwError != ERROR_SUCCESS)
+    {
+        ERR("RCreateServiceA() failed (Error %lu)\n", dwError);
+        SetLastError(dwError);
+        return NULL;
+    }
 
-    return RetVal;
+    return hService;
 }
 
 
@@ -602,7 +667,7 @@ cleanup:
  *
  * @implemented
  */
-SC_HANDLE STDCALL
+SC_HANDLE WINAPI
 CreateServiceW(SC_HANDLE hSCManager,
                LPCWSTR lpServiceName,
                LPCWSTR lpDisplayName,
@@ -624,6 +689,14 @@ CreateServiceW(SC_HANDLE hSCManager,
     LPWSTR lpStr;
 
     TRACE("CreateServiceW() called\n");
+    TRACE("%p %S %S\n", hSCManager, 
+          lpServiceName, lpDisplayName);
+
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return NULL;
+    }
 
     /* Calculate the Dependencies length*/
     if (lpDependencies != NULL)
@@ -636,33 +709,41 @@ 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 long *)&hService);
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RCreateServiceW((SC_RPC_HANDLE)hSCManager,
+                                  lpServiceName,
+                                  lpDisplayName,
+                                  dwDesiredAccess,
+                                  dwServiceType,
+                                  dwStartType,
+                                  dwErrorControl,
+                                  lpBinaryPathName,
+                                  lpLoadOrderGroup,
+                                  lpdwTagId,
+                                  (LPBYTE)lpDependencies,
+                                  dwDependenciesLength,
+                                  lpServiceStartName,
+                                  NULL,              /* FIXME: lpPassword */
+                                  0,                 /* FIXME: dwPasswordLength */
+                                  (SC_RPC_HANDLE *)&hService);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrCreateServiceW() failed (Error %lu)\n", dwError);
+        ERR("RCreateServiceW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
@@ -676,21 +757,27 @@ CreateServiceW(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 DeleteService(SC_HANDLE hService)
 {
     DWORD dwError;
 
     TRACE("DeleteService(%x)\n", hService);
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RDeleteService((SC_RPC_HANDLE)hService);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrDeleteService(BindingHandle,
-                                (unsigned int)hService);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrDeleteService() failed (Error %lu)\n", dwError);
+        ERR("RDeleteService() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -704,7 +791,7 @@ DeleteService(SC_HANDLE hService)
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 EnumDependentServicesA(SC_HANDLE hService,
                        DWORD dwServiceState,
                        LPENUM_SERVICE_STATUSA lpServices,
@@ -713,20 +800,32 @@ EnumDependentServicesA(SC_HANDLE hService,
                        LPDWORD lpServicesReturned)
 {
     LPENUM_SERVICE_STATUSA lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
     TRACE("EnumServicesStatusA() called\n");
 
-    HandleBind();
+    RpcTryExcept
+    {
+        dwError = REnumDependentServicesA((SC_RPC_HANDLE)hService,
+                                          dwServiceState,
+                                          (LPBYTE)lpServices,
+                                          cbBufSize,
+                                          pcbBytesNeeded,
+                                          lpServicesReturned);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    dwError = ScmrEnumDependentServicesA(BindingHandle,
-                                         (unsigned int)hService,
-                                         dwServiceState,
-                                         (unsigned char *)lpServices,
-                                         cbBufSize,
-                                         pcbBytesNeeded,
-                                         lpServicesReturned);
+    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++)
@@ -742,13 +841,6 @@ EnumDependentServicesA(SC_HANDLE hService,
         lpStatusPtr++;
     }
 
-    if (dwError != ERROR_SUCCESS)
-    {
-        ERR("ScmrEnumDependentServicesA() failed (Error %lu)\n", dwError);
-        SetLastError(dwError);
-        return FALSE;
-    }
-
     TRACE("EnumDependentServicesA() done\n");
 
     return TRUE;
@@ -760,7 +852,7 @@ EnumDependentServicesA(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 EnumDependentServicesW(SC_HANDLE hService,
                        DWORD dwServiceState,
                        LPENUM_SERVICE_STATUSW lpServices,
@@ -769,20 +861,32 @@ EnumDependentServicesW(SC_HANDLE hService,
                        LPDWORD lpServicesReturned)
 {
     LPENUM_SERVICE_STATUSW lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
     TRACE("EnumServicesStatusW() called\n");
 
-    HandleBind();
+    RpcTryExcept
+    {
+        dwError = REnumDependentServicesW((SC_RPC_HANDLE)hService,
+                                          dwServiceState,
+                                          (LPBYTE)lpServices,
+                                          cbBufSize,
+                                          pcbBytesNeeded,
+                                          lpServicesReturned);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    dwError = ScmrEnumDependentServicesW(BindingHandle,
-                                         (unsigned int)hService,
-                                         dwServiceState,
-                                         (unsigned char *)lpServices,
-                                         cbBufSize,
-                                         pcbBytesNeeded,
-                                         lpServicesReturned);
+    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++)
@@ -798,13 +902,6 @@ EnumDependentServicesW(SC_HANDLE hService,
         lpStatusPtr++;
     }
 
-    if (dwError != ERROR_SUCCESS)
-    {
-        ERR("ScmrEnumDependentServicesW() failed (Error %lu)\n", dwError);
-        SetLastError(dwError);
-        return FALSE;
-    }
-
     TRACE("EnumDependentServicesW() done\n");
 
     return TRUE;
@@ -817,7 +914,7 @@ EnumDependentServicesW(SC_HANDLE hService,
  * @unimplemented
  */
 BOOL
-STDCALL
+WINAPI
 EnumServiceGroupW(
     SC_HANDLE               hSCManager,
     DWORD                   dwServiceType,
@@ -840,7 +937,7 @@ EnumServiceGroupW(
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 EnumServicesStatusA(SC_HANDLE hSCManager,
                     DWORD dwServiceType,
                     DWORD dwServiceState,
@@ -851,22 +948,76 @@ EnumServicesStatusA(SC_HANDLE hSCManager,
                     LPDWORD lpResumeHandle)
 {
     LPENUM_SERVICE_STATUSA lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
     TRACE("EnumServicesStatusA() called\n");
 
-    HandleBind();
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    if (dwServiceType != SERVICE_DRIVER && dwServiceType != SERVICE_WIN32)
+    {
+        if (pcbBytesNeeded && lpServicesReturned)
+        {
+            *pcbBytesNeeded = 0;
+            *lpServicesReturned = 0;
+        }
+
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if (dwServiceState != SERVICE_ACTIVE && dwServiceState != SERVICE_INACTIVE && dwServiceState != SERVICE_STATE_ALL)
+    {
+            if (pcbBytesNeeded)
+                *pcbBytesNeeded = 0;
+
+            if (lpServicesReturned)
+                *lpServicesReturned = 0;
+
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if (!pcbBytesNeeded || !lpServicesReturned)
+    {
+        SetLastError(ERROR_INVALID_ADDRESS);
+        return FALSE;
+    }
 
-    dwError = ScmrEnumServicesStatusA(BindingHandle,
-                                      (unsigned int)hSCManager,
-                                      dwServiceType,
-                                      dwServiceState,
-                                      (unsigned char *)lpServices,
-                                      cbBufSize,
-                                      pcbBytesNeeded,
-                                      lpServicesReturned,
-                                      lpResumeHandle);
+    if (!lpServices && cbBufSize != 0)
+    {
+        SetLastError(ERROR_INVALID_ADDRESS);
+        return FALSE;
+    }
+
+    RpcTryExcept
+    {
+        dwError = REnumServicesStatusA((SC_RPC_HANDLE)hSCManager,
+                                       dwServiceType,
+                                       dwServiceState,
+                                       (LPBYTE)lpServices,
+                                       cbBufSize,
+                                       pcbBytesNeeded,
+                                       lpServicesReturned,
+                                       lpResumeHandle);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
+
+    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++)
@@ -882,13 +1033,6 @@ EnumServicesStatusA(SC_HANDLE hSCManager,
         lpStatusPtr++;
     }
 
-    if (dwError != ERROR_SUCCESS)
-    {
-        ERR("ScmrEnumServicesStatusA() failed (Error %lu)\n", dwError);
-        SetLastError(dwError);
-        return FALSE;
-    }
-
     TRACE("EnumServicesStatusA() done\n");
 
     return TRUE;
@@ -900,7 +1044,7 @@ EnumServicesStatusA(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 EnumServicesStatusW(SC_HANDLE hSCManager,
                     DWORD dwServiceType,
                     DWORD dwServiceState,
@@ -911,22 +1055,40 @@ EnumServicesStatusW(SC_HANDLE hSCManager,
                     LPDWORD lpResumeHandle)
 {
     LPENUM_SERVICE_STATUSW lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
     TRACE("EnumServicesStatusW() called\n");
 
-    HandleBind();
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    RpcTryExcept
+    {
+        dwError = REnumServicesStatusW((SC_RPC_HANDLE)hSCManager,
+                                       dwServiceType,
+                                       dwServiceState,
+                                       (LPBYTE)lpServices,
+                                       cbBufSize,
+                                       pcbBytesNeeded,
+                                       lpServicesReturned,
+                                       lpResumeHandle);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    dwError = ScmrEnumServicesStatusW(BindingHandle,
-                                      (unsigned int)hSCManager,
-                                      dwServiceType,
-                                      dwServiceState,
-                                      (unsigned char *)lpServices,
-                                      cbBufSize,
-                                      pcbBytesNeeded,
-                                      lpServicesReturned,
-                                      lpResumeHandle);
+    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++)
@@ -942,13 +1104,6 @@ EnumServicesStatusW(SC_HANDLE hSCManager,
         lpStatusPtr++;
     }
 
-    if (dwError != ERROR_SUCCESS)
-    {
-        ERR("ScmrEnumServicesStatusW() failed (Error %lu)\n", dwError);
-        SetLastError(dwError);
-        return FALSE;
-    }
-
     TRACE("EnumServicesStatusW() done\n");
 
     return TRUE;
@@ -960,7 +1115,7 @@ EnumServicesStatusW(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 EnumServicesStatusExA(SC_HANDLE hSCManager,
                       SC_ENUM_TYPE InfoLevel,
                       DWORD dwServiceType,
@@ -973,24 +1128,42 @@ EnumServicesStatusExA(SC_HANDLE hSCManager,
                       LPCSTR pszGroupName)
 {
     LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
     TRACE("EnumServicesStatusExA() called\n");
 
-    HandleBind();
+    if (InfoLevel != SC_ENUM_PROCESS_INFO)
+    {
+        SetLastError(ERROR_INVALID_LEVEL);
+        return FALSE;
+    }
 
-    dwError = ScmrEnumServicesStatusExA(BindingHandle,
-                                        (unsigned int)hSCManager,
-                                        (unsigned long)InfoLevel,
-                                        dwServiceType,
-                                        dwServiceState,
-                                        (unsigned char *)lpServices,
-                                        cbBufSize,
-                                        pcbBytesNeeded,
-                                        lpServicesReturned,
-                                        lpResumeHandle,
-                                        (char *)pszGroupName);
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+
+    RpcTryExcept
+    {
+        dwError = REnumServicesStatusExA((SC_RPC_HANDLE)hSCManager,
+                                         InfoLevel,
+                                         dwServiceType,
+                                         dwServiceState,
+                                         (LPBYTE)lpServices,
+                                         cbBufSize,
+                                         pcbBytesNeeded,
+                                         lpServicesReturned,
+                                         lpResumeHandle,
+                                         (LPSTR)pszGroupName);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
     if (dwError == ERROR_MORE_DATA)
     {
@@ -1016,7 +1189,7 @@ EnumServicesStatusExA(SC_HANDLE hSCManager,
     }
     else
     {
-        ERR("ScmrEnumServicesStatusExA() failed (Error %lu)\n", dwError);
+        ERR("REnumServicesStatusExA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1032,7 +1205,7 @@ EnumServicesStatusExA(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 EnumServicesStatusExW(SC_HANDLE hSCManager,
                       SC_ENUM_TYPE InfoLevel,
                       DWORD dwServiceType,
@@ -1045,24 +1218,29 @@ EnumServicesStatusExW(SC_HANDLE hSCManager,
                       LPCWSTR pszGroupName)
 {
     LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
-    DWORD dwError = ERROR_SUCCESS;
+    DWORD dwError;
     DWORD dwCount;
 
     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);
+    RpcTryExcept
+    {
+        dwError = REnumServicesStatusExW((SC_RPC_HANDLE)hSCManager,
+                                         InfoLevel,
+                                         dwServiceType,
+                                         dwServiceState,
+                                         (LPBYTE)lpServices,
+                                         cbBufSize,
+                                         pcbBytesNeeded,
+                                         lpServicesReturned,
+                                         lpResumeHandle,
+                                         (LPWSTR)pszGroupName);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
     if (dwError == ERROR_MORE_DATA)
     {
@@ -1088,7 +1266,7 @@ EnumServicesStatusExW(SC_HANDLE hSCManager,
     }
     else
     {
-        ERR("ScmrEnumServicesStatusExW() failed (Error %lu)\n", dwError);
+        ERR("REnumServicesStatusExW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1104,7 +1282,7 @@ EnumServicesStatusExW(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 GetServiceDisplayNameA(SC_HANDLE hSCManager,
                        LPCSTR lpServiceName,
                        LPSTR lpDisplayName,
@@ -1113,23 +1291,41 @@ GetServiceDisplayNameA(SC_HANDLE hSCManager,
     DWORD dwError;
 
     TRACE("GetServiceDisplayNameA() called\n");
+    TRACE("%p %s %p %p\n", hSCManager,
+          debugstr_a(lpServiceName), lpDisplayName, lpcchBuffer);
+
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    if (!lpDisplayName)
+        *lpcchBuffer = 0;
+
+    RpcTryExcept
+    {
+        dwError = RGetServiceDisplayNameA((SC_RPC_HANDLE)hSCManager,
+                                          lpServiceName,
+                                          lpDisplayName,
+                                          lpcchBuffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* HACK: because of a problem with rpcrt4, rpcserver is hacked to return 6 for ERROR_SERVICE_DOES_NOT_EXIST */
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
 
-    HandleBind();
 
-    dwError = ScmrGetServiceDisplayNameA(BindingHandle,
-                                         (unsigned int)hSCManager,
-                                         (LPSTR)lpServiceName,
-                                         lpDisplayName,
-                                         lpcchBuffer);
+    RpcEndExcept;
+
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
+        ERR("RGetServiceDisplayNameA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    (*lpcchBuffer)--;
-
     return TRUE;
 }
 
@@ -1139,7 +1335,7 @@ GetServiceDisplayNameA(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 GetServiceDisplayNameW(SC_HANDLE hSCManager,
                        LPCWSTR lpServiceName,
                        LPWSTR lpDisplayName,
@@ -1149,22 +1345,35 @@ GetServiceDisplayNameW(SC_HANDLE hSCManager,
 
     TRACE("GetServiceDisplayNameW() called\n");
 
-    HandleBind();
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    if (!lpDisplayName)
+        *lpcchBuffer = 0;
+
+    RpcTryExcept
+    {
+        dwError = RGetServiceDisplayNameW((SC_RPC_HANDLE)hSCManager,
+                                          lpServiceName,
+                                          lpDisplayName,
+                                          lpcchBuffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    dwError = ScmrGetServiceDisplayNameW(BindingHandle,
-                                         (unsigned int)hSCManager,
-                                         (LPWSTR)lpServiceName,
-                                         lpDisplayName,
-                                         lpcchBuffer);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
+        ERR("RGetServiceDisplayNameW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    (*lpcchBuffer)--;
-
     return TRUE;
 }
 
@@ -1174,7 +1383,7 @@ GetServiceDisplayNameW(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 GetServiceKeyNameA(SC_HANDLE hSCManager,
                    LPCSTR lpDisplayName,
                    LPSTR lpServiceName,
@@ -1184,22 +1393,44 @@ GetServiceKeyNameA(SC_HANDLE hSCManager,
 
     TRACE("GetServiceKeyNameA() called\n");
 
-    HandleBind();
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    if (!lpDisplayName)
+    {
+        SetLastError(ERROR_INVALID_ADDRESS);
+
+        if (!lpServiceName)
+            *lpcchBuffer = 1;
+        return FALSE;
+    }
+
+    if (!lpServiceName)
+        *lpcchBuffer = 0;
+
+    RpcTryExcept
+    {
+        dwError = RGetServiceKeyNameA((SC_RPC_HANDLE)hSCManager,
+                                      lpDisplayName,
+                                      lpServiceName,
+                                      lpcchBuffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    dwError = ScmrGetServiceKeyNameA(BindingHandle,
-                                     (unsigned int)hSCManager,
-                                     (LPSTR)lpDisplayName,
-                                     lpServiceName,
-                                     lpcchBuffer);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrGetServiceKeyNameA() failed (Error %lu)\n", dwError);
+        ERR("RGetServiceKeyNameA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    (*lpcchBuffer)--;
-
     return TRUE;
 }
 
@@ -1209,7 +1440,7 @@ GetServiceKeyNameA(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 GetServiceKeyNameW(SC_HANDLE hSCManager,
                    LPCWSTR lpDisplayName,
                    LPWSTR lpServiceName,
@@ -1219,22 +1450,44 @@ GetServiceKeyNameW(SC_HANDLE hSCManager,
 
     TRACE("GetServiceKeyNameW() called\n");
 
-    HandleBind();
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    if (!lpDisplayName)
+    {
+        SetLastError(ERROR_INVALID_ADDRESS);
+
+        if (!lpServiceName)
+            *lpcchBuffer = 1;
+        return FALSE;
+    }
+
+    if (!lpServiceName)
+        *lpcchBuffer = 0;
+
+    RpcTryExcept
+    {
+        dwError = RGetServiceKeyNameW((SC_RPC_HANDLE)hSCManager,
+                                      lpDisplayName,
+                                      lpServiceName,
+                                      lpcchBuffer);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    dwError = ScmrGetServiceKeyNameW(BindingHandle,
-                                     (unsigned int)hSCManager,
-                                     (LPWSTR)lpDisplayName,
-                                     lpServiceName,
-                                     lpcchBuffer);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrGetServiceKeyNameW() failed (Error %lu)\n", dwError);
+        ERR("RGetServiceKeyNameW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
 
-    (*lpcchBuffer)--;
-
     return TRUE;
 }
 
@@ -1244,7 +1497,7 @@ GetServiceKeyNameW(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-SC_LOCK STDCALL
+SC_LOCK WINAPI
 LockServiceDatabase(SC_HANDLE hSCManager)
 {
     SC_LOCK hLock;
@@ -1252,15 +1505,21 @@ LockServiceDatabase(SC_HANDLE hSCManager)
 
     TRACE("LockServiceDatabase(%x)\n", hSCManager);
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RLockServiceDatabase((SC_RPC_HANDLE)hSCManager,
+                                       (SC_RPC_LOCK *)&hLock);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrLockServiceDatabase(BindingHandle,
-                                      (unsigned int)hSCManager,
-                                      (unsigned int *)&hLock);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrLockServiceDatabase() failed (Error %lu)\n", dwError);
+        ERR("RLockServiceDatabase() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
@@ -1316,7 +1575,7 @@ WaitForSCManager(VOID)
  *
  * @implemented
  */
-SC_HANDLE STDCALL
+SC_HANDLE WINAPI
 OpenSCManagerA(LPCSTR lpMachineName,
                LPCSTR lpDatabaseName,
                DWORD dwDesiredAccess)
@@ -1329,17 +1588,23 @@ OpenSCManagerA(LPCSTR lpMachineName,
 
     WaitForSCManager();
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = ROpenSCManagerA((LPSTR)lpMachineName,
+                                  (LPSTR)lpDatabaseName,
+                                  dwDesiredAccess,
+                                  (SC_RPC_HANDLE *)&hScm);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrOpenSCManagerA(BindingHandle,
-                                 (LPSTR)lpMachineName,
-                                 (LPSTR)lpDatabaseName,
-                                 dwDesiredAccess,
-                                 (unsigned long*)&hScm);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrOpenSCManagerA() failed (Error %lu)\n", dwError);
+        ERR("ROpenSCManagerA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
@@ -1355,7 +1620,7 @@ OpenSCManagerA(LPCSTR lpMachineName,
  *
  * @implemented
  */
-SC_HANDLE STDCALL
+SC_HANDLE WINAPI
 OpenSCManagerW(LPCWSTR lpMachineName,
                LPCWSTR lpDatabaseName,
                DWORD dwDesiredAccess)
@@ -1368,17 +1633,23 @@ OpenSCManagerW(LPCWSTR lpMachineName,
 
     WaitForSCManager();
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = ROpenSCManagerW((LPWSTR)lpMachineName,
+                                  (LPWSTR)lpDatabaseName,
+                                  dwDesiredAccess,
+                                  (SC_RPC_HANDLE *)&hScm);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrOpenSCManagerW(BindingHandle,
-                                 (LPWSTR)lpMachineName,
-                                 (LPWSTR)lpDatabaseName,
-                                 dwDesiredAccess,
-                                 (unsigned long*)&hScm);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrOpenSCManagerW() failed (Error %lu)\n", dwError);
+        ERR("ROpenSCManagerW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
@@ -1394,7 +1665,7 @@ OpenSCManagerW(LPCWSTR lpMachineName,
  *
  * @implemented
  */
-SC_HANDLE STDCALL
+SC_HANDLE WINAPI
 OpenServiceA(SC_HANDLE hSCManager,
              LPCSTR lpServiceName,
              DWORD dwDesiredAccess)
@@ -1405,17 +1676,29 @@ OpenServiceA(SC_HANDLE hSCManager,
     TRACE("OpenServiceA(%p, %s, %lx)\n",
            hSCManager, lpServiceName, dwDesiredAccess);
 
-    HandleBind();
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return NULL;
+    }
+
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = ROpenServiceA((SC_RPC_HANDLE)hSCManager,
+                                (LPSTR)lpServiceName,
+                                dwDesiredAccess,
+                                (SC_RPC_HANDLE *)&hService);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrOpenServiceA(BindingHandle,
-                               (unsigned int)hSCManager,
-                               (LPSTR)lpServiceName,
-                               dwDesiredAccess,
-                               (unsigned long*)&hService);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrOpenServiceA() failed (Error %lu)\n", dwError);
+        ERR("ROpenServiceA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return NULL;
     }
@@ -1431,7 +1714,7 @@ OpenServiceA(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-SC_HANDLE STDCALL
+SC_HANDLE WINAPI
 OpenServiceW(SC_HANDLE hSCManager,
              LPCWSTR lpServiceName,
              DWORD dwDesiredAccess)
@@ -1442,17 +1725,32 @@ OpenServiceW(SC_HANDLE hSCManager,
     TRACE("OpenServiceW(%p, %S, %lx)\n",
            hSCManager, lpServiceName, dwDesiredAccess);
 
-    HandleBind();
+    if (!hSCManager)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return NULL;
+    }
+
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = ROpenServiceW((SC_RPC_HANDLE)hSCManager,
+                                (LPWSTR)lpServiceName,
+                                dwDesiredAccess,
+                                (SC_RPC_HANDLE *)&hService);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrOpenServiceW(BindingHandle,
-                               (unsigned int)hSCManager,
-                               (LPWSTR)lpServiceName,
-                               dwDesiredAccess,
-                               (unsigned long*)&hService);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("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;
     }
@@ -1468,7 +1766,7 @@ OpenServiceW(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 QueryServiceConfigA(SC_HANDLE hService,
                     LPQUERY_SERVICE_CONFIGA lpServiceConfig,
                     DWORD cbBufSize,
@@ -1479,17 +1777,23 @@ QueryServiceConfigA(SC_HANDLE hService,
     TRACE("QueryServiceConfigA(%p, %p, %lu, %p)\n",
            hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceConfigA((SC_RPC_HANDLE)hService,
+                                       (LPBYTE)lpServiceConfig,
+                                       cbBufSize,
+                                       pcbBytesNeeded);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceConfigA(BindingHandle,
-                                      (unsigned int)hService,
-                                      (unsigned char *)lpServiceConfig,
-                                      cbBufSize,
-                                      pcbBytesNeeded);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrQueryServiceConfigA() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceConfigA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1531,7 +1835,7 @@ QueryServiceConfigA(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 QueryServiceConfigW(SC_HANDLE hService,
                     LPQUERY_SERVICE_CONFIGW lpServiceConfig,
                     DWORD cbBufSize,
@@ -1542,17 +1846,26 @@ QueryServiceConfigW(SC_HANDLE hService,
     TRACE("QueryServiceConfigW(%p, %p, %lu, %p)\n",
            hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceConfigW((SC_RPC_HANDLE)hService,
+                                       (LPBYTE)lpServiceConfig,
+                                       cbBufSize,
+                                       pcbBytesNeeded);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceConfigW(BindingHandle,
-                                      (unsigned int)hService,
-                                      (unsigned char *)lpServiceConfig,
-                                      cbBufSize,
-                                      pcbBytesNeeded);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("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;
     }
@@ -1594,7 +1907,7 @@ QueryServiceConfigW(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 QueryServiceConfig2A(SC_HANDLE hService,
                      DWORD dwInfoLevel,
                      LPBYTE lpBuffer,
@@ -1603,21 +1916,41 @@ QueryServiceConfig2A(SC_HANDLE hService,
 {
     DWORD dwError;
 
-    TRACE("QueryServiceConfig2A(%p, %lu, %p, %lu, %p)\n",
+    DbgPrint("QueryServiceConfig2A(hService %p, dwInfoLevel %lu, lpBuffer %p, cbBufSize %lu, pcbBytesNeeded %p)\n",
            hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
 
-    HandleBind();
+    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;
+    }
+
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceConfig2A((SC_RPC_HANDLE)hService,
+                                        dwInfoLevel,
+                                        lpBuffer,
+                                        cbBufSize,
+                                        pcbBytesNeeded);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceConfig2A(BindingHandle,
-                                       (unsigned int)hService,
-                                       dwInfoLevel,
-                                       (unsigned char *)lpBuffer,
-                                       cbBufSize,
-                                       pcbBytesNeeded);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrQueryServiceConfig2A() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceConfig2A() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1669,7 +2002,7 @@ QueryServiceConfig2A(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 QueryServiceConfig2W(SC_HANDLE hService,
                      DWORD dwInfoLevel,
                      LPBYTE lpBuffer,
@@ -1681,18 +2014,38 @@ QueryServiceConfig2W(SC_HANDLE hService,
     TRACE("QueryServiceConfig2W(%p, %lu, %p, %lu, %p)\n",
            hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
 
-    HandleBind();
+    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;
+    }
+
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceConfig2W((SC_RPC_HANDLE)hService,
+                                        dwInfoLevel,
+                                        lpBuffer,
+                                        cbBufSize,
+                                        pcbBytesNeeded);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceConfig2W(BindingHandle,
-                                       (unsigned int)hService,
-                                       dwInfoLevel,
-                                       (unsigned char *)lpBuffer,
-                                       cbBufSize,
-                                       pcbBytesNeeded);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrQueryServiceConfig2W() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceConfig2W() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1744,7 +2097,7 @@ QueryServiceConfig2W(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 QueryServiceLockStatusA(SC_HANDLE hSCManager,
                         LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
                         DWORD cbBufSize,
@@ -1754,17 +2107,23 @@ QueryServiceLockStatusA(SC_HANDLE hSCManager,
 
     TRACE("QueryServiceLockStatusA() called\n");
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceLockStatusA((SC_RPC_HANDLE)hSCManager,
+                                           lpLockStatus,
+                                           cbBufSize,
+                                           pcbBytesNeeded);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceLockStatusA(BindingHandle,
-                                          (unsigned int)hSCManager,
-                                          (unsigned char *)lpLockStatus,
-                                          cbBufSize,
-                                          pcbBytesNeeded);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceLockStatusA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1786,7 +2145,7 @@ QueryServiceLockStatusA(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 QueryServiceLockStatusW(SC_HANDLE hSCManager,
                         LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
                         DWORD cbBufSize,
@@ -1796,17 +2155,23 @@ QueryServiceLockStatusW(SC_HANDLE hSCManager,
 
     TRACE("QueryServiceLockStatusW() called\n");
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceLockStatusW((SC_RPC_HANDLE)hSCManager,
+                                           lpLockStatus,
+                                           cbBufSize,
+                                           pcbBytesNeeded);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceLockStatusW(BindingHandle,
-                                          (unsigned int)hSCManager,
-                                          (unsigned char *)lpLockStatus,
-                                          cbBufSize,
-                                          pcbBytesNeeded);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceLockStatusW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1828,7 +2193,7 @@ QueryServiceLockStatusW(SC_HANDLE hSCManager,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 QueryServiceObjectSecurity(SC_HANDLE hService,
                            SECURITY_INFORMATION dwSecurityInformation,
                            PSECURITY_DESCRIPTOR lpSecurityDescriptor,
@@ -1840,15 +2205,21 @@ QueryServiceObjectSecurity(SC_HANDLE hService,
     TRACE("QueryServiceObjectSecurity(%p, %lu, %p)\n",
            hService, dwSecurityInformation, lpSecurityDescriptor);
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceObjectSecurity((SC_RPC_HANDLE)hService,
+                                              dwSecurityInformation,
+                                              (LPBYTE)lpSecurityDescriptor,
+                                              cbBufSize,
+                                              pcbBytesNeeded);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceObjectSecurity(BindingHandle,
-                                             (unsigned int)hService,
-                                             dwSecurityInformation,
-                                             (unsigned char *)lpSecurityDescriptor,
-                                             cbBufSize,
-                                             pcbBytesNeeded);
     if (dwError != ERROR_SUCCESS)
     {
         ERR("QueryServiceObjectSecurity() failed (Error %lu)\n", dwError);
@@ -1864,7 +2235,7 @@ QueryServiceObjectSecurity(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 SetServiceObjectSecurity(SC_HANDLE hService,
                          SECURITY_INFORMATION dwSecurityInformation,
                          PSECURITY_DESCRIPTOR lpSecurityDescriptor)
@@ -1901,20 +2272,25 @@ SetServiceObjectSecurity(SC_HANDLE hService,
         return FALSE;
     }
 
-    HandleBind();
-
-    /* Call to services.exe using RPC */
-    dwError = ScmrSetServiceObjectSecurity(BindingHandle,
-                                           (unsigned int)hService,
-                                           dwSecurityInformation,
-                                           (unsigned char *)SelfRelativeSD,
-                                           Length);
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RSetServiceObjectSecurity((SC_RPC_HANDLE)hService,
+                                            dwSecurityInformation,
+                                            (LPBYTE)SelfRelativeSD,
+                                            Length);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
     HeapFree(GetProcessHeap(), 0, SelfRelativeSD);
 
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrServiceObjectSecurity() failed (Error %lu)\n", dwError);
+        ERR("RServiceObjectSecurity() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1928,7 +2304,7 @@ SetServiceObjectSecurity(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 QueryServiceStatus(SC_HANDLE hService,
                    LPSERVICE_STATUS lpServiceStatus)
 {
@@ -1937,15 +2313,27 @@ QueryServiceStatus(SC_HANDLE hService,
     TRACE("QueryServiceStatus(%p, %p)\n",
            hService, lpServiceStatus);
 
-    HandleBind();
+    if (!hService)
+    {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceStatus((SC_RPC_HANDLE)hService,
+                                      lpServiceStatus);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceStatus(BindingHandle,
-                                     (unsigned int)hService,
-                                     lpServiceStatus);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrQueryServiceStatus() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceStatus() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1959,7 +2347,7 @@ QueryServiceStatus(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 QueryServiceStatusEx(SC_HANDLE hService,
                      SC_STATUS_TYPE InfoLevel,
                      LPBYTE lpBuffer,
@@ -1970,18 +2358,30 @@ QueryServiceStatusEx(SC_HANDLE hService,
 
     TRACE("QueryServiceStatusEx() called\n");
 
-    HandleBind();
+    if (InfoLevel != SC_STATUS_PROCESS_INFO)
+    {
+        SetLastError(ERROR_INVALID_LEVEL);
+        return FALSE;
+    }
+
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RQueryServiceStatusEx((SC_RPC_HANDLE)hService,
+                                        InfoLevel,
+                                        lpBuffer,
+                                        cbBufSize,
+                                        pcbBytesNeeded);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrQueryServiceStatusEx(BindingHandle,
-                                       (unsigned int)hService,
-                                       InfoLevel,
-                                       lpBuffer,
-                                       cbBufSize,
-                                       pcbBytesNeeded);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrQueryServiceStatusEx() failed (Error %lu)\n", dwError);
+        ERR("RQueryServiceStatusEx() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -1995,54 +2395,28 @@ QueryServiceStatusEx(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 StartServiceA(SC_HANDLE hService,
               DWORD dwNumServiceArgs,
               LPCSTR *lpServiceArgVectors)
 {
-    LPSTR lpBuffer = NULL;
-    LPSTR lpStr;
     DWORD dwError;
-    DWORD dwBufSize = 0;
-    DWORD i;
 
-    if (dwNumServiceArgs > 0)
+    RpcTryExcept
     {
-        for (i = 0; i < dwNumServiceArgs; i++)
-        {
-            dwBufSize += (strlen(lpServiceArgVectors[i]) + 1);
-        }
-        dwBufSize++;
-        TRACE("dwBufSize: %lu\n", dwBufSize);
-
-        lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize);
-        if (lpBuffer == NULL)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            return FALSE;
-        }
-
-        lpStr = lpBuffer;
-        for (i = 0; i < dwNumServiceArgs; i++)
-        {
-            strcpy(lpStr, lpServiceArgVectors[i]);
-            lpStr += (strlen(lpServiceArgVectors[i]) + 1);
-        }
-        *lpStr = 0;
+        dwError = RStartServiceA((SC_RPC_HANDLE)hService,
+                                 dwNumServiceArgs,
+                                 (LPSTRING_PTRSA)lpServiceArgVectors);
     }
-
-    dwError = ScmrStartServiceA(BindingHandle,
-                                (unsigned int)hService,
-                                dwNumServiceArgs,
-                                (unsigned char *)lpBuffer,
-                                dwBufSize);
-
-    if (lpBuffer != NULL)
-        HeapFree(GetProcessHeap(), 0, lpBuffer);
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrStartServiceA() failed (Error %lu)\n", dwError);
+        ERR("RStartServiceA() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -2056,51 +2430,28 @@ StartServiceA(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 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);
-    TRACE("dwBufSize: %lu\n", dwBufSize);
 
-    lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufSize);
-    if (lpBuffer == NULL)
+    RpcTryExcept
     {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
+        dwError = RStartServiceW((SC_RPC_HANDLE)hService,
+                                 dwNumServiceArgs,
+                                 (LPSTRING_PTRSW)lpServiceArgVectors);
     }
-
-    lpStr = lpBuffer;
-    for (i = 0; i < dwNumServiceArgs; i++)
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
     {
-        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);
+    RpcEndExcept;
 
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrStartServiceW() failed (Error %lu)\n", dwError);
+        ERR("RStartServiceW() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -2114,21 +2465,27 @@ StartServiceW(SC_HANDLE hService,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 UnlockServiceDatabase(SC_LOCK ScLock)
 {
     DWORD dwError;
 
     TRACE("UnlockServiceDatabase(%x)\n", ScLock);
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RUnlockServiceDatabase((LPSC_RPC_LOCK)&ScLock);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrUnlockServiceDatabase(BindingHandle,
-                                        (unsigned int)ScLock);
     if (dwError != ERROR_SUCCESS)
     {
-        ERR("ScmrUnlockServiceDatabase() failed (Error %lu)\n", dwError);
+        ERR("RUnlockServiceDatabase() failed (Error %lu)\n", dwError);
         SetLastError(dwError);
         return FALSE;
     }
@@ -2142,18 +2499,25 @@ UnlockServiceDatabase(SC_LOCK ScLock)
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 NotifyBootConfigStatus(BOOL BootAcceptable)
 {
     DWORD dwError;
 
     TRACE("NotifyBootConfigStatus()\n");
 
-    HandleBind();
+    RpcTryExcept
+    {
+        /* Call to services.exe using RPC */
+        dwError = RNotifyBootConfigStatus(NULL,
+                                          BootAcceptable);
+    }
+    RpcExcept(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dwError = ScmRpcStatusToWinError(RpcExceptionCode());
+    }
+    RpcEndExcept;
 
-    /* Call to services.exe using RPC */
-    dwError = ScmrNotifyBootConfigStatus(BindingHandle,
-                                         BootAcceptable);
     if (dwError != ERROR_SUCCESS)
     {
         ERR("NotifyBootConfigStatus() failed (Error %lu)\n", dwError);