- GetServiceDisplayNameA/W and GetServiceKeyNameA/W: Fix returned name size.
[reactos.git] / reactos / base / system / services / rpcserver.c
index da692d6..416cc13 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-#define SC_LOCK unsigned int
-#define SC_STATUS_TYPE unsigned long
-#define SC_ENUM_TYPE unsigned long
-
 /* GLOBALS *****************************************************************/
 
 #define MANAGER_TAG 0x72674D68  /* 'hMgr' */
@@ -115,7 +111,7 @@ ScmStartRpcServer(VOID)
 {
     RPC_STATUS Status;
 
-    DPRINT("ScmStartRpcServer() called");
+    DPRINT("ScmStartRpcServer() called\n");
 
     Status = RpcServerUseProtseqEpW(L"ncacn_np",
                                     10,
@@ -143,7 +139,7 @@ ScmStartRpcServer(VOID)
         return;
     }
 
-    DPRINT("ScmStartRpcServer() done");
+    DPRINT("ScmStartRpcServer() done\n");
 }
 
 
@@ -240,20 +236,20 @@ ScmAssignNewTag(PSERVICE lpService)
 
 
 /* Function 0 */
-DWORD
-ScmrCloseServiceHandle(handle_t BindingHandle,
-                       unsigned long hScObject)
+DWORD RCloseServiceHandle(
+    handle_t BindingHandle,
+    LPSC_RPC_HANDLE hSCObject)
 {
     PMANAGER_HANDLE hManager;
 
-    DPRINT("ScmrCloseServiceHandle() called\n");
+    DPRINT("RCloseServiceHandle() called\n");
 
-    DPRINT("hScObject = %X\n", hScObject);
+    DPRINT("hSCObject = %p\n", *hSCObject);
 
-    if (hScObject == 0)
+    if (*hSCObject == 0)
         return ERROR_INVALID_HANDLE;
 
-    hManager = (PMANAGER_HANDLE)hScObject;
+    hManager = (PMANAGER_HANDLE)*hSCObject;
     if (hManager->Handle.Tag == MANAGER_TAG)
     {
         DPRINT("Found manager handle\n");
@@ -266,7 +262,7 @@ ScmrCloseServiceHandle(handle_t BindingHandle,
             HeapFree(GetProcessHeap(), 0, hManager);
         }
 
-        DPRINT("ScmrCloseServiceHandle() done\n");
+        DPRINT("RCloseServiceHandle() done\n");
         return ERROR_SUCCESS;
     }
     else if (hManager->Handle.Tag == SERVICE_TAG)
@@ -281,7 +277,7 @@ ScmrCloseServiceHandle(handle_t BindingHandle,
             HeapFree(GetProcessHeap(), 0, hManager);
         }
 
-        DPRINT("ScmrCloseServiceHandle() done\n");
+        DPRINT("RCloseServiceHandle() done\n");
         return ERROR_SUCCESS;
     }
 
