Fix a typo. Use lpStartServiceName instead of lpServiceName.
[reactos.git] / reactos / base / system / services / rpcserver.c
index 81bff1d..b42f81a 100644 (file)
@@ -151,12 +151,12 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName,
     if (lpDatabaseName == NULL)
         lpDatabaseName = SERVICES_ACTIVE_DATABASEW;
 
-    if (wcsicmp(lpDatabaseName,SERVICES_FAILED_DATABASEW)==0)
+    if (_wcsicmp(lpDatabaseName,SERVICES_FAILED_DATABASEW)==0)
     {
         DPRINT1("Database %S, does not exist\n",lpDatabaseName);
         return ERROR_DATABASE_DOES_NOT_EXIST;
     }
-    else if (wcsicmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
+    else if (_wcsicmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
     {
         DPRINT1("Invalid Database name %S.\n",lpDatabaseName);
         return ERROR_INVALID_NAME;
@@ -332,7 +332,7 @@ Int_EnumDependentServicesW(HKEY hServicesKey,
             /* Can be more than one Dependencies in the DependOnService string */
             while (wcslen(lpszValueBuf + dwDependServiceStrPtr) > 0)
             {
-                if (wcsicmp(lpszValueBuf + dwDependServiceStrPtr, lpService->lpServiceName) == 0)
+                if (_wcsicmp(lpszValueBuf + dwDependServiceStrPtr, lpService->lpServiceName) == 0)
                 {
                     /* Get the current enumed service pointer */
                     lpCurrentService = ScmGetServiceEntryByName(lpszNameBuf);
@@ -400,7 +400,6 @@ Int_EnumDependentServicesW(HKEY hServicesKey,
 
 /* Function 0 */
 DWORD RCloseServiceHandle(
-    handle_t BindingHandle,
     LPSC_RPC_HANDLE hSCObject)
 {
     PMANAGER_HANDLE hManager;
@@ -498,8 +497,8 @@ DWORD RCloseServiceHandle(
                    it is now safe to delete the service */
 
                 /* Delete the Service Key */
-                dwError = RegDeleteKey(hServicesKey,
-                                       lpService->lpServiceName);
+                dwError = RegDeleteKeyW(hServicesKey,
+                                        lpService->lpServiceName);
 
                 RegCloseKey(hServicesKey);
 
@@ -526,7 +525,6 @@ DWORD RCloseServiceHandle(
 
 /* Function 1 */
 DWORD RControlService(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwControl,
     LPSERVICE_STATUS lpServiceStatus)
@@ -657,7 +655,6 @@ DWORD RControlService(
 
 /* Function 2 */
 DWORD RDeleteService(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService)
 {
     PSERVICE_HANDLE hSvc;
@@ -707,7 +704,6 @@ DWORD RDeleteService(
 
 /* Function 3 */
 DWORD RLockServiceDatabase(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     LPSC_RPC_LOCK lpLock)
 {
@@ -736,14 +732,12 @@ DWORD RLockServiceDatabase(
 
 /* Function 4 */
 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;
     PSERVICE lpService;
     ULONG DesiredAccess = 0;
@@ -751,6 +745,9 @@ DWORD RQueryServiceObjectSecurity(
     DWORD dwBytesNeeded;
     DWORD dwError;
 
+
+    SECURITY_DESCRIPTOR ObjectDescriptor;
+
     DPRINT("RQueryServiceObjectSecurity() called\n");
 
     hSvc = (PSERVICE_HANDLE)hService;
@@ -784,10 +781,13 @@ DWORD RQueryServiceObjectSecurity(
 
     /* FIXME: Lock the service list */
 
-    Status = RtlQuerySecurityObject(lpService->lpSecurityDescriptor,
+    /* hack */
+    Status = RtlCreateSecurityDescriptor(&ObjectDescriptor, SECURITY_DESCRIPTOR_REVISION);
+
+    Status = RtlQuerySecurityObject(&ObjectDescriptor  /* lpService->lpSecurityDescriptor */,
                                     dwSecurityInformation,
                                     (PSECURITY_DESCRIPTOR)lpSecurityDescriptor,
-                                    dwSecuityDescriptorSize,
+                                    cbBufSize,
                                     &dwBytesNeeded);
 
     /* FIXME: Unlock the service list */
@@ -812,15 +812,11 @@ DWORD RQueryServiceObjectSecurity(
     }
 
     return dwError;
-#endif
-    UNIMPLEMENTED;
-    return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /* Function 5 */
 DWORD RSetServiceObjectSecurity(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwSecurityInformation,
     LPBYTE lpSecurityDescriptor,
@@ -829,9 +825,9 @@ DWORD RSetServiceObjectSecurity(
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService;
     ULONG DesiredAccess = 0;
-    HANDLE hToken = NULL;
+    /* HANDLE hToken = NULL; */
     HKEY hServiceKey;
-    NTSTATUS Status;
+    /* NTSTATUS Status; */
     DWORD dwError;
 
     DPRINT1("RSetServiceObjectSecurity() called\n");
@@ -861,11 +857,11 @@ DWORD RSetServiceObjectSecurity(
         DesiredAccess |= WRITE_OWNER;
 
     if ((dwSecurityInformation & OWNER_SECURITY_INFORMATION) &&
-        (((PSECURITY_DESCRIPTOR)lpSecurityDescriptor)->Owner == NULL))
+        (((PISECURITY_DESCRIPTOR)lpSecurityDescriptor)->Owner == NULL))
         return ERROR_INVALID_PARAMETER;
 
     if ((dwSecurityInformation & GROUP_SECURITY_INFORMATION) &&
-        (((PSECURITY_DESCRIPTOR)lpSecurityDescriptor)->Group == NULL))
+        (((PISECURITY_DESCRIPTOR)lpSecurityDescriptor)->Group == NULL))
         return ERROR_INVALID_PARAMETER;
 
     if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
@@ -885,6 +881,7 @@ DWORD RSetServiceObjectSecurity(
     if (lpService->bDeleted)
         return ERROR_SERVICE_MARKED_FOR_DELETE;
 
+#if 0
     RpcImpersonateClient(NULL);
 
     Status = NtOpenThreadToken(NtCurrentThread(),
@@ -892,13 +889,12 @@ DWORD RSetServiceObjectSecurity(
                                TRUE,
                                &hToken);
     if (!NT_SUCCESS(Status))
-        return RtlNtStatusToDosError(Status);
+        return RtlNtStatusToDosError(Status); 
 
     RpcRevertToSelf();
 
     /* FIXME: Lock service database */
 
-#if 0
     Status = RtlSetSecurityObject(dwSecurityInformation,
                                   (PSECURITY_DESCRIPTOR)lpSecurityDescriptor,
                                   &lpService->lpSecurityDescriptor,
@@ -927,8 +923,10 @@ DWORD RSetServiceObjectSecurity(
 
 Done:
 
+#if 0
     if (hToken != NULL)
         NtClose(hToken);
+#endif
 
     /* FIXME: Unlock service database */
 
@@ -940,7 +938,6 @@ Done:
 
 /* Function 6 */
 DWORD RQueryServiceStatus(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     LPSERVICE_STATUS lpServiceStatus)
 {
@@ -1004,8 +1001,7 @@ ScmIsValidServiceState(DWORD dwCurrentState)
 
 /* Function 7 */
 DWORD RSetServiceStatus(
-    handle_t BindingHandle,
-    SC_RPC_HANDLE hServiceStatus,
+    RPC_SERVICE_STATUS_HANDLE hServiceStatus,
     LPSERVICE_STATUS lpServiceStatus)
 {
     PSERVICE lpService;
@@ -1026,7 +1022,7 @@ DWORD RSetServiceStatus(
         return ERROR_INVALID_HANDLE;
     }
 
-    lpService = ScmGetServiceEntryByClientHandle((ULONG)hServiceStatus);
+    lpService = ScmGetServiceEntryByClientHandle((HANDLE)hServiceStatus);
     if (lpService == NULL)
     {
         DPRINT1("lpService == NULL!\n");
@@ -1049,8 +1045,7 @@ DWORD RSetServiceStatus(
     }
 
     /* Check accepted controls */
-    if (lpServiceStatus->dwControlsAccepted == 0 ||
-        lpServiceStatus->dwControlsAccepted & ~0xFF)
+    if (lpServiceStatus->dwControlsAccepted & ~0xFF)
     {
         DPRINT1("Invalid controls accepted!\n");
         return ERROR_INVALID_DATA;
@@ -1070,7 +1065,6 @@ DWORD RSetServiceStatus(
 
 /* Function 8 */
 DWORD RUnlockServiceDatabase(
-    handle_t BindingHandle,
     LPSC_RPC_LOCK Lock)
 {
     UNIMPLEMENTED;
@@ -1080,7 +1074,6 @@ DWORD RUnlockServiceDatabase(
 
 /* Function 9 */
 DWORD RNotifyBootConfigStatus(
-    handle_t BindingHandle,
     SVCCTL_HANDLEW lpMachineName,
     DWORD BootAcceptable)
 {
@@ -1091,8 +1084,7 @@ DWORD RNotifyBootConfigStatus(
 
 /* Function 10 */
 DWORD RI_ScSetServiceBitsW(
-    handle_t BindingHandle,
-    SC_RPC_HANDLE hServiceStatus,
+    RPC_SERVICE_STATUS_HANDLE hServiceStatus,
     DWORD dwServiceBits,
     int bSetBitsOn,
     int bUpdateImmediately,
@@ -1105,7 +1097,6 @@ DWORD RI_ScSetServiceBitsW(
 
 /* Function 11 */
 DWORD RChangeServiceConfigW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwServiceType,
     DWORD dwStartType,
@@ -1357,7 +1348,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
 
     /* First check, if it's already good */
     if (ServiceNameLen > 12 &&
-        !wcsnicmp(L"\\SystemRoot\\", CanonName, 12))
+        !_wcsnicmp(L"\\SystemRoot\\", CanonName, 12))
     {
         *RelativeName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR) + sizeof(WCHAR));
         if (*RelativeName == NULL)
@@ -1375,7 +1366,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
 
     /* If it has %SystemRoot% prefix, substitute it to \System*/
     if (ServiceNameLen > 13 &&
-        !wcsnicmp(L"%SystemRoot%\\", CanonName, 13))
+        !_wcsnicmp(L"%SystemRoot%\\", CanonName, 13))
     {
         /* There is no +sizeof(wchar_t) because the name is less by 1 wchar */
         *RelativeName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR));
@@ -1445,7 +1436,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
     Expanded[ExpandedLen] = 0;
 
     if (ServiceNameLen > ExpandedLen &&
-        !wcsnicmp(Expanded, CanonName, ExpandedLen))
+        !_wcsnicmp(Expanded, CanonName, ExpandedLen))
     {
         /* Only \SystemRoot\ is missing */
         *RelativeName = LocalAlloc(LMEM_ZEROINIT,
@@ -1517,7 +1508,7 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
 
                 ExpandedLen = LinkTarget.Length / sizeof(WCHAR);
                 if ((ServiceNameLen > ExpandedLen) &&
-                    !wcsnicmp(LinkTarget.Buffer, CanonName, ExpandedLen))
+                    !_wcsnicmp(LinkTarget.Buffer, CanonName, ExpandedLen))
                 {
                     *RelativeName = LocalAlloc(LMEM_ZEROINIT,
                        (ServiceNameLen - ExpandedLen) * sizeof(WCHAR) + 13*sizeof(WCHAR));
@@ -1584,20 +1575,20 @@ ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
 
 DWORD
 ScmCanonDriverImagePath(DWORD dwStartType,
-                        wchar_t *lpServiceName,
+                        const wchar_t *lpServiceName,
                         wchar_t **lpCanonName)
 {
     DWORD ServiceNameLen, Result;
     UNICODE_STRING NtServiceName;
     WCHAR *RelativeName;
-    WCHAR *SourceName = lpServiceName;
+    const WCHAR *SourceName = lpServiceName;
 
     /* Calculate the length of the service's name */
     ServiceNameLen = wcslen(lpServiceName);
 
     /* 12 is wcslen(L"\\SystemRoot\\") */
     if (ServiceNameLen > 12 &&
-        !wcsnicmp(L"\\SystemRoot\\", lpServiceName, 12))
+        !_wcsnicmp(L"\\SystemRoot\\", lpServiceName, 12))
     {
         /* SystemRoot prefix is already included */
 
@@ -1622,7 +1613,7 @@ ScmCanonDriverImagePath(DWORD dwStartType,
 
     /* Check if it has %SystemRoot% (len=13) */
     if (ServiceNameLen > 13 &&
-        !wcsnicmp(L"%%SystemRoot%%\\", lpServiceName, 13))
+        !_wcsnicmp(L"%%SystemRoot%%\\", lpServiceName, 13))
     {
         /* Substitute %SystemRoot% with \\SystemRoot\\ */
         *lpCanonName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR) + sizeof(WCHAR));
@@ -1715,20 +1706,19 @@ ScmCanonDriverImagePath(DWORD dwStartType,
 
 /* Function 12 */
 DWORD RCreateServiceW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
-    LPWSTR lpServiceName,
-    LPWSTR lpDisplayName,
+    LPCWSTR lpServiceName,
+    LPCWSTR lpDisplayName,
     DWORD dwDesiredAccess,
     DWORD dwServiceType,
     DWORD dwStartType,
     DWORD dwErrorControl,
-    LPWSTR lpBinaryPathName,
-    LPWSTR lpLoadOrderGroup,
+    LPCWSTR lpBinaryPathName,
+    LPCWSTR lpLoadOrderGroup,
     LPDWORD lpdwTagId,
     LPBYTE lpDependencies,
     DWORD dwDependSize,
-    LPWSTR lpServiceStartName,
+    LPCWSTR lpServiceStartName,
     LPBYTE lpPassword,
     DWORD dwPwSize,
     LPSC_RPC_HANDLE lpServiceHandle)
@@ -1842,7 +1832,7 @@ DWORD RCreateServiceW(
     /* Fill the display name */
     if (lpDisplayName != NULL &&
         *lpDisplayName != 0 &&
-        wcsicmp(lpService->lpDisplayName, lpDisplayName) != 0)
+        _wcsicmp(lpService->lpDisplayName, lpDisplayName) != 0)
     {
         lpService->lpDisplayName = (WCHAR*) HeapAlloc(GetProcessHeap(), 0,
                                              (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
@@ -1979,8 +1969,9 @@ DWORD RCreateServiceW(
             goto done;
     }
 
-    /* If a non driver and NULL for lpServiceName, write ObjectName as LocalSystem */
-    if ((dwServiceType & SERVICE_WIN32) && (!lpServiceName))
+    /* FIXME: Handle lpServiceStartName propertly! */
+    /* If a non driver and NULL for lpServiceStartName, write ObjectName as LocalSystem */
+    if ((dwServiceType & SERVICE_WIN32) && (!lpServiceStartName))
     {
         dwError = RegSetValueExW(hServiceKey,
                                  L"ObjectName",
@@ -2051,7 +2042,6 @@ done:;
 
 /* Function 13 */
 DWORD REnumDependentServicesW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwServiceState,
     LPBYTE lpServices,
@@ -2181,7 +2171,6 @@ Done:
 
 /* Function 14 */
 DWORD REnumServicesStatusW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     DWORD dwServiceType,
     DWORD dwServiceState,
@@ -2240,7 +2229,8 @@ DWORD REnumServicesStatusW(
         return ERROR_ACCESS_DENIED;
     }
 
-    if (lpResumeHandle) dwLastResumeCount = *lpResumeHandle;
+    if (lpResumeHandle)
+        dwLastResumeCount = *lpResumeHandle;
 
     /* FIXME: Lock the service list shared */
 
@@ -2318,7 +2308,9 @@ DWORD REnumServicesStatusW(
 
     DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
 
-    if (lpResumeHandle) *lpResumeHandle = dwLastResumeCount;
+    if (lpResumeHandle)
+        *lpResumeHandle = dwLastResumeCount;
+
     *lpServicesReturned = dwServiceCount;
     *pcbBytesNeeded = dwRequiredSize;
 
@@ -2388,7 +2380,6 @@ Done:;
 
 /* Function 15 */
 DWORD ROpenSCManagerW(
-    handle_t BindingHandle,
     LPWSTR lpMachineName,
     LPWSTR lpDatabaseName,
     DWORD dwDesiredAccess,
@@ -2439,7 +2430,6 @@ DWORD ROpenSCManagerW(
 
 /* Function 16 */
 DWORD ROpenServiceW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     LPWSTR lpServiceName,
     DWORD dwDesiredAccess,
@@ -2459,12 +2449,6 @@ DWORD ROpenServiceW(
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
 
-    if (!lpServiceHandle)
-        return ERROR_INVALID_PARAMETER;
-
-    if (!lpServiceName)
-        return ERROR_INVALID_ADDRESS;
-
     hManager = (PMANAGER_HANDLE)hSCManager;
     if (!hManager || hManager->Handle.Tag != MANAGER_TAG)
     {
@@ -2472,6 +2456,12 @@ DWORD ROpenServiceW(
         return ERROR_INVALID_HANDLE;
     }
 
+    if (!lpServiceHandle)
+        return ERROR_INVALID_PARAMETER;
+
+    if (!lpServiceName)
+        return ERROR_INVALID_ADDRESS;
+
     /* FIXME: Lock the service list */
 
     /* Get service database entry */
@@ -2515,7 +2505,6 @@ DWORD ROpenServiceW(
 
 /* Function 17 */
 DWORD RQueryServiceConfigW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     LPBYTE lpBuf, //LPQUERY_SERVICE_CONFIGW lpServiceConfig,
     DWORD cbBufSize,
@@ -2692,7 +2681,6 @@ Done:;
 
 /* Function 18 */
 DWORD RQueryServiceLockStatusW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
     DWORD cbBufSize,
@@ -2705,7 +2693,6 @@ DWORD RQueryServiceLockStatusW(
 
 /* Function 19 */
 DWORD RStartServiceW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD argc,
     LPSTRING_PTRSW argv)
@@ -2760,9 +2747,8 @@ DWORD RStartServiceW(
 
 /* Function 20 */
 DWORD RGetServiceDisplayNameW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
-    LPWSTR lpServiceName,
+    LPCWSTR lpServiceName,
     LPWSTR lpDisplayName,
     DWORD *lpcchBuffer)
 {
@@ -2790,12 +2776,15 @@ DWORD RGetServiceDisplayNameW(
     {
         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)
+        /* If the service could not be found and lpcchBuffer is less than 2, windows
+           puts null in lpDisplayName and puts 2 in lpcchBuffer */
+        if (*lpcchBuffer < 2)
         {
-            *lpcchBuffer = 1;
-            *lpDisplayName = '\0';
+            *lpcchBuffer = 2;
+            if (lpDisplayName != NULL)
+            {
+                *lpDisplayName = '\0';
+            }
         }
 
         return ERROR_SERVICE_DOES_NOT_EXIST;
@@ -2805,7 +2794,7 @@ DWORD RGetServiceDisplayNameW(
     {
         dwLength = wcslen(lpService->lpServiceName);
 
-        if (lpServiceName != NULL &&
+        if (lpDisplayName != NULL &&
             *lpcchBuffer > dwLength)
         {
             wcscpy(lpDisplayName, lpService->lpServiceName);
@@ -2832,9 +2821,8 @@ DWORD RGetServiceDisplayNameW(
 
 /* Function 21 */
 DWORD RGetServiceKeyNameW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
-    LPWSTR lpDisplayName,
+    LPCWSTR lpDisplayName,
     LPWSTR lpServiceName,
     DWORD *lpcchBuffer)
 {
@@ -2862,12 +2850,15 @@ DWORD RGetServiceKeyNameW(
     {
         DPRINT1("Could not find a service!\n");
 
-        /* If the service could not be found and lpcchBuffer is 0, windows
+        /* If the service could not be found and lpcchBuffer is less than 2, windows
            puts null in lpDisplayName and puts 2 in lpcchBuffer */
-        if (*lpcchBuffer == 0)
+        if (*lpcchBuffer < 2)
         {
             *lpcchBuffer = 2;
-            *lpServiceName = '\0';
+            if (lpServiceName != NULL)
+            {
+                *lpServiceName = '\0';
+            }
         }
 
         return ERROR_SERVICE_DOES_NOT_EXIST;
@@ -2885,7 +2876,7 @@ DWORD RGetServiceKeyNameW(
 
     dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
 
-    *lpcchBuffer = dwLength * 2;
+    *lpcchBuffer = dwLength;
 
     return dwError;
 }
@@ -2893,8 +2884,7 @@ DWORD RGetServiceKeyNameW(
 
 /* Function 22 */
 DWORD RI_ScSetServiceBitsA(
-    handle_t BindingHandle,
-    SC_RPC_HANDLE hServiceStatus,
+    RPC_SERVICE_STATUS_HANDLE hServiceStatus,
     DWORD dwServiceBits,
     int bSetBitsOn,
     int bUpdateImmediately,
@@ -2907,7 +2897,6 @@ DWORD RI_ScSetServiceBitsA(
 
 /* Function 23 */
 DWORD RChangeServiceConfigA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwServiceType,
     DWORD dwStartType,
@@ -2999,7 +2988,7 @@ DWORD RChangeServiceConfigA(
                             lpDisplayName,
                             -1,
                             lpDisplayNameW,
-                            wcslen(lpDisplayNameW) + 1);
+                            strlen(lpDisplayName) + 1);
 
         RegSetValueExW(hServiceKey,
                        L"DisplayName",
@@ -3192,7 +3181,6 @@ done:
 
 /* Function 24 */
 DWORD RCreateServiceA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     LPSTR lpServiceName,
     LPSTR lpDisplayName,
@@ -3217,7 +3205,6 @@ DWORD RCreateServiceA(
 
 /* Function 25 */
 DWORD REnumDependentServicesA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwServiceState,
     LPBYTE lpServices,
@@ -3261,7 +3248,8 @@ DWORD REnumDependentServicesA(
                             KEY_READ,
                             &hServicesKey);
 
-    if (dwError != ERROR_SUCCESS) return dwError;
+    if (dwError != ERROR_SUCCESS)
+        return dwError;
 
     /* NOTE: Windows calculates the pcbBytesNeeded based on WCHAR strings for
              both EnumDependentServicesA and EnumDependentServicesW. So returned pcbBytesNeeded
@@ -3365,7 +3353,6 @@ Done:
 
 /* Function 26 */
 DWORD REnumServicesStatusA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     DWORD dwServiceType,
     DWORD dwServiceState,
@@ -3394,8 +3381,7 @@ DWORD REnumServicesStatusA(
         }
     }
 
-    dwError = REnumServicesStatusW(BindingHandle,
-                                   hSCManager,
+    dwError = REnumServicesStatusW(hSCManager,
                                    dwServiceType,
                                    dwServiceState,
                                    (LPBYTE)lpStatusPtrW,
@@ -3405,7 +3391,8 @@ DWORD REnumServicesStatusA(
                                    lpResumeHandle);
 
     /* if no services were returned then we are Done */
-    if (*lpServicesReturned == 0) goto Done;
+    if (*lpServicesReturned == 0)
+        goto Done;
 
     lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
     lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
@@ -3452,7 +3439,8 @@ DWORD REnumServicesStatusA(
     }
 
 Done:;
-    if (lpStatusPtrW) HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
+    if (lpStatusPtrW)
+        HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
 
     DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError);
 
@@ -3462,7 +3450,6 @@ Done:;
 
 /* Function 27 */
 DWORD ROpenSCManagerA(
-    handle_t BindingHandle,
     LPSTR lpMachineName,
     LPSTR lpDatabaseName,
     DWORD dwDesiredAccess,
@@ -3482,7 +3469,7 @@ DWORD ROpenSCManagerA(
         RtlCreateUnicodeStringFromAsciiz(&DatabaseName,
                                          lpDatabaseName);
 
-    dwError = ROpenSCManagerW(BindingHandle,
+    dwError = ROpenSCManagerW(//BindingHandle,
                               lpMachineName ? MachineName.Buffer : NULL,
                               lpDatabaseName ? DatabaseName.Buffer : NULL,
                               dwDesiredAccess,
@@ -3500,7 +3487,6 @@ DWORD ROpenSCManagerA(
 
 /* Function 28 */
 DWORD ROpenServiceA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     LPSTR lpServiceName,
     DWORD dwDesiredAccess,
@@ -3515,7 +3501,7 @@ DWORD ROpenServiceA(
         RtlCreateUnicodeStringFromAsciiz(&ServiceName,
                                          lpServiceName);
 
-    dwError = ROpenServiceW(BindingHandle,
+    dwError = ROpenServiceW(//BindingHandle,
                             hSCManager,
                             lpServiceName ? ServiceName.Buffer : NULL,
                             dwDesiredAccess,
@@ -3530,7 +3516,6 @@ DWORD ROpenServiceA(
 
 /* Function 29 */
 DWORD RQueryServiceConfigA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     LPBYTE lpBuf, //LPQUERY_SERVICE_CONFIGA lpServiceConfig,
     DWORD cbBufSize,
@@ -3599,7 +3584,7 @@ DWORD RQueryServiceConfigA(
     else
         dwRequiredSize += 2;
 
-    if (lpService->lpGroup != NULL)
+    if ((lpService->lpGroup != NULL) && (lpService->lpGroup->lpGroupName != NULL))
         dwRequiredSize += wcslen(lpService->lpGroup->lpGroupName) + 1;
     else
         dwRequiredSize += 2;
@@ -3641,7 +3626,7 @@ DWORD RQueryServiceConfigA(
                                 lpImagePath,
                                 -1,
                                 lpStr,
-                                wcslen(lpImagePath),
+                                wcslen(lpImagePath)+1,
                                 0,
                                 0);
         }
@@ -3653,14 +3638,14 @@ DWORD RQueryServiceConfigA(
         lpConfig->lpBinaryPathName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
         lpStr += (strlen((LPSTR)lpStr) + 1);
 
-        if (lpService->lpGroup)
+        if (lpService->lpGroup && lpService->lpGroup->lpGroupName)
         {
             WideCharToMultiByte(CP_ACP,
                                 0,
                                 lpService->lpGroup->lpGroupName,
                                 -1,
                                 lpStr,
-                                wcslen(lpService->lpGroup->lpGroupName),
+                                wcslen(lpService->lpGroup->lpGroupName)+1,
                                 0,
                                 0);
         }
@@ -3685,7 +3670,7 @@ DWORD RQueryServiceConfigA(
                                 lpServiceStartName,
                                 -1,
                                 lpStr,
-                                wcslen(lpServiceStartName),
+                                wcslen(lpServiceStartName)+1,
                                 0,
                                 0);
         }
@@ -3704,7 +3689,7 @@ DWORD RQueryServiceConfigA(
                                 lpService->lpDisplayName,
                                 -1,
                                 lpStr,
-                                wcslen(lpService->lpDisplayName),
+                                wcslen(lpService->lpDisplayName)+1,
                                 0,
                                 0);
         }
@@ -3739,7 +3724,6 @@ Done:;
 
 /* Function 30 */
 DWORD RQueryServiceLockStatusA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
     DWORD cbBufSize,
@@ -3752,7 +3736,6 @@ DWORD RQueryServiceLockStatusA(
 
 /* Function 31 */
 DWORD RStartServiceA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD argc,
     LPSTRING_PTRSA argv)
@@ -3806,14 +3789,13 @@ DWORD RStartServiceA(
 
 /* Function 32 */
 DWORD RGetServiceDisplayNameA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
-    LPSTR lpServiceName,
+    LPCSTR lpServiceName,
     LPSTR lpDisplayName,
     LPBOUNDED_DWORD_4K lpcchBuffer)
 {
 //    PMANAGER_HANDLE hManager;
-    PSERVICE lpService;
+    PSERVICE lpService = NULL;
     DWORD dwLength;
     DWORD dwError;
     LPWSTR lpServiceNameW;
@@ -3831,23 +3813,26 @@ DWORD RGetServiceDisplayNameA(
 //        return ERROR_INVALID_HANDLE;
 //    }
 
-    dwLength = strlen(lpServiceName) + 1;
-    lpServiceNameW = HeapAlloc(GetProcessHeap(),
-                               HEAP_ZERO_MEMORY,
-                               dwLength * sizeof(WCHAR));
-    if (!lpServiceNameW)
-        return ERROR_NOT_ENOUGH_MEMORY;
+    if (lpServiceName != NULL)
+    {
+        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);
+        MultiByteToWideChar(CP_ACP,
+                            0,
+                            lpServiceName,
+                            -1,
+                            lpServiceNameW,
+                            dwLength);
 
-    lpService = ScmGetServiceEntryByName(lpServiceNameW);
+        lpService = ScmGetServiceEntryByName(lpServiceNameW);
 
-    HeapFree(GetProcessHeap(), 0, lpServiceNameW);
+        HeapFree(GetProcessHeap(), 0, lpServiceNameW);
+    }
 
     if (lpService == NULL)
     {
@@ -3858,7 +3843,10 @@ DWORD RGetServiceDisplayNameA(
         if (*lpcchBuffer == 0)
         {
             *lpcchBuffer = 1;
-            *lpDisplayName = '\0';
+            if (lpDisplayName != NULL)
+            {
+                *lpDisplayName = '\0';
+            }
         }
         return ERROR_SERVICE_DOES_NOT_EXIST;
     }
@@ -3866,7 +3854,7 @@ DWORD RGetServiceDisplayNameA(
     if (!lpService->lpDisplayName)
     {
         dwLength = wcslen(lpService->lpServiceName);
-        if (lpServiceName != NULL &&
+        if (lpDisplayName != NULL &&
             *lpcchBuffer > dwLength)
         {
             WideCharToMultiByte(CP_ACP,
@@ -3874,7 +3862,7 @@ DWORD RGetServiceDisplayNameA(
                                 lpService->lpServiceName,
                                 wcslen(lpService->lpServiceName),
                                 lpDisplayName,
-                                *lpcchBuffer,
+                                dwLength + 1,
                                 NULL,
                                 NULL);
             return ERROR_SUCCESS;
@@ -3891,7 +3879,7 @@ DWORD RGetServiceDisplayNameA(
                                 lpService->lpDisplayName,
                                 wcslen(lpService->lpDisplayName),
                                 lpDisplayName,
-                                *lpcchBuffer,
+                                dwLength + 1,
                                 NULL,
                                 NULL);
             return ERROR_SUCCESS;
@@ -3908,9 +3896,8 @@ DWORD RGetServiceDisplayNameA(
 
 /* Function 33 */
 DWORD RGetServiceKeyNameA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
-    LPSTR lpDisplayName,
+    LPCSTR lpDisplayName,
     LPSTR lpServiceName,
     LPBOUNDED_DWORD_4K lpcchBuffer)
 {
@@ -3935,7 +3922,7 @@ DWORD RGetServiceKeyNameA(
     MultiByteToWideChar(CP_ACP,
                         0,
                         lpDisplayName,
-                        strlen(lpDisplayName),
+                        -1,
                         lpDisplayNameW,
                         dwLength);
 
@@ -3952,14 +3939,17 @@ DWORD RGetServiceKeyNameA(
         if (*lpcchBuffer == 0)
         {
             *lpcchBuffer = 1;
-            *lpServiceName = '\0';
+            if (lpServiceName != NULL)
+            {
+                *lpServiceName = '\0';
+            }
         }
 
         return ERROR_SERVICE_DOES_NOT_EXIST;
     }
 
     dwLength = wcslen(lpService->lpServiceName);
-    if (lpService != NULL &&
+    if (lpServiceName != NULL &&
         *lpcchBuffer > dwLength)
     {
         WideCharToMultiByte(CP_ACP,
@@ -3967,7 +3957,7 @@ DWORD RGetServiceKeyNameA(
                             lpService->lpServiceName,
                             wcslen(lpService->lpServiceName),
                             lpServiceName,
-                            dwLength,
+                            dwLength + 1,
                             NULL,
                             NULL);
         return ERROR_SUCCESS;
@@ -3983,7 +3973,6 @@ DWORD RGetServiceKeyNameA(
 
 /* Function 34 */
 DWORD RI_ScGetCurrentGroupStateW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     LPWSTR lpLoadOrderGroup,
     LPDWORD lpState)
@@ -3995,7 +3984,6 @@ DWORD RI_ScGetCurrentGroupStateW(
 
 /* Function 35 */
 DWORD REnumServiceGroupW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     DWORD dwServiceType,
     DWORD dwServiceState,
@@ -4011,20 +3999,123 @@ DWORD REnumServiceGroupW(
 }
 
 
+//
+// WARNING: This function is untested
+//
 /* Function 36 */
 DWORD RChangeServiceConfig2A(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     SC_RPC_CONFIG_INFOA Info)
 {
-    UNIMPLEMENTED;
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    SC_RPC_CONFIG_INFOW InfoW;
+    DWORD dwRet, dwLength;
+    PVOID ptr = NULL;
+
+    DPRINT("RChangeServiceConfig2A() called\n");
+    DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
+
+    InfoW.dwInfoLevel = Info.dwInfoLevel;
+
+    if (InfoW.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
+    {
+        LPSERVICE_DESCRIPTIONW lpServiceDescriptonW;
+        LPSERVICE_DESCRIPTIONA lpServiceDescriptonA;
+
+        lpServiceDescriptonA = Info.psd;
+
+        ///if (lpServiceDescriptonA &&
+        ///lpServiceDescriptonA->lpDescription)
+        ///{
+            dwLength = (strlen(Info.lpDescription) + 1) * sizeof(WCHAR);
+
+            lpServiceDescriptonW = HeapAlloc(GetProcessHeap(),
+                                            0,
+                                            dwLength + sizeof(SERVICE_DESCRIPTIONW));
+            if (!lpServiceDescriptonW)
+            {
+                return ERROR_NOT_ENOUGH_MEMORY;
+            }
+
+            lpServiceDescriptonW->lpDescription = (LPWSTR)(lpServiceDescriptonW + 1);
+
+            MultiByteToWideChar(CP_ACP,
+                                0,
+                                Info.lpDescription,
+                                -1,
+                                lpServiceDescriptonW->lpDescription,
+                                dwLength);
+
+            ptr = lpServiceDescriptonW;
+            InfoW.psd = lpServiceDescriptonW;
+        ///}
+    }
+    else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
+    {
+        LPSERVICE_FAILURE_ACTIONSW lpServiceFailureActionsW;
+        LPSERVICE_FAILURE_ACTIONSA lpServiceFailureActionsA;
+        DWORD dwRebootLen = 0;
+        DWORD dwCommandLen = 0;
+
+        lpServiceFailureActionsA = Info.psfa;
+
+        if (lpServiceFailureActionsA)
+        {
+            if (lpServiceFailureActionsA->lpRebootMsg)
+            {
+                dwRebootLen = (strlen(lpServiceFailureActionsA->lpRebootMsg) + 1) * sizeof(WCHAR);
+            }
+            if (lpServiceFailureActionsA->lpCommand)
+            {
+                dwCommandLen = (strlen(lpServiceFailureActionsA->lpCommand) + 1) * sizeof(WCHAR);
+            }
+            dwLength = dwRebootLen + dwCommandLen + sizeof(SERVICE_FAILURE_ACTIONSW);
+
+            lpServiceFailureActionsW = HeapAlloc(GetProcessHeap(),
+                                                 0,
+                                                 dwLength);
+            if (!lpServiceFailureActionsW)
+            {
+                return ERROR_NOT_ENOUGH_MEMORY;
+            }
+
+            lpServiceFailureActionsW->cActions = lpServiceFailureActionsA->cActions;
+            lpServiceFailureActionsW->dwResetPeriod = lpServiceFailureActionsA->dwResetPeriod;
+            CopyMemory(lpServiceFailureActionsW->lpsaActions, lpServiceFailureActionsA->lpsaActions, sizeof(SC_ACTION));
+
+            if (lpServiceFailureActionsA->lpRebootMsg)
+            {
+                MultiByteToWideChar(CP_ACP,
+                                    0,
+                                    lpServiceFailureActionsA->lpRebootMsg,
+                                    -1,
+                                    lpServiceFailureActionsW->lpRebootMsg,
+                                    dwRebootLen);
+            }
+
+            if (lpServiceFailureActionsA->lpCommand)
+            {
+                MultiByteToWideChar(CP_ACP,
+                                    0,
+                                    lpServiceFailureActionsA->lpCommand,
+                                    -1,
+                                    lpServiceFailureActionsW->lpCommand,
+                                    dwCommandLen);
+            }
+
+            ptr = lpServiceFailureActionsW;
+        }
+    }
+
+    dwRet = RChangeServiceConfig2W(hService, InfoW);
+
+    HeapFree(GetProcessHeap(), 0, ptr);
+
+    return dwRet;
 }
 
 
 /* Function 37 */
 DWORD RChangeServiceConfig2W(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     SC_RPC_CONFIG_INFOW Info)
 {
@@ -4076,16 +4167,17 @@ DWORD RChangeServiceConfig2W(
     if (dwError != ERROR_SUCCESS)
         goto done;
 
-    if (Info.dwInfoLevel & SERVICE_CONFIG_DESCRIPTION)
+    if (Info.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
     {
         LPSERVICE_DESCRIPTIONW lpServiceDescription;
 
-        lpServiceDescription = (LPSERVICE_DESCRIPTIONW)&Info;
-        lpServiceDescription->lpDescription = (LPWSTR)(&Info + sizeof(LPSERVICE_DESCRIPTIONW));
+        lpServiceDescription = (LPSERVICE_DESCRIPTIONW)Info.psd;
+        lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpServiceDescription + sizeof(LPSERVICE_DESCRIPTIONW));
 
         if (lpServiceDescription != NULL &&
             lpServiceDescription->lpDescription != NULL)
         {
+            DPRINT1("Setting value %S\n", lpServiceDescription->lpDescription);
             RegSetValueExW(hServiceKey,
                            L"Description",
                            0,
@@ -4097,7 +4189,7 @@ DWORD RChangeServiceConfig2W(
                 goto done;
         }
     }
-    else if (Info.dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS)
+    else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
     {
         UNIMPLEMENTED;
         dwError = ERROR_CALL_NOT_IMPLEMENTED;
@@ -4117,7 +4209,6 @@ done:
 
 /* Function 38 */
 DWORD RQueryServiceConfig2A(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwInfoLevel,
     LPBYTE lpBuffer,
@@ -4128,11 +4219,10 @@ DWORD RQueryServiceConfig2A(
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
     HKEY hServiceKey = NULL;
-    DWORD dwRequiredSize;
     LPWSTR lpDescriptionW = NULL;
     LPSTR lpDescription = NULL;
 
-    DPRINT("RQueryServiceConfig2W() called\n");
+    DPRINT1("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n",hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
 
     if (!lpBuffer)
         return ERROR_INVALID_ADDRESS;
@@ -4174,32 +4264,44 @@ DWORD RQueryServiceConfig2A(
         LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer;
         LPSTR lpStr;
 
+        *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA);
+
         dwError = ScmReadString(hServiceKey,
                                 L"Description",
                                 &lpDescriptionW);
-        if (dwError != ERROR_SUCCESS)
-            goto done;
+        if (dwError == ERROR_SUCCESS)
+        {
+            *pcbBytesNeeded += ((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR));
+        }
 
-        dwRequiredSize = sizeof(SERVICE_DESCRIPTIONA) + ((wcslen(lpDescriptionW) + 1));
+        if (cbBufSize >= *pcbBytesNeeded)
+        {
 
-        if (cbBufSize < dwRequiredSize)
+            if (dwError == ERROR_SUCCESS)
+            {
+                lpStr = (LPSTR)(lpServiceDescription + 1);
+
+                WideCharToMultiByte(CP_ACP,
+                                    0,
+                                    lpDescriptionW,
+                                    -1,
+                                    lpStr,
+                                    wcslen(lpDescriptionW),
+                                    NULL,
+                                    NULL);
+                lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
+            }
+            else
+            {
+                lpServiceDescription->lpDescription = NULL;
+                goto done;
+            }
+        }
+        else
         {
-            *pcbBytesNeeded = dwRequiredSize;
             dwError = ERROR_INSUFFICIENT_BUFFER;
             goto done;
         }
-
-        lpStr = (LPSTR)(lpServiceDescription + 1);
-
-        WideCharToMultiByte(CP_ACP,
-                            0,
-                            lpDescriptionW,
-                            -1,
-                            lpStr,
-                            wcslen(lpDescriptionW),
-                            NULL,
-                            NULL);
-        lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
     }
     else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS)
     {
@@ -4225,7 +4327,6 @@ done:
 
 /* Function 39 */
 DWORD RQueryServiceConfig2W(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwInfoLevel,
     LPBYTE lpBuffer,
@@ -4238,6 +4339,8 @@ DWORD RQueryServiceConfig2W(
     HKEY hServiceKey = NULL;
     DWORD dwRequiredSize;
     LPWSTR lpDescription = NULL;
+    LPWSTR lpFailureCommand = NULL;
+    LPWSTR lpRebootMessage = NULL;
 
     DPRINT("RQueryServiceConfig2W() called\n");
 
@@ -4302,8 +4405,55 @@ DWORD RQueryServiceConfig2W(
     }
     else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS)
     {
+        LPWSTR lpStr;
+        LPSERVICE_FAILURE_ACTIONSW lpFailureActions = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
+
         UNIMPLEMENTED;
-        dwError = ERROR_CALL_NOT_IMPLEMENTED;
+
+        dwError = ScmReadString(hServiceKey,
+                                L"FailureCommand",
+                                &lpFailureCommand);
+
+        dwError = ScmReadString(hServiceKey,
+                                L"RebootMessage",
+                                &lpRebootMessage);
+
+        dwRequiredSize = sizeof(SERVICE_FAILURE_ACTIONSW);
+
+        if (lpFailureCommand)
+            dwRequiredSize += (wcslen(lpFailureCommand) + 1) * sizeof(WCHAR);
+
+        if (lpRebootMessage)
+            dwRequiredSize += (wcslen(lpRebootMessage) + 1) * sizeof(WCHAR);
+
+        if (cbBufSize < dwRequiredSize)
+        {
+            *pcbBytesNeeded = dwRequiredSize;
+            dwError = ERROR_INSUFFICIENT_BUFFER;
+            goto done;
+        }
+
+        lpFailureActions->cActions = 0; 
+        lpFailureActions->dwResetPeriod = 0;
+        lpFailureActions->lpCommand = NULL;
+        lpFailureActions->lpRebootMsg = NULL;
+        lpFailureActions->lpsaActions = NULL;
+
+        lpStr = (LPWSTR)(lpFailureActions + 1);
+        if (lpRebootMessage)
+        {
+            wcscpy(lpStr, lpRebootMessage);
+            lpFailureActions->lpRebootMsg = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpRebootMessage);
+            lpStr += wcslen(lpRebootMessage) + 1;
+        }
+
+        if (lpFailureCommand)
+        {
+            wcscpy(lpStr, lpFailureCommand);
+            lpFailureActions->lpCommand = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpFailureCommand);
+            lpStr += wcslen(lpRebootMessage) + 1;
+        }
+        dwError = STATUS_SUCCESS;
         goto done;
     }
 
@@ -4311,6 +4461,12 @@ done:
     if (lpDescription != NULL)
         HeapFree(GetProcessHeap(), 0, lpDescription);
 
+    if (lpRebootMessage != NULL)
+        HeapFree(GetProcessHeap(), 0, lpRebootMessage);
+
+    if (lpFailureCommand != NULL)
+        HeapFree(GetProcessHeap(), 0, lpFailureCommand);
+
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
@@ -4324,7 +4480,6 @@ done:
 
 /* Function 40 */
 DWORD RQueryServiceStatusEx(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     SC_STATUS_TYPE InfoLevel,
     LPBYTE lpBuffer,
@@ -4385,7 +4540,6 @@ DWORD RQueryServiceStatusEx(
 
 /* Function 41 */
 DWORD REnumServicesStatusExA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     SC_ENUM_TYPE InfoLevel,
     DWORD dwServiceType,
@@ -4433,8 +4587,7 @@ DWORD REnumServicesStatusExA(
         }
     }
 
-    dwError = REnumServicesStatusExW(BindingHandle,
-                                     hSCManager,
+    dwError = REnumServicesStatusExW(hSCManager,
                                      InfoLevel,
                                      dwServiceType,
                                      dwServiceState,
@@ -4507,7 +4660,6 @@ Done:;
 
 /* Function 42 */
 DWORD REnumServicesStatusExW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hSCManager,
     SC_ENUM_TYPE InfoLevel,
     DWORD dwServiceType,
@@ -4782,7 +4934,7 @@ Done:;
 
 /* Function 43 */
 DWORD RSendTSMessage(
-    handle_t BindingHandle)
+    handle_t BindingHandle)  /* FIXME */
 {
     UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
@@ -4839,7 +4991,7 @@ DWORD RCreateServiceWOW64W(
 
 /* Function 46 */
 DWORD RQueryServiceTagInfo(
-    handle_t BindingHandle)
+    handle_t BindingHandle)  /* FIXME */
 {
     UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
@@ -4848,7 +5000,6 @@ DWORD RQueryServiceTagInfo(
 
 /* Function 47 */
 DWORD RNotifyServiceStatusChange(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     SC_RPC_NOTIFY_PARAMS NotifyParams,
     GUID *pClientProcessGuid,
@@ -4863,7 +5014,6 @@ DWORD RNotifyServiceStatusChange(
 
 /* Function 48 */
 DWORD RGetNotifyResults(
-    handle_t BindingHandle,
     SC_NOTIFY_RPC_HANDLE hNotify,
     PSC_RPC_NOTIFY_PARAMS_LIST *ppNotifyParams)
 {
@@ -4874,7 +5024,6 @@ DWORD RGetNotifyResults(
 
 /* Function 49 */
 DWORD RCloseNotifyHandle(
-    handle_t BindingHandle,
     LPSC_NOTIFY_RPC_HANDLE phNotify,
     PBOOL pfApcFired)
 {
@@ -4885,7 +5034,6 @@ DWORD RCloseNotifyHandle(
 
 /* Function 50 */
 DWORD RControlServiceExA(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwControl,
     DWORD dwInfoLevel)
@@ -4897,7 +5045,6 @@ DWORD RControlServiceExA(
 
 /* Function 51 */
 DWORD RControlServiceExW(
-    handle_t BindingHandle,
     SC_RPC_HANDLE hService,
     DWORD dwControl,
     DWORD dwInfoLevel)
@@ -4909,7 +5056,7 @@ DWORD RControlServiceExW(
 
 /* Function 52 */
 DWORD RSendPnPMessage(
-    handle_t BindingHandle)
+    handle_t BindingHandle)  /* FIXME */
 {
     UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
@@ -4918,7 +5065,7 @@ DWORD RSendPnPMessage(
 
 /* Function 53 */
 DWORD RValidatePnPService(
-    handle_t BindingHandle)
+    handle_t BindingHandle)  /* FIXME */
 {
     UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
@@ -4927,7 +5074,7 @@ DWORD RValidatePnPService(
 
 /* Function 54 */
 DWORD ROpenServiceStatusHandle(
-    handle_t BindingHandle)
+    handle_t BindingHandle)  /* FIXME */
 {
     UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
@@ -4936,14 +5083,14 @@ DWORD ROpenServiceStatusHandle(
 
 /* Function 55 */
 DWORD RFunction55(
-    handle_t BindingHandle)
+    handle_t BindingHandle)  /* FIXME */
 {
     UNIMPLEMENTED;
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
-void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
+void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
 {
     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
 }
@@ -4969,5 +5116,4 @@ void __RPC_USER SC_NOTIFY_RPC_HANDLE_rundown(SC_NOTIFY_RPC_HANDLE hNotify)
 {
 }
 
-
 /* EOF */