@@ -292,25 +288,25 @@ ScmrCloseServiceHandle(handle_t BindingHandle,
 
 
 /* Function 1 */
-DWORD
-ScmrControlService(handle_t BindingHandle,
-                   unsigned long hService,
-                   DWORD dwControl,
-                   LPSERVICE_STATUS lpServiceStatus)
+DWORD RControlService(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwControl,
+    LPSERVICE_STATUS lpServiceStatus)
 {
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService;
     ACCESS_MASK DesiredAccess;
     DWORD dwError = ERROR_SUCCESS;
 
-    DPRINT("ScmrControlService() called\n");
+    DPRINT("RControlService() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     /* Check the service handle */
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -381,25 +377,25 @@ ScmrControlService(handle_t BindingHandle,
 
 
 /* Function 2 */
-DWORD
-ScmrDeleteService(handle_t BindingHandle,
-                  unsigned long hService)
+DWORD RDeleteService(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService)
 {
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService;
     DWORD dwError;
 
-    DPRINT("ScmrDeleteService() called\n");
+    DPRINT("RDeleteService() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
         return ERROR_INVALID_HANDLE;
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
-                                  STANDARD_RIGHTS_REQUIRED))
+                                  DELETE))
         return ERROR_ACCESS_DENIED;
 
     lpService = hSvc->ServiceEntry;
@@ -424,26 +420,26 @@ ScmrDeleteService(handle_t BindingHandle,
 
     /* FIXME: Release service database lock */
 
-    DPRINT("ScmrDeleteService() done\n");
+    DPRINT("RDeleteService() done\n");
 
     return dwError;
 }
 
 
 /* Function 3 */
-DWORD
-ScmrLockServiceDatabase(handle_t BindingHandle,
-                        unsigned long hSCManager,
-                        SC_LOCK *hLock)
+DWORD RLockServiceDatabase(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPSC_RPC_LOCK lpLock)
 {
     PMANAGER_HANDLE hMgr;
 
-    DPRINT("ScmrLockServiceDatabase() called\n");
+    DPRINT("RLockServiceDatabase() called\n");
 
-    *hLock = 0;
+    *lpLock = 0;
 
     hMgr = (PMANAGER_HANDLE)hSCManager;
-    if (hMgr->Handle.Tag != MANAGER_TAG)
+    if (!hMgr || hMgr->Handle.Tag != MANAGER_TAG)
         return ERROR_INVALID_HANDLE;
 
     if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess,
@@ -453,20 +449,20 @@ ScmrLockServiceDatabase(handle_t BindingHandle,
 //    return ScmLockDatabase(0, hMgr->0xC, hLock);
 
     /* FIXME: Lock the database */
-    *hLock = 0x12345678; /* Dummy! */
+    *lpLock = (void *)0x12345678; /* Dummy! */
 
     return ERROR_SUCCESS;
 }
 
 
 /* Function 4 */
-DWORD
-ScmrQueryServiceObjectSecurity(handle_t BindingHandle,
-                               unsigned long hService,
-                               DWORD dwSecurityInformation,
-                               unsigned char *lpSecurityDescriptor,
-                               DWORD dwSecuityDescriptorSize,
-                               DWORD *pcbBytesNeeded)
+DWORD RQueryServiceObjectSecurity(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    SECURITY_INFORMATION dwSecurityInformation,
+    LPBYTE lpSecurityDescriptor,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_256K pcbBytesNeeded)
 {
 #if 0
     PSERVICE_HANDLE hSvc;
@@ -476,10 +472,10 @@ ScmrQueryServiceObjectSecurity(handle_t BindingHandle,
     DWORD dwBytesNeeded;
     DWORD dwError;
 
-    DPRINT("ScmrQueryServiceObjectSecurity() called\n");
+    DPRINT("RQueryServiceObjectSecurity() called\n");
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -538,18 +534,18 @@ ScmrQueryServiceObjectSecurity(handle_t BindingHandle,
 
     return dwError;
 #endif
-    DPRINT1("ScmrQueryServiceObjectSecurity() is unimplemented\n");
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 5 */
-DWORD
-ScmrSetServiceObjectSecurity(handle_t BindingHandle,
-                             unsigned long hService,
-                             DWORD dwSecurityInformation,
-                             unsigned char *lpSecurityDescriptor,
-                             DWORD dwSecuityDescriptorSize)
+DWORD RSetServiceObjectSecurity(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwSecurityInformation,
+    LPBYTE lpSecurityDescriptor,
+    DWORD dwSecuityDescriptorSize)
 {
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService;
@@ -559,10 +555,10 @@ ScmrSetServiceObjectSecurity(handle_t BindingHandle,
     NTSTATUS Status;
     DWORD dwError;
 
-    DPRINT1("ScmrSetServiceObjectSecurity() called\n");
+    DPRINT1("RSetServiceObjectSecurity() called\n");
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -642,7 +638,7 @@ ScmrSetServiceObjectSecurity(handle_t BindingHandle,
     if (dwError != ERROR_SUCCESS)
         goto Done;
 
-    DPRINT1("Stub: ScmrSetServiceObjectSecurity() is unimplemented\n");
+    UNIMPLEMENTED;
     dwError = ERROR_SUCCESS;
 //    dwError = ScmWriteSecurityDescriptor(hServiceKey,
 //                                         lpService->lpSecurityDescriptor);
@@ -657,28 +653,28 @@ Done:
 
     /* FIXME: Unlock service database */
 
-    DPRINT("ScmrSetServiceObjectSecurity() done (Error %lu)\n", dwError);
+    DPRINT("RSetServiceObjectSecurity() done (Error %lu)\n", dwError);
 
     return dwError;
 }
 
 
 /* Function 6 */
-DWORD
-ScmrQueryServiceStatus(handle_t BindingHandle,
-                       unsigned long hService,
-                       LPSERVICE_STATUS lpServiceStatus)
+DWORD RQueryServiceStatus(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    LPSERVICE_STATUS lpServiceStatus)
 {
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService;
 
-    DPRINT("ScmrQueryServiceStatus() called\n");
+    DPRINT("RQueryServiceStatus() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -708,14 +704,14 @@ ScmrQueryServiceStatus(handle_t BindingHandle,
 
 
 /* Function 7 */
-DWORD
-ScmrSetServiceStatus(handle_t BindingHandle,
-                     SERVICE_STATUS_HANDLE hServiceStatus,
-                     LPSERVICE_STATUS lpServiceStatus)
+DWORD RSetServiceStatus(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hServiceStatus,
+    LPSERVICE_STATUS lpServiceStatus)
 {
     PSERVICE lpService;
 
-    DPRINT("ScmrSetServiceStatus() called\n");
+    DPRINT("RSetServiceStatus() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
@@ -732,72 +728,70 @@ ScmrSetServiceStatus(handle_t BindingHandle,
                   sizeof(SERVICE_STATUS));
 
     DPRINT("Set %S to %lu\n", lpService->lpDisplayName, lpService->Status.dwCurrentState);
-    DPRINT("ScmrSetServiceStatus() done\n");
+    DPRINT("RSetServiceStatus() done\n");
 
     return ERROR_SUCCESS;
 }
 
 
 /* Function 8 */
-DWORD
-ScmrUnlockServiceDatabase(handle_t BindingHandle,
-                          SC_LOCK hLock)
+DWORD RUnlockServiceDatabase(
+    handle_t BindingHandle,
+    LPSC_RPC_LOCK Lock)
 {
-    DPRINT1("ScmrUnlockServiceDatabase() called\n");
-    /* FIXME */
+    UNIMPLEMENTED;
     return ERROR_SUCCESS;
 }
 
 
 /* Function 9 */
-DWORD
-ScmrNotifyBootConfigStatus(handle_t BindingHandle,
-                           BOOL BootAcceptable)
+DWORD RNotifyBootConfigStatus(
+    handle_t BindingHandle,
+    SVCCTL_HANDLEW lpMachineName,
+    DWORD BootAcceptable)
 {
-    DPRINT1("ScmrNotifyBootConfigStatus() called\n");
-    /* FIXME */
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 10 */
-DWORD
-ScmrSetServiceBitsW(handle_t BindingHandle,
-                    SERVICE_STATUS_HANDLE hServiceStatus,
-                    DWORD dwServiceBits,
-                    BOOL bSetBitsOn,
-                    BOOL bUpdateImmediately,
-                    wchar_t *lpString)
-{
-    DPRINT1("ScmrSetServiceBitsW() called\n");
-    /* FIXME */
+DWORD RSetServiceBitsW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hServiceStatus,
+    DWORD dwServiceBits,
+    int bSetBitsOn,
+    int bUpdateImmediately,
+    wchar_t *lpString)
+{
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 11 */
-DWORD
-ScmrChangeServiceConfigW(handle_t BiningHandle,
-                         unsigned long hService,
-                         DWORD dwServiceType,
-                         DWORD dwStartType,
-                         DWORD dwErrorControl,
-                         wchar_t *lpBinaryPathName,
-                         wchar_t *lpLoadOrderGroup,
-                         DWORD *lpdwTagId, /* in, out, unique */
-                         wchar_t *lpDependencies,
-                         DWORD dwDependenciesLength,
-                         wchar_t *lpServiceStartName,
-                         wchar_t *lpPassword,
-                         DWORD dwPasswordLength,
-                         wchar_t *lpDisplayName)
+DWORD RChangeServiceConfigW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwServiceType,
+    DWORD dwStartType,
+    DWORD dwErrorControl,
+    LPWSTR lpBinaryPathName,
+    LPWSTR lpLoadOrderGroup,
+    LPDWORD lpdwTagId,
+    LPBYTE lpDependencies,
+    DWORD dwDependSize,
+    LPWSTR lpServiceStartName,
+    LPBYTE lpPassword,
+    DWORD dwPwSize,
+    LPWSTR lpDisplayName)
 {
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
     HKEY hServiceKey = NULL;
 
-    DPRINT("ScmrChangeServiceConfigW() called\n");
+    DPRINT("RChangeServiceConfigW() called\n");
     DPRINT("dwServiceType = %lu\n", dwServiceType);
     DPRINT("dwStartType = %lu\n", dwStartType);
     DPRINT("dwErrorControl = %lu\n", dwErrorControl);
@@ -809,7 +803,7 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -973,8 +967,8 @@ ScmrChangeServiceConfigW(handle_t BiningHandle,
     if (lpDependencies != NULL && *lpDependencies != 0)
     {
         dwError = ScmWriteDependencies(hServiceKey,
-                                       lpDependencies,
-                                       dwDependenciesLength);
+                                       (LPWSTR)lpDependencies,
+                                       dwDependSize);
         if (dwError != ERROR_SUCCESS)
             goto done;
     }
@@ -990,7 +984,7 @@ done:
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
-    DPRINT("ScmrChangeServiceConfigW() done (Error %lu)\n", dwError);
+    DPRINT("RChangeServiceConfigW() done (Error %lu)\n", dwError);
 
     return dwError;
 }
@@ -1371,24 +1365,24 @@ ScmCanonDriverImagePath(DWORD dwStartType,
 
 
 /* Function 12 */
-DWORD
-ScmrCreateServiceW(handle_t BindingHandle,
-                   unsigned long hSCManager,
-                   wchar_t *lpServiceName,
-                   wchar_t *lpDisplayName,
-                   DWORD dwDesiredAccess,
-                   DWORD dwServiceType,
-                   DWORD dwStartType,
-                   DWORD dwErrorControl,
-                   wchar_t *lpBinaryPathName,
-                   wchar_t *lpLoadOrderGroup,
-                   DWORD *lpdwTagId, /* in, out */
-                   wchar_t *lpDependencies,
-                   DWORD dwDependenciesLength,
-                   wchar_t *lpServiceStartName,
-                   wchar_t *lpPassword,
-                   DWORD dwPasswordLength,
-                   unsigned long *hService) /* out */
+DWORD RCreateServiceW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPWSTR lpServiceName,
+    LPWSTR lpDisplayName,
+    DWORD dwDesiredAccess,
+    DWORD dwServiceType,
+    DWORD dwStartType,
+    DWORD dwErrorControl,
+    LPWSTR lpBinaryPathName,
+    LPWSTR lpLoadOrderGroup,
+    LPDWORD lpdwTagId,
+    LPBYTE lpDependencies,
+    DWORD dwDependSize,
+    LPWSTR lpServiceStartName,
+    LPBYTE lpPassword,
+    DWORD dwPwSize,
+    LPSC_RPC_HANDLE lpServiceHandle)
 {
     PMANAGER_HANDLE hManager;
     DWORD dwError = ERROR_SUCCESS;
@@ -1397,7 +1391,7 @@ ScmrCreateServiceW(handle_t BindingHandle,
     LPWSTR lpImagePath = NULL;
     HKEY hServiceKey = NULL;
 
-    DPRINT("ScmrCreateServiceW() called\n");
+    DPRINT("RCreateServiceW() called\n");
     DPRINT("lpServiceName = %S\n", lpServiceName);
     DPRINT("lpDisplayName = %S\n", lpDisplayName);
     DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess);
@@ -1411,7 +1405,7 @@ ScmrCreateServiceW(handle_t BindingHandle,
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hManager = (PMANAGER_HANDLE)hSCManager;
-    if (hManager->Handle.Tag != MANAGER_TAG)
+    if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
     {
         DPRINT1("Invalid manager handle!\n");
         return ERROR_INVALID_HANDLE;
@@ -1585,8 +1579,8 @@ ScmrCreateServiceW(handle_t BindingHandle,
     if (lpDependencies != NULL && *lpDependencies != 0)
     {
         dwError = ScmWriteDependencies(hServiceKey,
-                                       lpDependencies,
-                                       dwDependenciesLength);
+                                       (LPWSTR)lpDependencies,
+                                       dwDependSize);
         if (dwError != ERROR_SUCCESS)
             goto done;
     }
@@ -1612,8 +1606,8 @@ done:;
 
     if (dwError == ERROR_SUCCESS)
     {
-        DPRINT("hService %lx\n", hServiceHandle);
-        *hService = (unsigned long)hServiceHandle;
+        DPRINT("hService %p\n", hServiceHandle);
+        *lpServiceHandle = (unsigned long)hServiceHandle; /* FIXME: 64 bit portability */
 
         if (lpdwTagId != NULL)
             *lpdwTagId = lpService->dwTag;
@@ -1639,45 +1633,45 @@ done:;
     if (lpImagePath != NULL)
         HeapFree(GetProcessHeap(), 0, lpImagePath);
 
-    DPRINT("ScmrCreateServiceW() done (Error %lu)\n", dwError);
+    DPRINT("RCreateServiceW() done (Error %lu)\n", dwError);
 
     return dwError;
 }
 
 
 /* Function 13 */
-DWORD
-ScmrEnumDependentServicesW(handle_t BindingHandle,
-                           unsigned long hService,
-                           DWORD dwServiceState,
-                           unsigned char *lpServices,
-                           DWORD cbBufSize,
-                           DWORD *pcbBytesNeeded,
-                           DWORD *lpServicesReturned)
+DWORD REnumDependentServicesW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwServiceState,
+    LPBYTE lpServices,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_256K pcbBytesNeeded,
+    LPBOUNDED_DWORD_256K lpServicesReturned)
 {
     DWORD dwError = ERROR_SUCCESS;
 
-    DPRINT1("ScmrEnumDependentServicesW() called\n");
+    UNIMPLEMENTED;
     *pcbBytesNeeded = 0;
     *lpServicesReturned = 0;
 
-    DPRINT1("ScmrEnumDependentServicesW() done (Error %lu)\n", dwError);
+    DPRINT1("REnumDependentServicesW() done (Error %lu)\n", dwError);
 
     return dwError;
 }
 
 
 /* Function 14 */
-DWORD
-ScmrEnumServicesStatusW(handle_t BindingHandle,
-                        unsigned long hSCManager,
-                        DWORD dwServiceType,
-                        DWORD dwServiceState,
-                        unsigned char *lpServices,
-                        DWORD dwBufSize,
-                        DWORD *pcbBytesNeeded,
-                        DWORD *lpServicesReturned,
-                        DWORD *lpResumeHandle)
+DWORD REnumServicesStatusW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    DWORD dwServiceType,
+    DWORD dwServiceState,
+    LPBYTE lpBuffer,
+    DWORD dwBufSize,
+    LPBOUNDED_DWORD_256K pcbBytesNeeded,
+    LPBOUNDED_DWORD_256K lpServicesReturned,
+    LPBOUNDED_DWORD_256K lpResumeHandle)
 {
     PMANAGER_HANDLE hManager;
     PSERVICE lpService;
@@ -1692,13 +1686,13 @@ ScmrEnumServicesStatusW(handle_t BindingHandle,
     LPENUM_SERVICE_STATUSW lpStatusPtr;
     LPWSTR lpStringPtr;
 
-    DPRINT("ScmrEnumServicesStatusW() called\n");
+    DPRINT("REnumServicesStatusW() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hManager = (PMANAGER_HANDLE)hSCManager;
-    if (hManager->Handle.Tag != MANAGER_TAG)
+    if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
     {
         DPRINT1("Invalid manager handle!\n");
         return ERROR_INVALID_HANDLE;
@@ -1801,8 +1795,8 @@ ScmrEnumServicesStatusW(handle_t BindingHandle,
     *lpServicesReturned = dwServiceCount;
     *pcbBytesNeeded = dwRequiredSize;
 
-    lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpServices;
-    lpStringPtr = (LPWSTR)((ULONG_PTR)lpServices +
+    lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpBuffer;
+    lpStringPtr = (LPWSTR)((ULONG_PTR)lpBuffer +
                            dwServiceCount * sizeof(ENUM_SERVICE_STATUSW));
 
     dwRequiredSize = 0;
@@ -1833,13 +1827,13 @@ ScmrEnumServicesStatusW(handle_t BindingHandle,
             /* Copy the service name */
             wcscpy(lpStringPtr,
                    CurrentService->lpServiceName);
-            lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
+            lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
             lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
 
             /* Copy the display name */
             wcscpy(lpStringPtr,
                    CurrentService->lpDisplayName);
-            lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
+            lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
             lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
 
             /* Copy the status information */
@@ -1860,24 +1854,24 @@ ScmrEnumServicesStatusW(handle_t BindingHandle,
 Done:;
     /* FIXME: Unlock the service list */
 
-    DPRINT("ScmrEnumServicesStatusW() done (Error %lu)\n", dwError);
+    DPRINT("REnumServicesStatusW() done (Error %lu)\n", dwError);
 
     return dwError;
 }
 
 
 /* Function 15 */
-DWORD
-ScmrOpenSCManagerW(handle_t BindingHandle,
-                   wchar_t *lpMachineName,
-                   wchar_t *lpDatabaseName,
-                   DWORD dwDesiredAccess,
-                   unsigned long *hScm)
+DWORD ROpenSCManagerW(
+    handle_t BindingHandle,
+    LPWSTR lpMachineName,
+    LPWSTR lpDatabaseName,
+    DWORD dwDesiredAccess,
+    LPSC_RPC_HANDLE lpScHandle)
 {
     DWORD dwError;
     SC_HANDLE hHandle;
 
-    DPRINT("ScmrOpenSCManagerW() called\n");
+    DPRINT("ROpenSCManagerW() called\n");
     DPRINT("lpMachineName = %p\n", lpMachineName);
     DPRINT("lpMachineName: %S\n", lpMachineName);
     DPRINT("lpDataBaseName = %p\n", lpDatabaseName);
@@ -1887,6 +1881,9 @@ ScmrOpenSCManagerW(handle_t BindingHandle,
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
+    if (!lpScHandle)
+        return ERROR_INVALID_PARAMETER;
+
     dwError = ScmCreateManagerHandle(lpDatabaseName,
                                      &hHandle);
     if (dwError != ERROR_SUCCESS)
@@ -1905,30 +1902,30 @@ ScmrOpenSCManagerW(handle_t BindingHandle,
         return dwError;
     }
 
-    *hScm = (unsigned long)hHandle;
-    DPRINT("*hScm = %x\n", *hScm);
+    *lpScHandle = (unsigned long)hHandle; /* FIXME: 64 bit portability */
+    DPRINT("*hScm = %p\n", *lpScHandle);
 
-    DPRINT("ScmrOpenSCManagerW() done\n");
+    DPRINT("ROpenSCManagerW() done\n");
 
     return ERROR_SUCCESS;
 }
 
 
 /* Function 16 */
-DWORD
-ScmrOpenServiceW(handle_t BindingHandle,
-                 unsigned long hSCManager,
-                 wchar_t *lpServiceName,
-                 DWORD dwDesiredAccess,
-                 unsigned long *hService)
+DWORD ROpenServiceW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPWSTR lpServiceName,
+    DWORD dwDesiredAccess,
+    LPSC_RPC_HANDLE lpServiceHandle)
 {
     PSERVICE lpService;
     PMANAGER_HANDLE hManager;
     SC_HANDLE hHandle;
     DWORD dwError;
 
-    DPRINT("ScmrOpenServiceW() called\n");
-    DPRINT("hSCManager = %x\n", hSCManager);
+    DPRINT("ROpenServiceW() called\n");
+    DPRINT("hSCManager = %p\n", hSCManager);
     DPRINT("lpServiceName = %p\n", lpServiceName);
     DPRINT("lpServiceName: %S\n", lpServiceName);
     DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
@@ -1936,8 +1933,11 @@ ScmrOpenServiceW(handle_t BindingHandle,
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
+    if (!lpServiceHandle)
+        return ERROR_INVALID_PARAMETER;
+
     hManager = (PMANAGER_HANDLE)hSCManager;
-    if (hManager->Handle.Tag != MANAGER_TAG)
+    if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
     {
         DPRINT1("Invalid manager handle!\n");
         return ERROR_INVALID_HANDLE;
@@ -1972,23 +1972,24 @@ ScmrOpenServiceW(handle_t BindingHandle,
         return dwError;
     }
 
-    *hService = (unsigned long)hHandle;
-    DPRINT("*hService = %x\n", *hService);
+    *lpServiceHandle = (unsigned long)hHandle; /* FIXME: 64 bit portability */
+    DPRINT("*hService = %p\n", *lpServiceHandle);
 
-    DPRINT("ScmrOpenServiceW() done\n");
+    DPRINT("ROpenServiceW() done\n");
 
     return ERROR_SUCCESS;
 }
 
 
 /* Function 17 */
-DWORD
-ScmrQueryServiceConfigW(handle_t BindingHandle,
-                        unsigned long hService,
-                        unsigned char *lpServiceConfig,
-                        DWORD cbBufSize,
-                        DWORD *pcbBytesNeeded)
+DWORD RQueryServiceConfigW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    LPBYTE lpBuf, //LPQUERY_SERVICE_CONFIGW lpServiceConfig,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_8K pcbBytesNeeded)
 {
+    LPQUERY_SERVICE_CONFIGW lpServiceConfig = (LPQUERY_SERVICE_CONFIGW)lpBuf;
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
@@ -1999,13 +2000,13 @@ ScmrQueryServiceConfigW(handle_t BindingHandle,
     LPQUERY_SERVICE_CONFIGW lpConfig;
     LPWSTR lpStr;
 
-    DPRINT("ScmrQueryServiceConfigW() called\n");
+    DPRINT("RQueryServiceConfigW() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -2135,44 +2136,43 @@ Done:;
 
     /* FIXME: Unlock the service database */
 
-    DPRINT("ScmrQueryServiceConfigW() done\n");
+    DPRINT("RQueryServiceConfigW() done\n");
 
     return dwError;
 }
 
 
 /* Function 18 */
-DWORD
-ScmrQueryServiceLockStatusW(handle_t BindingHandle,
-                            unsigned long hSCManager,
-                            unsigned char *lpLockStatus,   /* [out, unique, size_is(cbBufSize)] */
-                            DWORD cbBufSize,       /* [in] */
-                            DWORD *pcbBytesNeeded) /* [out] */
+DWORD RQueryServiceLockStatusW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_4K pcbBytesNeeded)
 {
-    DPRINT1("ScmrQueryServiceLockStatusW() called\n");
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 19 */
-DWORD
-ScmrStartServiceW(handle_t BindingHandle,
-                  unsigned long hService,
-                  DWORD dwNumServiceArgs,
-                  unsigned char *lpServiceArgBuffer,
-                  DWORD cbBufSize)
+DWORD RStartServiceW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD argc,
+    LPSTRING_PTRSW argv)
 {
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
 
-    DPRINT("ScmrStartServiceW() called\n");
+    DPRINT("RStartServiceW() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -2198,28 +2198,33 @@ ScmrStartServiceW(handle_t BindingHandle,
     if (lpService->bDeleted)
         return ERROR_SERVICE_MARKED_FOR_DELETE;
 
+    if (argv) {
+        UNIMPLEMENTED;
+        argv = NULL;
+    }
+
     /* Start the service */
-    dwError = ScmStartService(lpService, (LPWSTR)lpServiceArgBuffer);
+    dwError = ScmStartService(lpService, argc, (LPWSTR *)argv);
 
     return dwError;
 }
 
 
 /* Function 20 */
-DWORD
-ScmrGetServiceDisplayNameW(handle_t BindingHandle,
-                           unsigned long hSCManager,
-                           wchar_t *lpServiceName,
-                           wchar_t *lpDisplayName, /* [out, unique] */
-                           DWORD *lpcchBuffer)
+DWORD RGetServiceDisplayNameW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPWSTR lpServiceName,
+    LPWSTR lpDisplayName,
+    DWORD *lpcchBuffer)
 {
 //    PMANAGER_HANDLE hManager;
     PSERVICE lpService;
     DWORD dwLength;
     DWORD dwError;
 
-    DPRINT("ScmrGetServiceDisplayNameW() called\n");
-    DPRINT("hSCManager = %x\n", hSCManager);
+    DPRINT("RGetServiceDisplayNameW() called\n");
+    DPRINT("hSCManager = %p\n", hSCManager);
     DPRINT("lpServiceName: %S\n", lpServiceName);
     DPRINT("lpDisplayName: %p\n", lpDisplayName);
     DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
@@ -2236,15 +2241,37 @@ ScmrGetServiceDisplayNameW(handle_t BindingHandle,
     if (lpService == NULL)
     {
         DPRINT1("Could not find a service!\n");
+
+        /* If the service could not be found and lpcchBuffer is 0, windows
+           puts null in lpDisplayName and puts 1 in lpcchBuffer */
+        if (*lpcchBuffer == 0)
+        {
+            *lpcchBuffer = 1;
+            *lpDisplayName = '\0';
+        }
+
         return ERROR_SERVICE_DOES_NOT_EXIST;
     }
 
-    dwLength = wcslen(lpService->lpDisplayName) + 1;
+    if (!lpService->lpDisplayName)
+    {
+        dwLength = wcslen(lpService->lpServiceName);
 
-    if (lpDisplayName != NULL &&
-        *lpcchBuffer >= dwLength)
+        if (lpServiceName != NULL &&
+            *lpcchBuffer > dwLength)
+        {
+            wcscpy(lpDisplayName, lpService->lpServiceName);
+        }
+    }
+    else
     {
-        wcscpy(lpDisplayName, lpService->lpDisplayName);
+        dwLength = wcslen(lpService->lpDisplayName);
+
+        if (lpDisplayName != NULL &&
+            *lpcchBuffer > dwLength)
+        {
+            wcscpy(lpDisplayName, lpService->lpDisplayName);
+        }
     }
 
     dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
@@ -2256,20 +2283,20 @@ ScmrGetServiceDisplayNameW(handle_t BindingHandle,
 
 
 /* Function 21 */
-DWORD
-ScmrGetServiceKeyNameW(handle_t BindingHandle,
-                       unsigned long hSCManager,
-                       wchar_t *lpDisplayName,
-                       wchar_t *lpServiceName, /* [out, unique] */
-                       DWORD *lpcchBuffer)
+DWORD RGetServiceKeyNameW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPWSTR lpDisplayName,
+    LPWSTR lpServiceName,
+    DWORD *lpcchBuffer)
 {
 //    PMANAGER_HANDLE hManager;
     PSERVICE lpService;
     DWORD dwLength;
     DWORD dwError;
 
-    DPRINT("ScmrGetServiceKeyNameW() called\n");
-    DPRINT("hSCManager = %x\n", hSCManager);
+    DPRINT("RGetServiceKeyNameW() called\n");
+    DPRINT("hSCManager = %p\n", hSCManager);
     DPRINT("lpDisplayName: %S\n", lpDisplayName);
     DPRINT("lpServiceName: %p\n", lpServiceName);
     DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
@@ -2286,97 +2313,108 @@ ScmrGetServiceKeyNameW(handle_t BindingHandle,
     if (lpService == NULL)
     {
         DPRINT1("Could not find a service!\n");
+
+        /* If the service could not be found and lpcchBuffer is 0, windows
+           puts null in lpDisplayName and puts 2 in lpcchBuffer */
+        if (*lpcchBuffer == 0)
+        {
+            *lpcchBuffer = 2;
+            *lpServiceName = '\0';
+        }
+
         return ERROR_SERVICE_DOES_NOT_EXIST;
     }
 
-    dwLength = wcslen(lpService->lpServiceName) + 1;
+    dwLength = wcslen(lpService->lpServiceName);
 
     if (lpServiceName != NULL &&
-        *lpcchBuffer >= dwLength)
+        *lpcchBuffer > dwLength)
     {
         wcscpy(lpServiceName, lpService->lpServiceName);
+        *lpcchBuffer = dwLength;
+        return ERROR_SUCCESS;
     }
 
     dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
 
-    *lpcchBuffer = dwLength;
+    *lpcchBuffer = dwLength * 2;
 
     return dwError;
 }
 
 
 /* Function 22 */
-DWORD
-ScmrSetServiceBitsA(handle_t BindingHandle,
-                    SERVICE_STATUS_HANDLE hServiceStatus,
-                    DWORD dwServiceBits,
-                    BOOL bSetBitsOn,
-                    BOOL bUpdateImmediately,
-                    char *lpString)
-{
-    DPRINT1("ScmrSetServiceBitsA() is unimplemented\n");
+DWORD RSetServiceBitsA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hServiceStatus,
+    DWORD dwServiceBits,
+    int bSetBitsOn,
+    int bUpdateImmediately,
+    char *lpString)
+{
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 23 */
-DWORD
-ScmrChangeServiceConfigA(handle_t BiningHandle,
-                         unsigned long hService,
-                         DWORD dwServiceType,
-                         DWORD dwStartType,
-                         DWORD dwErrorControl,
-                         char *lpBinaryPathName,
-                         char *lpLoadOrderGroup,
-                         DWORD *lpdwTagId,
-                         char *lpDependencies,
-                         DWORD dwDependenciesLength,
-                         char *lpServiceStartName,
-                         char *lpPassword,
-                         DWORD dwPasswordLength,
-                         char *lpDisplayName)
-{
-    DPRINT1("ScmrChangeServiceConfigA() is unimplemented\n");
+DWORD RChangeServiceConfigA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwServiceType,
+    DWORD dwStartType,
+    DWORD dwErrorControl,
+    LPSTR lpBinaryPathName,
+    LPSTR lpLoadOrderGroup,
+    LPDWORD lpdwTagId,
+    LPSTR lpDependencies,
+    DWORD dwDependSize,
+    LPSTR lpServiceStartName,
+    LPBYTE lpPassword,
+    DWORD dwPwSize,
+    LPSTR lpDisplayName)
+{
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 24 */
-DWORD
-ScmrCreateServiceA(handle_t BindingHandle,
-                   unsigned long hSCManager,
-                   char *lpServiceName,
-                   char *lpDisplayName,
-                   DWORD dwDesiredAccess,
-                   DWORD dwServiceType,
-                   DWORD dwStartType,
-                   DWORD dwErrorControl,
-                   char *lpBinaryPathName,
-                   char *lpLoadOrderGroup,
-                   DWORD *lpdwTagId, /* in, out */
-                   char *lpDependencies,
-                   DWORD dwDependenciesLength,
-                   char *lpServiceStartName,
-                   char *lpPassword,
-                   DWORD dwPasswordLength,
-                   unsigned long *hService) /* out */
-{
-    DPRINT1("ScmrCreateServiceA() is unimplemented\n");
+DWORD RCreateServiceA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPSTR lpServiceName,
+    LPSTR lpDisplayName,
+    DWORD dwDesiredAccess,
+    DWORD dwServiceType,
+    DWORD dwStartType,
+    DWORD dwErrorControl,
+    LPSTR lpBinaryPathName,
+    LPSTR lpLoadOrderGroup,
+    LPDWORD lpdwTagId,
+    LPBYTE lpDependencies,
+    DWORD dwDependSize,
+    LPSTR lpServiceStartName,
+    LPBYTE lpPassword,
+    DWORD dwPwSize,
+    LPSC_RPC_HANDLE lpServiceHandle)
+{
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 25 */
-DWORD
-ScmrEnumDependentServicesA(handle_t BindingHandle,
-                           unsigned long hService,
-                           DWORD dwServiceState,
-                           unsigned char *lpServices,
-                           DWORD cbBufSize,
-                           DWORD *pcbBytesNeeded,
-                           DWORD *lpServicesReturned)
-{
-    DPRINT1("ScmrEnumDependentServicesA() is unimplemented\n");
+DWORD REnumDependentServicesA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwServiceState,
+    LPBYTE lpServices,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_256K pcbBytesNeeded,
+    LPBOUNDED_DWORD_256K lpServicesReturned)
+{
+    UNIMPLEMENTED;
     *pcbBytesNeeded = 0;
     *lpServicesReturned = 0;
     return ERROR_CALL_NOT_IMPLEMENTED;
@@ -2384,35 +2422,35 @@ ScmrEnumDependentServicesA(handle_t BindingHandle,
 
 
 /* Function 26 */
-DWORD
-ScmrEnumServicesStatusA(handle_t BindingHandle,
-                        unsigned long hSCManager,
-                        DWORD dwServiceType,
-                        DWORD dwServiceState,
-                        unsigned char *lpServices,
-                        DWORD dwBufSize,
-                        DWORD *pcbBytesNeeded,
-                        DWORD *lpServicesReturned,
-                        unsigned long *lpResumeHandle)
-{
-    DPRINT1("ScmrEnumServicesAtatusA() is unimplemented\n");
+DWORD REnumServicesStatusA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    DWORD dwServiceType,
+    DWORD dwServiceState,
+    LPBYTE lpBuffer,
+    DWORD dwBufSize,
+    LPBOUNDED_DWORD_256K pcbBytesNeeded,
+    LPBOUNDED_DWORD_256K lpServicesReturned,
+    LPBOUNDED_DWORD_256K lpResumeHandle)
+{
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 27 */
-DWORD
-ScmrOpenSCManagerA(handle_t BindingHandle,
-                   char *lpMachineName,
-                   char *lpDatabaseName,
-                   DWORD dwDesiredAccess,
-                   unsigned long *hScm)
+DWORD ROpenSCManagerA(
+    handle_t BindingHandle,
+    LPSTR lpMachineName,
+    LPSTR lpDatabaseName,
+    DWORD dwDesiredAccess,
+    LPSC_RPC_HANDLE lpScHandle)
 {
     UNICODE_STRING MachineName;
     UNICODE_STRING DatabaseName;
     DWORD dwError;
 
-    DPRINT("ScmrOpenSCManagerA() called\n");
+    DPRINT("ROpenSCManagerA() called\n");
 
     if (lpMachineName)
         RtlCreateUnicodeStringFromAsciiz(&MachineName,
@@ -2422,11 +2460,11 @@ ScmrOpenSCManagerA(handle_t BindingHandle,
         RtlCreateUnicodeStringFromAsciiz(&DatabaseName,
                                          lpDatabaseName);
 
-    dwError = ScmrOpenSCManagerW(BindingHandle,
+    dwError = ROpenSCManagerW(BindingHandle,
                                  lpMachineName ? MachineName.Buffer : NULL,
                                  lpDatabaseName ? DatabaseName.Buffer : NULL,
                                  dwDesiredAccess,
-                                 hScm);
+                                 lpScHandle);
 
     if (lpMachineName)
         RtlFreeUnicodeString(&MachineName);
@@ -2439,26 +2477,26 @@ ScmrOpenSCManagerA(handle_t BindingHandle,
 
 
 /* Function 28 */
-DWORD
-ScmrOpenServiceA(handle_t BindingHandle,
-                 unsigned long hSCManager,
-                 char *lpServiceName,
-                 DWORD dwDesiredAccess,
-                 unsigned long *hService)
+DWORD ROpenServiceA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPSTR lpServiceName,
+    DWORD dwDesiredAccess,
+    LPSC_RPC_HANDLE lpServiceHandle)
 {
     UNICODE_STRING ServiceName;
     DWORD dwError;
 
-    DPRINT("ScmrOpenServiceA() called\n");
+    DPRINT("ROpenServiceA() called\n");
 
     RtlCreateUnicodeStringFromAsciiz(&ServiceName,
                                      lpServiceName);
 
-    dwError = ScmrOpenServiceW(BindingHandle,
+    dwError = ROpenServiceW(BindingHandle,
                                hSCManager,
                                ServiceName.Buffer,
                                dwDesiredAccess,
-                               hService);
+                               lpServiceHandle);
 
     RtlFreeUnicodeString(&ServiceName);
 
@@ -2467,50 +2505,49 @@ ScmrOpenServiceA(handle_t BindingHandle,
 
 
 /* Function 29 */
-DWORD
-ScmrQueryServiceConfigA(handle_t BindingHandle,
-                        unsigned long hService,
-                        unsigned char *lpServiceConfig,
-                        DWORD cbBufSize,
-                        DWORD *pcbBytesNeeded)
+DWORD RQueryServiceConfigA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    LPBYTE lpBuf, //LPQUERY_SERVICE_CONFIGA lpServiceConfig,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_8K pcbBytesNeeded)
 {
-    DPRINT1("ScmrQueryServiceConfigA() is unimplemented\n");
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 30 */
-DWORD
-ScmrQueryServiceLockStatusA(handle_t BindingHandle,
-                            unsigned long hSCManager,
-                            unsigned char *lpLockStatus,   /* [out, unique, size_is(cbBufSize)] */
-                            DWORD cbBufSize,       /* [in] */
-                            DWORD *pcbBytesNeeded) /* [out] */
+DWORD RQueryServiceLockStatusA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_4K pcbBytesNeeded)
 {
-    DPRINT1("ScmrQueryServiceLockStatusA() called\n");
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 31 */
-DWORD
-ScmrStartServiceA(handle_t BindingHandle,
-                  unsigned long hService,
-                  DWORD dwNumServiceArgs,
-                  unsigned char *lpServiceArgBuffer,
-                  DWORD cbBufSize)
+DWORD RStartServiceA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD argc,
+    LPSTRING_PTRSA argv)
 {
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
 
-    DPRINT1("ScmrStartServiceA() called\n");
+    DPRINT1("RStartServiceA() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -2539,7 +2576,7 @@ ScmrStartServiceA(handle_t BindingHandle,
     /* FIXME: Convert argument vector to Unicode */
 
     /* Start the service */
-    dwError = ScmStartService(lpService, NULL);
+    dwError = ScmStartService(lpService, 0, NULL);
 
     /* FIXME: Free argument vector */
 
@@ -2548,84 +2585,239 @@ ScmrStartServiceA(handle_t BindingHandle,
 
 
 /* Function 32 */
-DWORD
-ScmrGetServiceDisplayNameA(handle_t BindingHandle,
-                           unsigned long hSCManager,
-                           char *lpServiceName,
-                           char *lpDisplayName, /* [out, unique] */
-                           DWORD *lpcchBuffer)
+DWORD RGetServiceDisplayNameA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPSTR lpServiceName,
+    LPSTR lpDisplayName,
+    LPBOUNDED_DWORD_4K lpcchBuffer)
 {
-    DPRINT1("ScmrGetServiceDisplayNameA() is unimplemented\n");
-    return ERROR_CALL_NOT_IMPLEMENTED;
+//    PMANAGER_HANDLE hManager;
+    PSERVICE lpService;
+    DWORD dwLength;
+    DWORD dwError;
+    LPWSTR lpServiceNameW;
+
+    DPRINT("RGetServiceDisplayNameA() called\n");
+    DPRINT("hSCManager = %p\n", hSCManager);
+    DPRINT("lpServiceName: %s\n", lpServiceName);
+    DPRINT("lpDisplayName: %p\n", lpDisplayName);
+    DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
+
+//    hManager = (PMANAGER_HANDLE)hSCManager;
+//    if (hManager->Handle.Tag != MANAGER_TAG)
+//    {
+//        DPRINT1("Invalid manager handle!\n");
+//        return ERROR_INVALID_HANDLE;
+//    }
+
+    dwLength = strlen(lpServiceName) + 1;
+    lpServiceNameW = HeapAlloc(GetProcessHeap(),
+                               HEAP_ZERO_MEMORY,
+                               dwLength * sizeof(WCHAR));
+    if (!lpServiceNameW)
+        return ERROR_NOT_ENOUGH_MEMORY;
+
+    MultiByteToWideChar(CP_ACP,
+                        0,
+                        lpServiceName,
+                        strlen(lpServiceName),
+                        lpServiceNameW,
+                        dwLength);
+
+    lpService = ScmGetServiceEntryByName(lpServiceNameW);
+
+    HeapFree(GetProcessHeap(), 0, lpServiceNameW);
+
+    if (lpService == NULL)
+    {
+        DPRINT1("Could not find a service!\n");
+
+        /* If the service could not be found and lpcchBuffer is 0, windows
+           puts null in lpDisplayName and puts 1 in lpcchBuffer */
+        if (*lpcchBuffer == 0)
+        {
+            *lpcchBuffer = 1;
+            *lpDisplayName = '\0';
+        }
+        return ERROR_SERVICE_DOES_NOT_EXIST;
+    }
+
+    if (!lpService->lpDisplayName)
+    {
+        dwLength = wcslen(lpService->lpServiceName);
+        if (lpServiceName != NULL &&
+            *lpcchBuffer > dwLength)
+        {
+            WideCharToMultiByte(CP_ACP,
+                                0,
+                                lpService->lpServiceName,
+                                wcslen(lpService->lpServiceName),
+                                lpDisplayName,
+                                *lpcchBuffer,
+                                NULL,
+                                NULL);
+            return ERROR_SUCCESS;
+        }
+    }
+    else
+    {
+        dwLength = wcslen(lpService->lpDisplayName);
+        if (lpDisplayName != NULL &&
+            *lpcchBuffer > dwLength)
+        {
+            WideCharToMultiByte(CP_ACP,
+                                0,
+                                lpService->lpDisplayName,
+                                wcslen(lpService->lpDisplayName),
+                                lpDisplayName,
+                                *lpcchBuffer,
+                                NULL,
+                                NULL);
+            return ERROR_SUCCESS;
+        }
+    }
+
+    dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
+
+    *lpcchBuffer = dwLength * 2;
+
+    return dwError;
 }
 
 
 /* Function 33 */
-DWORD
-ScmrGetServiceKeyNameA(handle_t BindingHandle,
-                       unsigned long hSCManager,
-                       char *lpDisplayName,
-                       char *lpServiceName, /* [out, unique] */
-                       DWORD *lpcchBuffer)
+DWORD RGetServiceKeyNameA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    LPSTR lpDisplayName,
+    LPSTR lpServiceName,
+    LPBOUNDED_DWORD_4K lpcchBuffer)
 {
-    DPRINT1("ScmrGetServiceKeyNameA() is unimplemented\n");
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    PSERVICE lpService;
+    DWORD dwLength;
+    DWORD dwError;
+    LPWSTR lpDisplayNameW;
+
+    DPRINT("RGetServiceKeyNameA() called\n");
+    DPRINT("hSCManager = %p\n", hSCManager);
+    DPRINT("lpDisplayName: %s\n", lpDisplayName);
+    DPRINT("lpServiceName: %p\n", lpServiceName);
+    DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
+
+    dwLength = strlen(lpDisplayName) + 1;
+    lpDisplayNameW = HeapAlloc(GetProcessHeap(),
+                               HEAP_ZERO_MEMORY,
+                               dwLength * sizeof(WCHAR));
+    if (!lpDisplayNameW)
+        return ERROR_NOT_ENOUGH_MEMORY;
+
+    MultiByteToWideChar(CP_ACP,
+                        0,
+                        lpDisplayName,
+                        strlen(lpDisplayName),
+                        lpDisplayNameW,
+                        dwLength);
+
+    lpService = ScmGetServiceEntryByDisplayName(lpDisplayNameW);
+
+    HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
+
+    if (lpService == NULL)
+    {
+        DPRINT1("Could not find the service!\n");
+
+        /* If the service could not be found and lpcchBuffer is 0,
+           put null in lpDisplayName and puts 1 in lpcchBuffer, verified WINXP. */
+        if (*lpcchBuffer == 0)
+        {
+            *lpcchBuffer = 1;
+            *lpServiceName = '\0';
+        }
+
+        return ERROR_SERVICE_DOES_NOT_EXIST;
+    }
+
+    dwLength = wcslen(lpService->lpServiceName);
+    if (lpService != NULL &&
+        *lpcchBuffer > dwLength)
+    {
+        WideCharToMultiByte(CP_ACP,
+                            0,
+                            lpService->lpServiceName,
+                            wcslen(lpService->lpServiceName),
+                            lpServiceName,
+                            dwLength,
+                            NULL,
+                            NULL);
+        return ERROR_SUCCESS;
+    }
+
+    dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
+
+    *lpcchBuffer = dwLength * 2;
+
+    return dwError;
 }
 
 
 /* Function 34 */
-DWORD
-ScmrGetCurrentGroupStateW(handle_t BindingHandle)
+DWORD RGetCurrentGroupStateW(
+    handle_t BindingHandle)
 {
-    DPRINT1("ScmrGetCurrentGroupStateW() is unimplemented\n");
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 35 */
-DWORD
-ScmrEnumServiceGroupW(handle_t BindingHandle)
+DWORD REnumServiceGroupW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    DWORD dwServiceType,
+    DWORD dwServiceState,
+    LPBYTE lpBuffer,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_256K pcbBytesNeeded,
+    LPBOUNDED_DWORD_256K lpServicesReturned,
+    LPBOUNDED_DWORD_256K lpResumeIndex,
+    LPCWSTR pszGroupName)
 {
-    DPRINT1("ScmrEnumServiceGroupW() is unimplemented\n");
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 36 */
-DWORD
-ScmrChangeServiceConfig2A(handle_t BindingHandle,
-                          unsigned long hService,
-                          DWORD dwInfoLevel,
-                          unsigned char *lpInfo,
-                          DWORD dwInfoSize)
+DWORD RChangeServiceConfig2A(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    SC_RPC_CONFIG_INFOA Info)
 {
-    DPRINT1("ScmrChangeServiceConfig2A() is unimplemented\n");
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 37 */
-DWORD
-ScmrChangeServiceConfig2W(handle_t BindingHandle,
-                          unsigned long hService,
-                          DWORD dwInfoLevel,
-                          unsigned char *lpInfo,
-                          DWORD dwInfoSize)
+DWORD RChangeServiceConfig2W(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    SC_RPC_CONFIG_INFOW Info)
 {
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
     HKEY hServiceKey = NULL;
 
-    DPRINT("ScmrChangeServiceConfig2W() called\n");
-    DPRINT("dwInfoLevel = %lu\n", dwInfoLevel);
-    DPRINT("dwInfoSize = %lu\n", dwInfoSize);
+    DPRINT("RChangeServiceConfig2W() called\n");
+    DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -2661,12 +2853,12 @@ ScmrChangeServiceConfig2W(handle_t BindingHandle,
     if (dwError != ERROR_SUCCESS)
         goto done;
 
-    if (dwInfoLevel & SERVICE_CONFIG_DESCRIPTION)
+    if (Info.dwInfoLevel & SERVICE_CONFIG_DESCRIPTION)
     {
         LPSERVICE_DESCRIPTIONW lpServiceDescription;
 
-        lpServiceDescription = (LPSERVICE_DESCRIPTIONW)lpInfo;
-        lpServiceDescription->lpDescription = (LPWSTR)(lpInfo + sizeof(LPSERVICE_DESCRIPTIONW));
+        lpServiceDescription = (LPSERVICE_DESCRIPTIONW)&Info;
+        lpServiceDescription->lpDescription = (LPWSTR)(&Info + sizeof(LPSERVICE_DESCRIPTIONW));
 
         if (lpServiceDescription != NULL &&
             lpServiceDescription->lpDescription != NULL)
@@ -2682,9 +2874,9 @@ ScmrChangeServiceConfig2W(handle_t BindingHandle,
                 goto done;
         }
     }
-    else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS)
+    else if (Info.dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS)
     {
-        DPRINT1("SERVICE_CONFIG_FAILURE_ACTIONS not implemented\n");
+        UNIMPLEMENTED;
         dwError = ERROR_CALL_NOT_IMPLEMENTED;
         goto done;
     }
@@ -2694,34 +2886,34 @@ done:
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
-    DPRINT("ScmrChangeServiceConfig2W() done (Error %lu)\n", dwError);
+    DPRINT("RChangeServiceConfig2W() done (Error %lu)\n", dwError);
 
     return dwError;
 }
 
 
 /* Function 38 */
-DWORD
-ScmrQueryServiceConfig2A(handle_t BindingHandle,
-                         unsigned long hService,
-                         DWORD dwInfoLevel,
-                         unsigned char *lpBuffer,
-                         DWORD cbBufSize,
-                         DWORD *pcbBytesNeeded)
-{
-    DPRINT1("ScmrQueryServiceConfig2A() is unimplemented\n");
+DWORD RQueryServiceConfig2A(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwInfoLevel,
+    LPBYTE lpBuffer,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_8K pcbBytesNeeded)
+{
+    UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 39 */
-DWORD
-ScmrQueryServiceConfig2W(handle_t BindingHandle,
-                         unsigned long hService,
-                         DWORD dwInfoLevel,
-                         unsigned char *lpBuffer,
-                         DWORD cbBufSize,
-                         DWORD *pcbBytesNeeded)
+DWORD RQueryServiceConfig2W(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwInfoLevel,
+    LPBYTE lpBuffer,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_8K pcbBytesNeeded)
 {
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
@@ -2730,13 +2922,13 @@ ScmrQueryServiceConfig2W(handle_t BindingHandle,
     DWORD dwRequiredSize;
     LPWSTR lpDescription = NULL;
 
-    DPRINT("ScmrQueryServiceConfig2W() called\n");
+    DPRINT("RQueryServiceConfig2W() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -2792,7 +2984,7 @@ ScmrQueryServiceConfig2W(handle_t BindingHandle,
     }
     else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS)
     {
-        DPRINT1("SERVICE_CONFIG_FAILURE_ACTIONS not implemented\n");
+        UNIMPLEMENTED;
         dwError = ERROR_CALL_NOT_IMPLEMENTED;
         goto done;
     }
@@ -2806,26 +2998,26 @@ done:
 
     /* FIXME: Unlock database */
 
-    DPRINT("ScmrQueryServiceConfig2W() done (Error %lu)\n", dwError);
+    DPRINT("RQueryServiceConfig2W() done (Error %lu)\n", dwError);
 
     return dwError;
 }
 
 
 /* Function 40 */
-DWORD
-ScmrQueryServiceStatusEx(handle_t BindingHandle,
-                         unsigned long hService,
-                         SC_STATUS_TYPE InfoLevel,
-                         unsigned char *lpBuffer, /* out */
-                         DWORD cbBufSize,
-                         DWORD *pcbBytesNeeded) /* out */
+DWORD RQueryServiceStatusEx(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    SC_STATUS_TYPE InfoLevel,
+    LPBYTE lpBuffer,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_8K pcbBytesNeeded)
 {
     LPSERVICE_STATUS_PROCESS lpStatus;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService;
 
-    DPRINT("ScmrQueryServiceStatusEx() called\n");
+    DPRINT("RQueryServiceStatusEx() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
@@ -2839,7 +3031,7 @@ ScmrQueryServiceStatusEx(handle_t BindingHandle,
         return ERROR_INSUFFICIENT_BUFFER;
 
     hSvc = (PSERVICE_HANDLE)hService;
-    if (hSvc->Handle.Tag != SERVICE_TAG)
+    if (!hSvc || hSvc->Handle.Tag != SERVICE_TAG)
     {
         DPRINT1("Invalid handle tag!\n");
         return ERROR_INVALID_HANDLE;
@@ -2874,20 +3066,20 @@ ScmrQueryServiceStatusEx(handle_t BindingHandle,
 
 
 /* Function 41 */
-DWORD
-ScmrEnumServicesStatusExA(handle_t BindingHandle,
-                          unsigned long hSCManager,
-                          SC_STATUS_TYPE InfoLevel,
-                          DWORD dwServiceType,
-                          DWORD dwServiceState,
-                          unsigned char *lpServices,
-                          DWORD dwBufSize,
-                          DWORD *pcbBytesNeeded,
-                          DWORD *lpServicesReturned,
-                          unsigned long *lpResumeHandle,
-                          char *pszGroupName)
-{
-    DPRINT1("ScmrEnumServicesStatusExA() is unimplemented\n");
+DWORD REnumServicesStatusExA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    SC_ENUM_TYPE InfoLevel,
+    DWORD dwServiceType,
+    DWORD dwServiceState,
+    LPBYTE lpBuffer,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_256K pcbBytesNeeded,
+    LPBOUNDED_DWORD_256K lpServicesReturned,
+    LPBOUNDED_DWORD_256K lpResumeIndex,
+    LPCSTR pszGroupName)
+{
+    UNIMPLEMENTED;
     *pcbBytesNeeded = 0;
     *lpServicesReturned = 0;
     return ERROR_CALL_NOT_IMPLEMENTED;
@@ -2895,18 +3087,18 @@ ScmrEnumServicesStatusExA(handle_t BindingHandle,
 
 
 /* Function 42 */
-DWORD
-ScmrEnumServicesStatusExW(handle_t BindingHandle,
-                          unsigned long hSCManager,
-                          SC_ENUM_TYPE InfoLevel,
-                          DWORD dwServiceType,
-                          DWORD dwServiceState,
-                          unsigned char *lpServices,
-                          DWORD dwBufSize,
-                          DWORD *pcbBytesNeeded,
-                          DWORD *lpServicesReturned,
-                          DWORD *lpResumeHandle,
-                          wchar_t *pszGroupName)
+DWORD REnumServicesStatusExW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hSCManager,
+    SC_ENUM_TYPE InfoLevel,
+    DWORD dwServiceType,
+    DWORD dwServiceState,
+    LPBYTE lpBuffer,
+    DWORD cbBufSize,
+    LPBOUNDED_DWORD_256K pcbBytesNeeded,
+    LPBOUNDED_DWORD_256K lpServicesReturned,
+    LPBOUNDED_DWORD_256K lpResumeIndex,
+    LPCWSTR pszGroupName)
 {
     PMANAGER_HANDLE hManager;
     PSERVICE lpService;
@@ -2921,7 +3113,7 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle,
     LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
     LPWSTR lpStringPtr;
 
-    DPRINT("ScmrEnumServicesStatusExW() called\n");
+    DPRINT("REnumServicesStatusExW() called\n");
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
@@ -2930,7 +3122,7 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle,
         return ERROR_INVALID_LEVEL;
 
     hManager = (PMANAGER_HANDLE)hSCManager;
-    if (hManager->Handle.Tag != MANAGER_TAG)
+    if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
     {
         DPRINT1("Invalid manager handle!\n");
         return ERROR_INVALID_HANDLE;
@@ -2948,7 +3140,7 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle,
     *pcbBytesNeeded = 0;
     *lpServicesReturned = 0;
 
-    dwLastResumeCount = *lpResumeHandle;
+    dwLastResumeCount = *lpResumeIndex;
 
     /* Lock the service list shared */
 
@@ -2999,7 +3191,7 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle,
                  ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
                  ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
 
-        if (dwRequiredSize + dwSize <= dwBufSize)
+        if (dwRequiredSize + dwSize <= cbBufSize)
         {
             DPRINT("Service name: %S  fit\n", CurrentService->lpServiceName);
             dwRequiredSize += dwSize;
@@ -3059,12 +3251,12 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle,
 
     DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
 
-    *lpResumeHandle = dwLastResumeCount;
+    *lpResumeIndex = dwLastResumeCount;
     *lpServicesReturned = dwServiceCount;
     *pcbBytesNeeded = dwRequiredSize;
 
-    lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpServices;
-    lpStringPtr = (LPWSTR)((ULONG_PTR)lpServices +
+    lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpBuffer;
+    lpStringPtr = (LPWSTR)((ULONG_PTR)lpBuffer +
                            dwServiceCount * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
 
     dwRequiredSize = 0;
@@ -3105,18 +3297,18 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle,
                  ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
                  ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
 
-        if (dwRequiredSize + dwSize <= dwBufSize)
+        if (dwRequiredSize + dwSize <= cbBufSize)
         {
             /* Copy the service name */
             wcscpy(lpStringPtr,
                    CurrentService->lpServiceName);
-            lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
+            lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
             lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
 
             /* Copy the display name */
             wcscpy(lpStringPtr,
                    CurrentService->lpDisplayName);
-            lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpServices);
+            lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
             lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
 
             /* Copy the status information */
@@ -3139,14 +3331,173 @@ ScmrEnumServicesStatusExW(handle_t BindingHandle,
 Done:;
     /* Unlock the service list */
 
-    DPRINT("ScmrEnumServicesStatusExW() done (Error %lu)\n", dwError);
+    DPRINT("REnumServicesStatusExW() done (Error %lu)\n", dwError);
 
     return dwError;
 }
 
 
 /* Function 43 */
-/* ScmrSendTSMessage */
+DWORD RSendTSMessage(
+    handle_t BindingHandle)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 44 */
+DWORD RCreateServiceWOW64A(
+    handle_t BindingHandle,
+    LPSTR lpServiceName,
+    LPSTR lpDisplayName,
+    DWORD dwDesiredAccess,
+    DWORD dwServiceType,
+    DWORD dwStartType,
+    DWORD dwErrorControl,
+    LPSTR lpBinaryPathName,
+    LPSTR lpLoadOrderGroup,
+    LPDWORD lpdwTagId,
+    LPBYTE lpDependencies,
+    DWORD dwDependSize,
+    LPSTR lpServiceStartName,
+    LPBYTE lpPassword,
+    DWORD dwPwSize,
+    LPSC_RPC_HANDLE lpServiceHandle)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 45 */
+DWORD RCreateServiceWOW64W(
+    handle_t BindingHandle,
+    LPWSTR lpServiceName,
+    LPWSTR lpDisplayName,
+    DWORD dwDesiredAccess,
+    DWORD dwServiceType,
+    DWORD dwStartType,
+    DWORD dwErrorControl,
+    LPWSTR lpBinaryPathName,
+    LPWSTR lpLoadOrderGroup,
+    LPDWORD lpdwTagId,
+    LPBYTE lpDependencies,
+    DWORD dwDependSize,
+    LPWSTR lpServiceStartName,
+    LPBYTE lpPassword,
+    DWORD dwPwSize,
+    LPSC_RPC_HANDLE lpServiceHandle)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 46 */
+DWORD RQueryServiceTagInfo(
+    handle_t BindingHandle)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 47 */
+DWORD RNotifyServiceStatusChange(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    SC_RPC_NOTIFY_PARAMS NotifyParams,
+    GUID *pClientProcessGuid,
+    GUID *pSCMProcessGuid,
+    PBOOL pfCreateRemoteQueue,
+    LPSC_NOTIFY_RPC_HANDLE phNotify)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 48 */
+DWORD RGetNotifyResults(
+    handle_t BindingHandle,
+    SC_NOTIFY_RPC_HANDLE hNotify,
+    PSC_RPC_NOTIFY_PARAMS_LIST *ppNotifyParams)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 49 */
+DWORD RCloseNotifyHandle(
+    handle_t BindingHandle,
+    LPSC_NOTIFY_RPC_HANDLE phNotify,
+    PBOOL pfApcFired)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 50 */
+DWORD RControlServiceExA(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwControl,
+    DWORD dwInfoLevel)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 51 */
+DWORD RControlServiceExW(
+    handle_t BindingHandle,
+    SC_RPC_HANDLE hService,
+    DWORD dwControl,
+    DWORD dwInfoLevel)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 52 */
+DWORD RSendPnPMessage(
+    handle_t BindingHandle)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 53 */
+DWORD RValidatePnPService(
+    handle_t BindingHandle)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 54 */
+DWORD ROpenServiceStatusHandle(
+    handle_t BindingHandle)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 55 */
+DWORD RFunction55(
+    handle_t BindingHandle)
+{
+    UNIMPLEMENTED;
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
 
 
 void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
@@ -3160,4 +3511,20 @@ void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
     HeapFree(GetProcessHeap(), 0, ptr);
 }
 
+
+void __RPC_USER SC_RPC_HANDLE_rundown(SC_RPC_HANDLE hSCObject)
+{
+}
+
+
+void __RPC_USER SC_RPC_LOCK_rundown(SC_RPC_LOCK Lock)
+{
+}
+
+
+void __RPC_USER SC_NOTIFY_RPC_HANDLE_rundown(SC_NOTIFY_RPC_HANDLE hNotify)
+{
+}
+
+
 /* EOF */