[SERVICES]
[reactos.git] / reactos / base / system / services / rpcserver.c
index 71a5de3..fbe4bb5 100644 (file)
@@ -12,6 +12,8 @@
 
 #include "services.h"
 
+#include <winnls.h>
+
 #define NDEBUG
 #include <debug.h>
 
@@ -301,7 +303,7 @@ ScmAssignNewTag(PSERVICE lpService)
     if (dwError != ERROR_SUCCESS && dwError != ERROR_MORE_DATA)
         goto findFreeTag;
 
-    pdwGroupTags = HeapAlloc(GetProcessHeap(), 0, cbDataSize);
+    pdwGroupTags = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbDataSize);
     if (!pdwGroupTags)
     {
         dwError = ERROR_NOT_ENOUGH_MEMORY;
@@ -395,7 +397,8 @@ cleanup:
 DWORD
 ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
 {
-    DWORD ServiceNameLen, BufferSize, ExpandedLen;
+    SIZE_T ServiceNameLen, ExpandedLen;
+    DWORD BufferSize;
     WCHAR Dest;
     WCHAR *Expanded;
     UNICODE_STRING NtPathName, SystemRoot, LinkTarget;
@@ -652,7 +655,8 @@ ScmCanonDriverImagePath(DWORD dwStartType,
                         const wchar_t *lpServiceName,
                         wchar_t **lpCanonName)
 {
-    DWORD ServiceNameLen, Result;
+    DWORD Result;
+    SIZE_T ServiceNameLen;
     UNICODE_STRING NtServiceName;
     WCHAR *RelativeName;
     const WCHAR *SourceName = lpServiceName;
@@ -895,8 +899,8 @@ Int_EnumDependentServicesW(HKEY hServicesKey,
                     {
                         /* Calculate the required size */
                         dwRequiredSize += sizeof(SERVICE_STATUS);
-                        dwRequiredSize += ((wcslen(lpCurrentService->lpServiceName) + 1) * sizeof(WCHAR));
-                        dwRequiredSize += ((wcslen(lpCurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+                        dwRequiredSize += (DWORD)((wcslen(lpCurrentService->lpServiceName) + 1) * sizeof(WCHAR));
+                        dwRequiredSize += (DWORD)((wcslen(lpCurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
 
                         /* Add the size for service name and display name pointers */
                         dwRequiredSize += (2 * sizeof(PVOID));
@@ -923,7 +927,7 @@ Int_EnumDependentServicesW(HKEY hServicesKey,
                     }
                 }
 
-                dwDependServiceStrPtr += (wcslen(lpszValueBuf + dwDependServiceStrPtr) + 1);
+                dwDependServiceStrPtr += (DWORD)(wcslen(lpszValueBuf + dwDependServiceStrPtr) + 1);
             }
         }
         else if (*pcbBytesNeeded)
@@ -1288,7 +1292,7 @@ DWORD RDeleteService(
 
     dwError = ScmMarkServiceForDelete(lpService);
 
-Done:;
+Done:
     /* Unlock the service database */
     ScmUnlockDatabase();
 
@@ -1307,7 +1311,7 @@ DWORD RLockServiceDatabase(
 
     DPRINT("RLockServiceDatabase() called\n");
 
-    *lpLock = 0;
+    *lpLock = NULL;
 
     hMgr = ScmGetServiceManagerFromHandle(hSCManager);
     if (hMgr == NULL)
@@ -1320,12 +1324,7 @@ DWORD RLockServiceDatabase(
                                   SC_MANAGER_LOCK))
         return ERROR_ACCESS_DENIED;
 
-//    return ScmLockDatabase(0, hMgr->0xC, hLock);
-
-    /* FIXME: Lock the database */
-    *lpLock = (SC_RPC_LOCK)0x12345678; /* Dummy! */
-
-    return ERROR_SUCCESS;
+    return ScmAcquireServiceStartLock(FALSE, lpLock);
 }
 
 
@@ -1618,12 +1617,13 @@ DWORD RSetServiceStatus(
 {
     PSERVICE lpService;
     DWORD dwPreviousState;
+    DWORD dwPreviousType;
     LPCWSTR lpErrorStrings[2];
     WCHAR szErrorBuffer[32];
 
     DPRINT("RSetServiceStatus() called\n");
-    DPRINT("hServiceStatus = %p\n", hServiceStatus);
-    DPRINT("dwServiceType = %lu\n", lpServiceStatus->dwServiceType);
+    DPRINT("hServiceStatus = %lu\n", hServiceStatus);
+    DPRINT("dwServiceType = 0x%lx\n", lpServiceStatus->dwServiceType);
     DPRINT("dwCurrentState = %lu\n", lpServiceStatus->dwCurrentState);
     DPRINT("dwControlsAccepted = %lu\n", lpServiceStatus->dwControlsAccepted);
     DPRINT("dwWin32ExitCode = %lu\n", lpServiceStatus->dwWin32ExitCode);
@@ -1638,11 +1638,6 @@ DWORD RSetServiceStatus(
     }
 
     lpService = (PSERVICE)hServiceStatus;
-    if (lpService == NULL)
-    {
-        DPRINT("lpService == NULL!\n");
-        return ERROR_INVALID_HANDLE;
-    }
 
     /* Check current state */
     if (!ScmIsValidServiceState(lpServiceStatus->dwCurrentState))
@@ -1672,10 +1667,17 @@ DWORD RSetServiceStatus(
     /* Save the current service state */
     dwPreviousState = lpService->Status.dwCurrentState;
 
+    /* Save the current service type */
+    dwPreviousType = lpService->Status.dwServiceType;
+
+    /* Update the service status */
     RtlCopyMemory(&lpService->Status,
                   lpServiceStatus,
                   sizeof(SERVICE_STATUS));
 
+    /* Restore the previous service type */
+    lpService->Status.dwServiceType = dwPreviousType;
+
     /* Unlock the service database */
     ScmUnlockDatabase();
 
@@ -1706,8 +1708,8 @@ DWORD RSetServiceStatus(
 DWORD RUnlockServiceDatabase(
     LPSC_RPC_LOCK Lock)
 {
-    UNIMPLEMENTED;
-    return ERROR_SUCCESS;
+    DPRINT("RUnlockServiceDatabase(%p)\n", Lock);
+    return ScmReleaseServiceStartLock(Lock);
 }
 
 
@@ -1761,7 +1763,7 @@ DWORD RChangeServiceConfigW(
     LPWSTR lpImagePathW = NULL;
 
     DPRINT("RChangeServiceConfigW() called\n");
-    DPRINT("dwServiceType = %lu\n", dwServiceType);
+    DPRINT("dwServiceType = 0x%lx\n", dwServiceType);
     DPRINT("dwStartType = %lu\n", dwStartType);
     DPRINT("dwErrorControl = %lu\n", dwErrorControl);
     DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName);
@@ -1818,11 +1820,11 @@ DWORD RChangeServiceConfigW(
                        0,
                        REG_SZ,
                        (LPBYTE)lpDisplayName,
-                       (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
+                       (DWORD)((wcslen(lpDisplayName) + 1) * sizeof(WCHAR)));
 
         /* Update the display name */
         lpDisplayNameW = HeapAlloc(GetProcessHeap(),
-                                   0,
+                                   HEAP_ZERO_MEMORY,
                                    (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
         if (lpDisplayNameW == NULL)
         {
@@ -1901,7 +1903,7 @@ DWORD RChangeServiceConfigW(
                                  0,
                                  REG_EXPAND_SZ,
                                  (LPBYTE)lpImagePathW,
-                                 (wcslen(lpImagePathW) + 1) * sizeof(WCHAR));
+                                 (DWORD)((wcslen(lpImagePathW) + 1) * sizeof(WCHAR)));
 
         if (lpImagePathW != lpBinaryPathName)
             HeapFree(GetProcessHeap(), 0, lpImagePathW);
@@ -1918,7 +1920,7 @@ DWORD RChangeServiceConfigW(
                                  0,
                                  REG_SZ,
                                  (LPBYTE)lpLoadOrderGroup,
-                                 (wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
+                                 (DWORD)((wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR)));
         if (dwError != ERROR_SUCCESS)
             goto done;
 
@@ -1958,7 +1960,7 @@ DWORD RChangeServiceConfigW(
 
     if (lpPassword != NULL)
     {
-        /* FIXME: Write password */
+        /* FIXME: Decrypt and write password */
     }
 
 done:
@@ -2005,7 +2007,7 @@ DWORD RCreateServiceW(
     DPRINT("lpServiceName = %S\n", lpServiceName);
     DPRINT("lpDisplayName = %S\n", lpDisplayName);
     DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess);
-    DPRINT("dwServiceType = %lu\n", dwServiceType);
+    DPRINT("dwServiceType = 0x%lx\n", dwServiceType);
     DPRINT("dwStartType = %lu\n", dwStartType);
     DPRINT("dwErrorControl = %lu\n", dwErrorControl);
     DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName);
@@ -2145,7 +2147,8 @@ DWORD RCreateServiceW(
         *lpDisplayName != 0 &&
         _wcsicmp(lpService->lpDisplayName, lpDisplayName) != 0)
     {
-        lpService->lpDisplayName = HeapAlloc(GetProcessHeap(), 0,
+        lpService->lpDisplayName = HeapAlloc(GetProcessHeap(),
+                                             HEAP_ZERO_MEMORY,
                                              (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
         if (lpService->lpDisplayName == NULL)
         {
@@ -2188,7 +2191,7 @@ DWORD RCreateServiceW(
                        0,
                        REG_SZ,
                        (LPBYTE)lpDisplayName,
-                       (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
+                       (DWORD)((wcslen(lpDisplayName) + 1) * sizeof(WCHAR)));
     }
 
     /* Set the service type */
@@ -2229,7 +2232,7 @@ DWORD RCreateServiceW(
                                  0,
                                  REG_EXPAND_SZ,
                                  (LPBYTE)lpBinaryPathName,
-                                 (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
+                                 (DWORD)((wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR)));
         if (dwError != ERROR_SUCCESS)
             goto done;
     }
@@ -2240,7 +2243,7 @@ DWORD RCreateServiceW(
                                  0,
                                  REG_EXPAND_SZ,
                                  (LPBYTE)lpImagePath,
-                                 (wcslen(lpImagePath) + 1) * sizeof(WCHAR));
+                                 (DWORD)((wcslen(lpImagePath) + 1) * sizeof(WCHAR)));
         if (dwError != ERROR_SUCCESS)
             goto done;
     }
@@ -2253,7 +2256,7 @@ DWORD RCreateServiceW(
                                  0,
                                  REG_SZ,
                                  (LPBYTE)lpLoadOrderGroup,
-                                 (wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
+                                 (DWORD)((wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR)));
         if (dwError != ERROR_SUCCESS)
             goto done;
     }
@@ -2289,14 +2292,14 @@ DWORD RCreateServiceW(
                                  0,
                                  REG_SZ,
                                  (LPBYTE)lpObjectName,
-                                 (wcslen(lpObjectName) + 1) * sizeof(WCHAR));
+                                 (DWORD)((wcslen(lpObjectName) + 1) * sizeof(WCHAR)));
         if (dwError != ERROR_SUCCESS)
             goto done;
     }
 
     if (lpPassword != NULL)
     {
-        /* FIXME: Write password */
+        /* FIXME: Decrypt and write password */
     }
 
     dwError = ScmCreateServiceHandle(lpService,
@@ -2312,7 +2315,7 @@ DWORD RCreateServiceW(
     lpService->dwRefCount = 1;
     DPRINT("CreateService - lpService->dwRefCount %u\n", lpService->dwRefCount);
 
-done:;
+done:
     /* Unlock the service database */
     ScmUnlockDatabase();
 
@@ -2427,7 +2430,7 @@ DWORD REnumDependentServicesW(
 
     /* Allocate memory for array of service pointers */
     lpServicesArray = HeapAlloc(GetProcessHeap(),
-                                0,
+                                HEAP_ZERO_MEMORY,
                                 (dwServicesReturned + 1) * sizeof(PSERVICE));
     if (!lpServicesArray)
     {
@@ -2450,7 +2453,7 @@ DWORD REnumDependentServicesW(
         goto Done;
     }
 
-    lpServicesPtr = (LPENUM_SERVICE_STATUSW) lpServices;
+    lpServicesPtr = (LPENUM_SERVICE_STATUSW)lpServices;
     lpStr = (LPWSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSW)));
 
     /* Copy EnumDepenedentService to Buffer */
@@ -2473,7 +2476,7 @@ DWORD REnumDependentServicesW(
         lpServicesPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
         lpStr += (wcslen(lpService->lpServiceName) + 1);
 
-        lpServicesPtr ++;
+        lpServicesPtr++;
     }
 
     *lpServicesReturned = dwServicesReturned;
@@ -2635,7 +2638,7 @@ DWORD ROpenServiceW(
     *lpServiceHandle = (SC_RPC_HANDLE)hHandle;
     DPRINT("*hService = %p\n", *lpServiceHandle);
 
-Done:;
+Done:
     /* Unlock the service database */
     ScmUnlockDatabase();
 
@@ -2662,7 +2665,6 @@ DWORD RQueryServiceConfigW(
     LPWSTR lpDependencies = NULL;
     DWORD dwDependenciesLength = 0;
     DWORD dwRequiredSize;
-    LPQUERY_SERVICE_CONFIGW lpConfig = NULL;
     WCHAR lpEmptyString[] = {0,0};
     LPWSTR lpStr;
 
@@ -2721,12 +2723,12 @@ DWORD RQueryServiceConfigW(
     dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW);
 
     if (lpImagePath != NULL)
-        dwRequiredSize += ((wcslen(lpImagePath) + 1) * sizeof(WCHAR));
+        dwRequiredSize += (DWORD)((wcslen(lpImagePath) + 1) * sizeof(WCHAR));
     else
         dwRequiredSize += 2 * sizeof(WCHAR);
 
-    if (lpService->lpGroup != NULL)
-        dwRequiredSize += ((wcslen(lpService->lpGroup->lpGroupName) + 1) * sizeof(WCHAR));
+    if ((lpService->lpGroup != NULL) && (lpService->lpGroup->lpGroupName != NULL))
+        dwRequiredSize += (DWORD)((wcslen(lpService->lpGroup->lpGroupName) + 1) * sizeof(WCHAR));
     else
         dwRequiredSize += 2 * sizeof(WCHAR);
 
@@ -2736,12 +2738,12 @@ DWORD RQueryServiceConfigW(
         dwRequiredSize += 2 * sizeof(WCHAR);
 
     if (lpServiceStartName != NULL)
-        dwRequiredSize += ((wcslen(lpServiceStartName) + 1) * sizeof(WCHAR));
+        dwRequiredSize += (DWORD)((wcslen(lpServiceStartName) + 1) * sizeof(WCHAR));
     else
         dwRequiredSize += 2 * sizeof(WCHAR);
 
     if (lpService->lpDisplayName != NULL)
-        dwRequiredSize += ((wcslen(lpService->lpDisplayName) + 1) * sizeof(WCHAR));
+        dwRequiredSize += (DWORD)((wcslen(lpService->lpDisplayName) + 1) * sizeof(WCHAR));
     else
         dwRequiredSize += 2 * sizeof(WCHAR);
 
@@ -2751,13 +2753,12 @@ DWORD RQueryServiceConfigW(
     }
     else
     {
-        lpConfig = (LPQUERY_SERVICE_CONFIGW)lpServiceConfig;
-        lpConfig->dwServiceType = lpService->Status.dwServiceType;
-        lpConfig->dwStartType = lpService->dwStartType;
-        lpConfig->dwErrorControl = lpService->dwErrorControl;
-        lpConfig->dwTagId = lpService->dwTag;
+        lpServiceConfig->dwServiceType = lpService->Status.dwServiceType;
+        lpServiceConfig->dwStartType = lpService->dwStartType;
+        lpServiceConfig->dwErrorControl = lpService->dwErrorControl;
+        lpServiceConfig->dwTagId = lpService->dwTag;
 
-        lpStr = (LPWSTR)(lpConfig + 1);
+        lpStr = (LPWSTR)(lpServiceConfig + 1);
 
         /* Append the image path */
         if (lpImagePath != NULL)
@@ -2769,11 +2770,11 @@ DWORD RQueryServiceConfigW(
             wcscpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpBinaryPathName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpBinaryPathName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
         lpStr += (wcslen(lpStr) + 1);
 
         /* Append the group name */
-        if (lpService->lpGroup != NULL)
+        if ((lpService->lpGroup != NULL) && (lpService->lpGroup->lpGroupName != NULL))
         {
             wcscpy(lpStr, lpService->lpGroup->lpGroupName);
         }
@@ -2782,7 +2783,7 @@ DWORD RQueryServiceConfigW(
             wcscpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
         lpStr += (wcslen(lpStr) + 1);
 
         /* Append Dependencies */
@@ -2797,7 +2798,7 @@ DWORD RQueryServiceConfigW(
             wcscpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpDependencies = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpDependencies = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
         if (lpDependencies != NULL)
             lpStr += dwDependenciesLength;
         else
@@ -2813,7 +2814,7 @@ DWORD RQueryServiceConfigW(
             wcscpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpServiceStartName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpServiceStartName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
         lpStr += (wcslen(lpStr) + 1);
 
         /* Append the display name */
@@ -2826,13 +2827,13 @@ DWORD RQueryServiceConfigW(
             wcscpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
     }
 
     if (pcbBytesNeeded != NULL)
         *pcbBytesNeeded = dwRequiredSize;
 
-Done:;
+Done:
     /* Unlock the service database */
     ScmUnlockDatabase();
 
@@ -2857,12 +2858,41 @@ Done:;
 /* Function 18 */
 DWORD RQueryServiceLockStatusW(
     SC_RPC_HANDLE hSCManager,
-    LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
+    LPBYTE lpBuf, // LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
     DWORD cbBufSize,
     LPBOUNDED_DWORD_4K pcbBytesNeeded)
 {
-    UNIMPLEMENTED;
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus = (LPQUERY_SERVICE_LOCK_STATUSW)lpBuf;
+    PMANAGER_HANDLE hMgr;
+    DWORD dwRequiredSize;
+
+    if (!lpLockStatus || !pcbBytesNeeded)
+        return ERROR_INVALID_PARAMETER;
+
+    hMgr = ScmGetServiceManagerFromHandle(hSCManager);
+    if (hMgr == NULL)
+    {
+        DPRINT1("Invalid service manager handle!\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
+    if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess,
+                                  SC_MANAGER_QUERY_LOCK_STATUS))
+    {
+        DPRINT("Insufficient access rights! 0x%lx\n", hMgr->Handle.DesiredAccess);
+        return ERROR_ACCESS_DENIED;
+    }
+
+    /* FIXME: we need to compute instead the real length of the owner name */
+    dwRequiredSize = sizeof(QUERY_SERVICE_LOCK_STATUSW) + sizeof(WCHAR);
+    *pcbBytesNeeded = dwRequiredSize;
+
+    if (cbBufSize < dwRequiredSize)
+        return ERROR_INSUFFICIENT_BUFFER;
+
+    ScmQueryServiceLockStatusW(lpLockStatus);
+
+    return ERROR_SUCCESS;
 }
 
 
@@ -2875,6 +2905,8 @@ DWORD RStartServiceW(
     DWORD dwError = ERROR_SUCCESS;
     PSERVICE_HANDLE hSvc;
     PSERVICE lpService = NULL;
+
+#ifndef NDEBUG
     DWORD i;
 
     DPRINT("RStartServiceW(%p %lu %p) called\n", hService, argc, argv);
@@ -2883,9 +2915,10 @@ DWORD RStartServiceW(
     {
         for (i = 0; i < argc; i++)
         {
-            DPRINT("  argv[%lu]: %S\n", i, argv[i]);
+            DPRINT("  argv[%lu]: %S\n", i, argv[i].StringPtr);
         }
     }
+#endif
 
     if (ScmShutdown)
         return ERROR_SHUTDOWN_IN_PROGRESS;
@@ -2962,7 +2995,7 @@ DWORD RGetServiceDisplayNameW(
             *lpcchBuffer = 2;
             if (lpDisplayName != NULL)
             {
-                *lpDisplayName = '\0';
+                *lpDisplayName = 0;
             }
         }
 
@@ -2971,7 +3004,7 @@ DWORD RGetServiceDisplayNameW(
 
     if (!lpService->lpDisplayName)
     {
-        dwLength = wcslen(lpService->lpServiceName);
+        dwLength = (DWORD)wcslen(lpService->lpServiceName);
 
         if (lpDisplayName != NULL &&
             *lpcchBuffer > dwLength)
@@ -2981,7 +3014,7 @@ DWORD RGetServiceDisplayNameW(
     }
     else
     {
-        dwLength = wcslen(lpService->lpDisplayName);
+        dwLength = (DWORD)wcslen(lpService->lpDisplayName);
 
         if (lpDisplayName != NULL &&
             *lpcchBuffer > dwLength)
@@ -3036,14 +3069,14 @@ DWORD RGetServiceKeyNameW(
             *lpcchBuffer = 2;
             if (lpServiceName != NULL)
             {
-                *lpServiceName = '\0';
+                *lpServiceName = 0;
             }
         }
 
         return ERROR_SERVICE_DOES_NOT_EXIST;
     }
 
-    dwLength = wcslen(lpService->lpServiceName);
+    dwLength = (DWORD)wcslen(lpService->lpServiceName);
 
     if (lpServiceName != NULL &&
         *lpcchBuffer > dwLength)
@@ -3083,7 +3116,7 @@ DWORD RChangeServiceConfigA(
     LPSTR lpBinaryPathName,
     LPSTR lpLoadOrderGroup,
     LPDWORD lpdwTagId,
-    LPSTR lpDependencies,
+    LPBYTE lpDependencies,
     DWORD dwDependSize,
     LPSTR lpServiceStartName,
     LPBYTE lpPassword,
@@ -3099,7 +3132,6 @@ DWORD RChangeServiceConfigA(
     LPWSTR lpCanonicalImagePathW = NULL;
     LPWSTR lpLoadOrderGroupW = NULL;
     LPWSTR lpDependenciesW = NULL;
-    // LPWSTR lpPasswordW = NULL;
 
     DPRINT("RChangeServiceConfigA() called\n");
     DPRINT("dwServiceType = %lu\n", dwServiceType);
@@ -3156,7 +3188,7 @@ DWORD RChangeServiceConfigA(
     {
         /* Set the display name */
         lpDisplayNameW = HeapAlloc(GetProcessHeap(),
-                                   0,
+                                   HEAP_ZERO_MEMORY,
                                    (strlen(lpDisplayName) + 1) * sizeof(WCHAR));
         if (lpDisplayNameW == NULL)
         {
@@ -3169,14 +3201,14 @@ DWORD RChangeServiceConfigA(
                             lpDisplayName,
                             -1,
                             lpDisplayNameW,
-                            strlen(lpDisplayName) + 1);
+                            (int)(strlen(lpDisplayName) + 1));
 
         RegSetValueExW(hServiceKey,
                        L"DisplayName",
                        0,
                        REG_SZ,
                        (LPBYTE)lpDisplayNameW,
-                       (wcslen(lpDisplayNameW) + 1) * sizeof(WCHAR));
+                       (DWORD)((wcslen(lpDisplayNameW) + 1) * sizeof(WCHAR)));
 
         /* Update lpService->lpDisplayName */
         if (lpService->lpDisplayName)
@@ -3234,7 +3266,7 @@ DWORD RChangeServiceConfigA(
     {
         /* Set the image path */
         lpBinaryPathNameW = HeapAlloc(GetProcessHeap(),
-                                      0,
+                                      HEAP_ZERO_MEMORY,
                                       (strlen(lpBinaryPathName) + 1) * sizeof(WCHAR));
         if (lpBinaryPathNameW == NULL)
         {
@@ -3247,7 +3279,7 @@ DWORD RChangeServiceConfigA(
                             lpBinaryPathName,
                             -1,
                             lpBinaryPathNameW,
-                            strlen(lpBinaryPathName) + 1);
+                            (int)(strlen(lpBinaryPathName) + 1));
 
         if (lpService->Status.dwServiceType & SERVICE_DRIVER)
         {
@@ -3268,7 +3300,7 @@ DWORD RChangeServiceConfigA(
                                  0,
                                  REG_EXPAND_SZ,
                                  (LPBYTE)lpBinaryPathNameW,
-                                 (wcslen(lpBinaryPathNameW) + 1) * sizeof(WCHAR));
+                                 (DWORD)((wcslen(lpBinaryPathNameW) + 1) * sizeof(WCHAR)));
 
         HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
 
@@ -3280,7 +3312,7 @@ DWORD RChangeServiceConfigA(
     if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
     {
         lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(),
-                                      0,
+                                      HEAP_ZERO_MEMORY,
                                       (strlen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
         if (lpLoadOrderGroupW == NULL)
         {
@@ -3293,14 +3325,14 @@ DWORD RChangeServiceConfigA(
                             lpLoadOrderGroup,
                             -1,
                             lpLoadOrderGroupW,
-                            strlen(lpLoadOrderGroup) + 1);
+                            (int)(strlen(lpLoadOrderGroup) + 1));
 
         dwError = RegSetValueExW(hServiceKey,
                                  L"Group",
                                  0,
                                  REG_SZ,
                                  (LPBYTE)lpLoadOrderGroupW,
-                                 (wcslen(lpLoadOrderGroupW) + 1) * sizeof(WCHAR));
+                                 (DWORD)((wcslen(lpLoadOrderGroupW) + 1) * sizeof(WCHAR)));
         if (dwError != ERROR_SUCCESS)
         {
             HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
@@ -3338,8 +3370,8 @@ DWORD RChangeServiceConfigA(
     if (lpDependencies != NULL && *lpDependencies != 0)
     {
         lpDependenciesW = HeapAlloc(GetProcessHeap(),
-                                    0,
-                                    (strlen(lpDependencies) + 1) * sizeof(WCHAR));
+                                    HEAP_ZERO_MEMORY,
+                                    (strlen((LPSTR)lpDependencies) + 1) * sizeof(WCHAR));
         if (lpDependenciesW == NULL)
         {
             dwError = ERROR_NOT_ENOUGH_MEMORY;
@@ -3348,10 +3380,10 @@ DWORD RChangeServiceConfigA(
 
         MultiByteToWideChar(CP_ACP,
                             0,
-                            lpDependencies,
+                            (LPSTR)lpDependencies,
                             dwDependSize,
                             lpDependenciesW,
-                            strlen(lpDependencies) + 1);
+                            (int)(strlen((LPSTR)lpDependencies) + 1));
 
         dwError = ScmWriteDependencies(hServiceKey,
                                        (LPWSTR)lpDependenciesW,
@@ -3362,7 +3394,7 @@ DWORD RChangeServiceConfigA(
 
     if (lpPassword != NULL)
     {
-        /* FIXME: Write password */
+        /* FIXME: Decrypt and write password */
     }
 
 done:
@@ -3405,14 +3437,14 @@ DWORD RCreateServiceA(
     LPWSTR lpDependenciesW = NULL;
     LPWSTR lpServiceStartNameW = NULL;
     DWORD dwDependenciesLength = 0;
-    DWORD dwLength;
+    SIZE_T cchLength;
     int len;
     LPCSTR lpStr;
 
     if (lpServiceName)
     {
         len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
-        lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        lpServiceNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
         if (!lpServiceNameW)
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -3424,7 +3456,7 @@ DWORD RCreateServiceA(
     if (lpDisplayName)
     {
         len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
-        lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
         if (!lpDisplayNameW)
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -3436,7 +3468,7 @@ DWORD RCreateServiceA(
     if (lpBinaryPathName)
     {
         len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
-        lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
         if (!lpBinaryPathNameW)
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -3448,7 +3480,7 @@ DWORD RCreateServiceA(
     if (lpLoadOrderGroup)
     {
         len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
-        lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
         if (!lpLoadOrderGroupW)
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -3462,13 +3494,13 @@ DWORD RCreateServiceA(
         lpStr = (LPCSTR)lpDependencies;
         while (*lpStr)
         {
-            dwLength = strlen(lpStr) + 1;
-            dwDependenciesLength += dwLength;
-            lpStr = lpStr + dwLength;
+            cchLength = strlen(lpStr) + 1;
+            dwDependenciesLength += (DWORD)cchLength;
+            lpStr = lpStr + cchLength;
         }
         dwDependenciesLength++;
 
-        lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
+        lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
         if (!lpDependenciesW)
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -3480,7 +3512,7 @@ DWORD RCreateServiceA(
     if (lpServiceStartName)
     {
         len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
-        lpServiceStartNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
         if (!lpServiceStartNameW)
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
@@ -3604,7 +3636,7 @@ DWORD REnumDependentServicesA(
 
     /* Allocate memory for array of service pointers */
     lpServicesArray = HeapAlloc(GetProcessHeap(),
-                                0,
+                                HEAP_ZERO_MEMORY,
                                 (dwServicesReturned + 1) * sizeof(PSERVICE));
     if (!lpServicesArray)
     {
@@ -3646,7 +3678,7 @@ DWORD REnumDependentServicesA(
                             lpService->lpDisplayName,
                             -1,
                             lpStr,
-                            wcslen(lpService->lpDisplayName),
+                            (int)wcslen(lpService->lpDisplayName),
                             0,
                             0);
         lpServicesPtr->lpDisplayName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
@@ -3658,13 +3690,13 @@ DWORD REnumDependentServicesA(
                             lpService->lpServiceName,
                             -1,
                             lpStr,
-                            wcslen(lpService->lpServiceName),
+                            (int)wcslen(lpService->lpServiceName),
                             0,
                             0);
         lpServicesPtr->lpServiceName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
         lpStr += strlen(lpStr) + 1;
 
-        lpServicesPtr ++;
+        lpServicesPtr++;
     }
 
     *lpServicesReturned = dwServicesReturned;
@@ -3693,6 +3725,7 @@ DWORD REnumServicesStatusA(
     LPBOUNDED_DWORD_256K lpResumeHandle)
 {
     LPENUM_SERVICE_STATUSW lpStatusPtrW = NULL;
+    LPENUM_SERVICE_STATUSW lpStatusPtrIncrW;
     LPENUM_SERVICE_STATUSA lpStatusPtrA = NULL;
     LPWSTR lpStringPtrW;
     LPSTR lpStringPtrA;
@@ -3701,6 +3734,11 @@ DWORD REnumServicesStatusA(
 
     DPRINT("REnumServicesStatusA() called\n");
 
+    if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
+    {
+        return ERROR_INVALID_ADDRESS;
+    }
+
     if ((dwBufSize > 0) && (lpBuffer))
     {
         lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);
@@ -3724,6 +3762,7 @@ DWORD REnumServicesStatusA(
     if (*lpServicesReturned == 0)
         goto Done;
 
+    lpStatusPtrIncrW = lpStatusPtrW;
     lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
     lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
                   *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSA));
@@ -3738,7 +3777,7 @@ DWORD REnumServicesStatusA(
                             lpStringPtrW,
                             -1,
                             lpStringPtrA,
-                            wcslen(lpStringPtrW),
+                            (int)wcslen(lpStringPtrW),
                             0,
                             0);
 
@@ -3752,7 +3791,7 @@ DWORD REnumServicesStatusA(
                             lpStringPtrW,
                             -1,
                             lpStringPtrA,
-                            wcslen(lpStringPtrW),
+                            (int)wcslen(lpStringPtrW),
                             0,
                             0);
 
@@ -3762,13 +3801,14 @@ DWORD REnumServicesStatusA(
 
         /* Copy the status information */
         memcpy(&lpStatusPtrA->ServiceStatus,
-               &lpStatusPtrW->ServiceStatus,
+               &lpStatusPtrIncrW->ServiceStatus,
                sizeof(SERVICE_STATUS));
 
+        lpStatusPtrIncrW++;
         lpStatusPtrA++;
     }
 
-Done:;
+Done:
     if (lpStatusPtrW)
         HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
 
@@ -3859,7 +3899,6 @@ DWORD RQueryServiceConfigA(
     LPWSTR lpDependencies = NULL;
     DWORD dwDependenciesLength = 0;
     DWORD dwRequiredSize;
-    LPQUERY_SERVICE_CONFIGA lpConfig = NULL;
     CHAR lpEmptyString[]={0,0};
     LPSTR lpStr;
 
@@ -3918,12 +3957,12 @@ DWORD RQueryServiceConfigA(
     dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGA);
 
     if (lpImagePath != NULL)
-        dwRequiredSize += wcslen(lpImagePath) + 1;
+        dwRequiredSize += (DWORD)(wcslen(lpImagePath) + 1);
     else
         dwRequiredSize += 2;
 
     if ((lpService->lpGroup != NULL) && (lpService->lpGroup->lpGroupName != NULL))
-        dwRequiredSize += wcslen(lpService->lpGroup->lpGroupName) + 1;
+        dwRequiredSize += (DWORD)(wcslen(lpService->lpGroup->lpGroupName) + 1);
     else
         dwRequiredSize += 2;
 
@@ -3934,12 +3973,12 @@ DWORD RQueryServiceConfigA(
         dwRequiredSize += 2;
 
     if (lpServiceStartName != NULL)
-        dwRequiredSize += wcslen(lpServiceStartName) + 1;
+        dwRequiredSize += (DWORD)(wcslen(lpServiceStartName) + 1);
     else
         dwRequiredSize += 2;
 
     if (lpService->lpDisplayName != NULL)
-        dwRequiredSize += wcslen(lpService->lpDisplayName) + 1;
+        dwRequiredSize += (DWORD)(wcslen(lpService->lpDisplayName) + 1);
     else
         dwRequiredSize += 2;
 
@@ -3949,11 +3988,10 @@ DWORD RQueryServiceConfigA(
     }
     else
     {
-        lpConfig = (LPQUERY_SERVICE_CONFIGA)lpServiceConfig;
-        lpConfig->dwServiceType = lpService->Status.dwServiceType;
-        lpConfig->dwStartType = lpService->dwStartType;
-        lpConfig->dwErrorControl = lpService->dwErrorControl;
-        lpConfig->dwTagId = lpService->dwTag;
+        lpServiceConfig->dwServiceType = lpService->Status.dwServiceType;
+        lpServiceConfig->dwStartType = lpService->dwStartType;
+        lpServiceConfig->dwErrorControl = lpService->dwErrorControl;
+        lpServiceConfig->dwTagId = lpService->dwTag;
 
         lpStr = (LPSTR)(lpServiceConfig + 1);
 
@@ -3967,7 +4005,7 @@ DWORD RQueryServiceConfigA(
                                 lpImagePath,
                                 -1,
                                 lpStr,
-                                wcslen(lpImagePath) + 1,
+                                (int)(wcslen(lpImagePath) + 1),
                                 0,
                                 0);
         }
@@ -3976,7 +4014,7 @@ DWORD RQueryServiceConfigA(
             strcpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpBinaryPathName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpBinaryPathName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
         lpStr += (strlen((LPSTR)lpStr) + 1);
 
         if (lpService->lpGroup && lpService->lpGroup->lpGroupName)
@@ -3986,7 +4024,7 @@ DWORD RQueryServiceConfigA(
                                 lpService->lpGroup->lpGroupName,
                                 -1,
                                 lpStr,
-                                wcslen(lpService->lpGroup->lpGroupName) + 1,
+                                (int)(wcslen(lpService->lpGroup->lpGroupName) + 1),
                                 0,
                                 0);
         }
@@ -3995,7 +4033,7 @@ DWORD RQueryServiceConfigA(
             strcpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpLoadOrderGroup = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpLoadOrderGroup = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
         lpStr += (strlen(lpStr) + 1);
 
         /* Append Dependencies */
@@ -4015,7 +4053,7 @@ DWORD RQueryServiceConfigA(
             strcpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpDependencies = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpDependencies = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
         if (lpDependencies)
             lpStr += dwDependenciesLength;
         else
@@ -4028,7 +4066,7 @@ DWORD RQueryServiceConfigA(
                                 lpServiceStartName,
                                 -1,
                                 lpStr,
-                                wcslen(lpServiceStartName) + 1,
+                                (int)(wcslen(lpServiceStartName) + 1),
                                 0,
                                 0);
         }
@@ -4037,7 +4075,7 @@ DWORD RQueryServiceConfigA(
             strcpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpServiceStartName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpServiceStartName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
         lpStr += (strlen(lpStr) + 1);
 
         if (lpService->lpDisplayName)
@@ -4047,7 +4085,7 @@ DWORD RQueryServiceConfigA(
                                 lpService->lpDisplayName,
                                 -1,
                                 lpStr,
-                                wcslen(lpService->lpDisplayName) + 1,
+                                (int)(wcslen(lpService->lpDisplayName) + 1),
                                 0,
                                 0);
         }
@@ -4056,13 +4094,13 @@ DWORD RQueryServiceConfigA(
             strcpy(lpStr, lpEmptyString);
         }
 
-        lpConfig->lpDisplayName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+        lpServiceConfig->lpDisplayName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceConfig);
     }
 
     if (pcbBytesNeeded != NULL)
         *pcbBytesNeeded = dwRequiredSize;
 
-Done:;
+Done:
     /* Unlock the service database */
     ScmUnlockDatabase();
 
@@ -4087,12 +4125,41 @@ Done:;
 /* Function 30 */
 DWORD RQueryServiceLockStatusA(
     SC_RPC_HANDLE hSCManager,
-    LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
+    LPBYTE lpBuf, // LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
     DWORD cbBufSize,
     LPBOUNDED_DWORD_4K pcbBytesNeeded)
 {
-    UNIMPLEMENTED;
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus = (LPQUERY_SERVICE_LOCK_STATUSA)lpBuf;
+    PMANAGER_HANDLE hMgr;
+    DWORD dwRequiredSize;
+
+    if (!lpLockStatus || !pcbBytesNeeded)
+        return ERROR_INVALID_PARAMETER;
+
+    hMgr = ScmGetServiceManagerFromHandle(hSCManager);
+    if (hMgr == NULL)
+    {
+        DPRINT1("Invalid service manager handle!\n");
+        return ERROR_INVALID_HANDLE;
+    }
+
+    if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess,
+                                  SC_MANAGER_QUERY_LOCK_STATUS))
+    {
+        DPRINT("Insufficient access rights! 0x%lx\n", hMgr->Handle.DesiredAccess);
+        return ERROR_ACCESS_DENIED;
+    }
+
+    /* FIXME: we need to compute instead the real length of the owner name */
+    dwRequiredSize = sizeof(QUERY_SERVICE_LOCK_STATUSA) + sizeof(CHAR);
+    *pcbBytesNeeded = dwRequiredSize;
+
+    if (cbBufSize < dwRequiredSize)
+        return ERROR_INSUFFICIENT_BUFFER;
+
+    ScmQueryServiceLockStatusA(lpLockStatus);
+
+    return ERROR_SUCCESS;
 }
 
 
@@ -4224,7 +4291,7 @@ DWORD RGetServiceDisplayNameA(
 
     if (lpServiceName != NULL)
     {
-        dwLength = strlen(lpServiceName) + 1;
+        dwLength = (DWORD)(strlen(lpServiceName) + 1);
         lpServiceNameW = HeapAlloc(GetProcessHeap(),
                                    HEAP_ZERO_MEMORY,
                                    dwLength * sizeof(WCHAR));
@@ -4254,7 +4321,7 @@ DWORD RGetServiceDisplayNameA(
             *lpcchBuffer = 1;
             if (lpDisplayName != NULL)
             {
-                *lpDisplayName = '\0';
+                *lpDisplayName = 0;
             }
         }
         return ERROR_SERVICE_DOES_NOT_EXIST;
@@ -4262,14 +4329,14 @@ DWORD RGetServiceDisplayNameA(
 
     if (!lpService->lpDisplayName)
     {
-        dwLength = wcslen(lpService->lpServiceName);
+        dwLength = (DWORD)wcslen(lpService->lpServiceName);
         if (lpDisplayName != NULL &&
             *lpcchBuffer > dwLength)
         {
             WideCharToMultiByte(CP_ACP,
                                 0,
                                 lpService->lpServiceName,
-                                wcslen(lpService->lpServiceName),
+                                (int)wcslen(lpService->lpServiceName),
                                 lpDisplayName,
                                 dwLength + 1,
                                 NULL,
@@ -4279,14 +4346,14 @@ DWORD RGetServiceDisplayNameA(
     }
     else
     {
-        dwLength = wcslen(lpService->lpDisplayName);
+        dwLength = (DWORD)wcslen(lpService->lpDisplayName);
         if (lpDisplayName != NULL &&
             *lpcchBuffer > dwLength)
         {
             WideCharToMultiByte(CP_ACP,
                                 0,
                                 lpService->lpDisplayName,
-                                wcslen(lpService->lpDisplayName),
+                                (int)wcslen(lpService->lpDisplayName),
                                 lpDisplayName,
                                 dwLength + 1,
                                 NULL,
@@ -4321,7 +4388,7 @@ DWORD RGetServiceKeyNameA(
     DPRINT("lpServiceName: %p\n", lpServiceName);
     DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
 
-    dwLength = strlen(lpDisplayName) + 1;
+    dwLength = (DWORD)(strlen(lpDisplayName) + 1);
     lpDisplayNameW = HeapAlloc(GetProcessHeap(),
                                HEAP_ZERO_MEMORY,
                                dwLength * sizeof(WCHAR));
@@ -4350,21 +4417,21 @@ DWORD RGetServiceKeyNameA(
             *lpcchBuffer = 1;
             if (lpServiceName != NULL)
             {
-                *lpServiceName = '\0';
+                *lpServiceName = 0;
             }
         }
 
         return ERROR_SERVICE_DOES_NOT_EXIST;
     }
 
-    dwLength = wcslen(lpService->lpServiceName);
+    dwLength = (DWORD)wcslen(lpService->lpServiceName);
     if (lpServiceName != NULL &&
         *lpcchBuffer > dwLength)
     {
         WideCharToMultiByte(CP_ACP,
                             0,
                             lpService->lpServiceName,
-                            wcslen(lpService->lpServiceName),
+                            (int)wcslen(lpService->lpServiceName),
                             lpServiceName,
                             dwLength + 1,
                             NULL,
@@ -4428,19 +4495,23 @@ DWORD REnumServiceGroupW(
         return ERROR_INVALID_HANDLE;
     }
 
+    if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
+    {
+        return ERROR_INVALID_ADDRESS;
+    }
+
     *pcbBytesNeeded = 0;
     *lpServicesReturned = 0;
 
     if ((dwServiceType == 0) ||
-        ((dwServiceType & ~(SERVICE_DRIVER | SERVICE_WIN32)) != 0))
+        ((dwServiceType & ~SERVICE_TYPE_ALL) != 0))
     {
         DPRINT("Not a valid Service Type!\n");
         return ERROR_INVALID_PARAMETER;
     }
 
-    if ((dwServiceState != SERVICE_ACTIVE) &&
-        (dwServiceState != SERVICE_INACTIVE) &&
-        (dwServiceState != SERVICE_STATE_ALL))
+    if ((dwServiceState == 0) ||
+        ((dwServiceState & ~SERVICE_STATE_ALL) != 0))
     {
         DPRINT("Not a valid Service State!\n");
         return ERROR_INVALID_PARAMETER;
@@ -4505,8 +4576,8 @@ DWORD REnumServiceGroupW(
         }
 
         dwSize = sizeof(ENUM_SERVICE_STATUSW) +
-                 ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
-                 ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+                 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+                 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
 
         if (dwRequiredSize + dwSize > cbBufSize)
         {
@@ -4557,8 +4628,8 @@ DWORD REnumServiceGroupW(
         }
 
         dwRequiredSize += (sizeof(ENUM_SERVICE_STATUSW) +
-                           ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
-                           ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
+                           (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+                           (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
 
         dwError = ERROR_MORE_DATA;
     }
@@ -4610,8 +4681,8 @@ DWORD REnumServiceGroupW(
         }
 
         dwSize = sizeof(ENUM_SERVICE_STATUSW) +
-                 ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
-                 ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+                 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+                 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
 
         if (dwRequiredSize + dwSize > cbBufSize)
             break;
@@ -4651,9 +4722,6 @@ Done:
 }
 
 
-//
-// WARNING: This function is untested
-//
 /* Function 36 */
 DWORD RChangeServiceConfig2A(
     SC_RPC_HANDLE hService,
@@ -4670,82 +4738,139 @@ DWORD RChangeServiceConfig2A(
 
     if (InfoW.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
     {
-        LPSERVICE_DESCRIPTIONW lpServiceDescriptonW;
-        //LPSERVICE_DESCRIPTIONA lpServiceDescriptonA;
+        LPSERVICE_DESCRIPTIONW lpServiceDescriptionW;
+        //LPSERVICE_DESCRIPTIONA lpServiceDescriptionA;
 
-        //lpServiceDescriptonA = Info.psd;
+        //lpServiceDescriptionA = Info.psd;
 
-        ///if (lpServiceDescriptonA &&
-        ///lpServiceDescriptonA->lpDescription)
+        ///if (lpServiceDescriptionA &&
+        ///lpServiceDescriptionA->lpDescription)
         ///{
-            dwLength = (strlen(Info.lpDescription) + 1) * sizeof(WCHAR);
+            dwLength = (DWORD)((strlen(Info.lpDescription) + 1) * sizeof(WCHAR));
 
-            lpServiceDescriptonW = HeapAlloc(GetProcessHeap(),
-                                             0,
-                                             dwLength + sizeof(SERVICE_DESCRIPTIONW));
-            if (!lpServiceDescriptonW)
+            lpServiceDescriptionW = HeapAlloc(GetProcessHeap(),
+                                              HEAP_ZERO_MEMORY,
+                                              dwLength + sizeof(SERVICE_DESCRIPTIONW));
+            if (!lpServiceDescriptionW)
             {
                 return ERROR_NOT_ENOUGH_MEMORY;
             }
 
-            lpServiceDescriptonW->lpDescription = (LPWSTR)(lpServiceDescriptonW + 1);
+            lpServiceDescriptionW->lpDescription = (LPWSTR)(lpServiceDescriptionW + 1);
 
             MultiByteToWideChar(CP_ACP,
                                 0,
                                 Info.lpDescription,
                                 -1,
-                                lpServiceDescriptonW->lpDescription,
+                                lpServiceDescriptionW->lpDescription,
                                 dwLength);
 
-            ptr = lpServiceDescriptonW;
-            InfoW.psd = lpServiceDescriptonW;
+            ptr = lpServiceDescriptionW;
+            InfoW.psd = lpServiceDescriptionW;
         ///}
     }
     else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
     {
         LPSERVICE_FAILURE_ACTIONSW lpServiceFailureActionsW;
         LPSERVICE_FAILURE_ACTIONSA lpServiceFailureActionsA;
-        DWORD dwRebootLen = 0;
+        DWORD dwRebootLen  = 0;
         DWORD dwCommandLen = 0;
+        DWORD dwActionArrayLen = 0;
+        LPWSTR lpStr = NULL;
 
         lpServiceFailureActionsA = Info.psfa;
 
         if (lpServiceFailureActionsA)
         {
+            /*
+             * The following code is inspired by the
+             * SERVICE_CONFIG_FAILURE_ACTIONS case of
+             * the RQueryServiceConfig2W function.
+             */
+
+            /* Retrieve the needed length for the two data strings */
             if (lpServiceFailureActionsA->lpRebootMsg)
             {
-                dwRebootLen = (strlen(lpServiceFailureActionsA->lpRebootMsg) + 1) * sizeof(WCHAR);
+                dwRebootLen = (DWORD)((strlen(lpServiceFailureActionsA->lpRebootMsg) + 1) * sizeof(WCHAR));
             }
             if (lpServiceFailureActionsA->lpCommand)
             {
-                dwCommandLen = (strlen(lpServiceFailureActionsA->lpCommand) + 1) * sizeof(WCHAR);
+                dwCommandLen = (DWORD)((strlen(lpServiceFailureActionsA->lpCommand) + 1) * sizeof(WCHAR));
             }
-            dwLength = dwRebootLen + dwCommandLen + sizeof(SERVICE_FAILURE_ACTIONSW);
 
+            /*
+             * Retrieve the size of the lpsaActions array if needed.
+             * We will copy the lpsaActions array only if there is at
+             * least one action AND that the original array is valid.
+             */
+            if (lpServiceFailureActionsA->cActions > 0 && lpServiceFailureActionsA->lpsaActions)
+            {
+                dwActionArrayLen = lpServiceFailureActionsA->cActions * sizeof(SC_ACTION);
+            }
+
+            /* Compute the total length for the UNICODE structure, including data */
+            dwLength = sizeof(SERVICE_FAILURE_ACTIONSW) +
+                       dwActionArrayLen + dwRebootLen + dwCommandLen;
+
+            /* Allocate the structure */
             lpServiceFailureActionsW = HeapAlloc(GetProcessHeap(),
-                                                 0,
+                                                 HEAP_ZERO_MEMORY,
                                                  dwLength);
             if (!lpServiceFailureActionsW)
             {
                 return ERROR_NOT_ENOUGH_MEMORY;
             }
 
-            lpServiceFailureActionsW->cActions = lpServiceFailureActionsA->cActions;
+            /* Copy the members */
             lpServiceFailureActionsW->dwResetPeriod = lpServiceFailureActionsA->dwResetPeriod;
-            CopyMemory(lpServiceFailureActionsW->lpsaActions, lpServiceFailureActionsA->lpsaActions, sizeof(SC_ACTION));
+            lpServiceFailureActionsW->cActions      = lpServiceFailureActionsA->cActions;
 
-            if (lpServiceFailureActionsA->lpRebootMsg)
+            /* Copy the lpsaActions array if needed */
+            if (dwActionArrayLen > 0)
+            {
+                /* The storage zone is just after the end of the SERVICE_FAILURE_ACTIONSW structure */
+                lpServiceFailureActionsW->lpsaActions = (LPSC_ACTION)((ULONG_PTR)(lpServiceFailureActionsW + 1));
+
+                /* dwActionArrayLen == lpServiceFailureActionsW->cActions * sizeof(SC_ACTION) */
+                RtlCopyMemory(lpServiceFailureActionsW->lpsaActions,
+                              lpServiceFailureActionsA->lpsaActions,
+                              dwActionArrayLen);
+            }
+            else
             {
+                /* No lpsaActions array */
+                lpServiceFailureActionsW->lpsaActions = NULL;
+            }
+            /* The data strings are stored just after the lpsaActions array */
+            lpStr = (LPWSTR)((ULONG_PTR)(lpServiceFailureActionsW + 1) + dwActionArrayLen);
+
+            /*
+             * Convert the data strings to UNICODE
+             */
+
+            lpServiceFailureActionsW->lpRebootMsg = NULL;
+            lpServiceFailureActionsW->lpCommand   = NULL;
+
+            if (dwRebootLen)
+            {
+                /* lpRebootMsg points just after the lpsaActions array */
+                lpServiceFailureActionsW->lpRebootMsg = lpStr;
+
                 MultiByteToWideChar(CP_ACP,
                                     0,
                                     lpServiceFailureActionsA->lpRebootMsg,
                                     -1,
                                     lpServiceFailureActionsW->lpRebootMsg,
                                     dwRebootLen);
+
+                lpStr += dwRebootLen / sizeof(WCHAR);
             }
 
-            if (lpServiceFailureActionsA->lpCommand)
+            if (dwCommandLen)
             {
+                /* lpRebootMsg points just after the lpRebootMsg data string */
+                lpServiceFailureActionsW->lpCommand = lpStr;
+
                 MultiByteToWideChar(CP_ACP,
                                     0,
                                     lpServiceFailureActionsA->lpCommand,
@@ -4754,7 +4879,9 @@ DWORD RChangeServiceConfig2A(
                                     dwCommandLen);
             }
 
+            /* Set the pointers */
             ptr = lpServiceFailureActionsW;
+            InfoW.psfa = lpServiceFailureActionsW;
         }
     }
 
@@ -4995,7 +5122,7 @@ ScmSetFailureActions(PSERVICE_HANDLE hSvc,
                                0,
                                REG_SZ,
                                (LPBYTE)lpFailureActions->lpRebootMsg,
-                               (wcslen(lpFailureActions->lpRebootMsg) + 1) * sizeof(WCHAR));
+                               (DWORD)((wcslen(lpFailureActions->lpRebootMsg) + 1) * sizeof(WCHAR)));
             }
         }
 
@@ -5016,7 +5143,7 @@ ScmSetFailureActions(PSERVICE_HANDLE hSvc,
                                0,
                                REG_SZ,
                                (LPBYTE)lpFailureActions->lpCommand,
-                               (wcslen(lpFailureActions->lpCommand) + 1) * sizeof(WCHAR));
+                               (DWORD)((wcslen(lpFailureActions->lpCommand) + 1) * sizeof(WCHAR)));
             }
         }
     }
@@ -5088,22 +5215,35 @@ DWORD RChangeServiceConfig2W(
 
     if (Info.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
     {
-        LPSERVICE_DESCRIPTIONW lpServiceDescription;
-
-        lpServiceDescription = (LPSERVICE_DESCRIPTIONW)Info.psd;
+        LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)Info.psd;
 
+        /* Modify the service description, if specified */
         if (lpServiceDescription != NULL &&
             lpServiceDescription->lpDescription != NULL)
         {
-            DPRINT("Setting value %S\n", lpServiceDescription->lpDescription);
-            dwError = RegSetValueExW(hServiceKey,
-                                     L"Description",
-                                     0,
-                                     REG_SZ,
-                                     (LPBYTE)lpServiceDescription->lpDescription,
-                                     (wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR));
-            if (dwError != ERROR_SUCCESS)
-                goto done;
+            /* If the description is "" then we delete it */
+            if (*lpServiceDescription->lpDescription == 0)
+            {
+                DPRINT("Delete service description\n");
+                dwError = RegDeleteValueW(hServiceKey, L"Description");
+
+                if (dwError == ERROR_FILE_NOT_FOUND)
+                    dwError = ERROR_SUCCESS;
+            }
+            else
+            {
+                DPRINT("Setting service description value %S\n", lpServiceDescription->lpDescription);
+                dwError = RegSetValueExW(hServiceKey,
+                                         L"Description",
+                                         0,
+                                         REG_SZ,
+                                         (LPBYTE)lpServiceDescription->lpDescription,
+                                         (DWORD)((wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR)));
+            }
+        }
+        else
+        {
+            dwError = ERROR_SUCCESS;
         }
     }
     else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
@@ -5197,7 +5337,7 @@ DWORD RQueryServiceConfig2A(
 
         *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA);
         if (dwError == ERROR_SUCCESS)
-            *pcbBytesNeeded += ((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR));
+            *pcbBytesNeeded += (DWORD)((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR));
 
         if (cbBufSize < *pcbBytesNeeded)
         {
@@ -5214,7 +5354,7 @@ DWORD RQueryServiceConfig2A(
                                 lpDescriptionW,
                                 -1,
                                 lpStr,
-                                wcslen(lpDescriptionW),
+                                (int)wcslen(lpDescriptionW),
                                 NULL,
                                 NULL);
             lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
@@ -5255,10 +5395,10 @@ DWORD RQueryServiceConfig2A(
                       &lpRebootMessageW);
 
         if (lpRebootMessageW)
-            dwRequiredSize += (wcslen(lpRebootMessageW) + 1) * sizeof(WCHAR);
+            dwRequiredSize += (DWORD)((wcslen(lpRebootMessageW) + 1) * sizeof(WCHAR));
 
         if (lpFailureCommandW)
-            dwRequiredSize += (wcslen(lpFailureCommandW) + 1) * sizeof(WCHAR);
+            dwRequiredSize += (DWORD)((wcslen(lpFailureCommandW) + 1) * sizeof(WCHAR));
 
         if (cbBufSize < dwRequiredSize)
         {
@@ -5318,7 +5458,7 @@ DWORD RQueryServiceConfig2A(
                                 lpRebootMessageW,
                                 -1,
                                 lpStr,
-                                wcslen(lpRebootMessageW),
+                                (int)wcslen(lpRebootMessageW),
                                 NULL,
                                 NULL);
             lpFailureActions->lpRebootMsg = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpFailureActions);
@@ -5332,7 +5472,7 @@ DWORD RQueryServiceConfig2A(
                                 lpFailureCommandW,
                                 -1,
                                 lpStr,
-                                wcslen(lpFailureCommandW),
+                                (int)wcslen(lpFailureCommandW),
                                 NULL,
                                 NULL);
             lpFailureActions->lpCommand = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpFailureActions);
@@ -5433,7 +5573,7 @@ DWORD RQueryServiceConfig2W(
 
         *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONW);
         if (dwError == ERROR_SUCCESS)
-            *pcbBytesNeeded += ((wcslen(lpDescription) + 1) * sizeof(WCHAR));
+            *pcbBytesNeeded += (DWORD)((wcslen(lpDescription) + 1) * sizeof(WCHAR));
 
         if (cbBufSize < *pcbBytesNeeded)
         {
@@ -5483,10 +5623,10 @@ DWORD RQueryServiceConfig2W(
                       &lpRebootMessage);
 
         if (lpRebootMessage)
-            dwRequiredSize += (wcslen(lpRebootMessage) + 1) * sizeof(WCHAR);
+            dwRequiredSize += (DWORD)((wcslen(lpRebootMessage) + 1) * sizeof(WCHAR));
 
         if (lpFailureCommand)
-            dwRequiredSize += (wcslen(lpFailureCommand) + 1) * sizeof(WCHAR);
+            dwRequiredSize += (DWORD)((wcslen(lpFailureCommand) + 1) * sizeof(WCHAR));
 
         if (cbBufSize < dwRequiredSize)
         {
@@ -5658,6 +5798,7 @@ DWORD REnumServicesStatusExA(
     LPCSTR pszGroupName)
 {
     LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrW = NULL;
+    LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrIncrW;
     LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtrA = NULL;
     LPWSTR lpStringPtrW;
     LPSTR lpStringPtrA;
@@ -5667,6 +5808,11 @@ DWORD REnumServicesStatusExA(
 
     DPRINT("REnumServicesStatusExA() called\n");
 
+    if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
+    {
+        return ERROR_INVALID_ADDRESS;
+    }
+
     if (pszGroupName)
     {
         pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
@@ -5681,7 +5827,7 @@ DWORD REnumServicesStatusExA(
                             pszGroupName,
                             -1,
                             pszGroupNameW,
-                            strlen(pszGroupName) + 1);
+                            (int)(strlen(pszGroupName) + 1));
     }
 
     if ((cbBufSize > 0) && (lpBuffer))
@@ -5709,6 +5855,7 @@ DWORD REnumServicesStatusExA(
     if (*lpServicesReturned == 0)
         goto Done;
 
+    lpStatusPtrIncrW = lpStatusPtrW;
     lpStatusPtrA = (LPENUM_SERVICE_STATUS_PROCESSA)lpBuffer;
     lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
                   *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSA));
@@ -5723,7 +5870,7 @@ DWORD REnumServicesStatusExA(
                             lpStringPtrW,
                             -1,
                             lpStringPtrA,
-                            wcslen(lpStringPtrW),
+                            (int)wcslen(lpStringPtrW),
                             0,
                             0);
 
@@ -5737,7 +5884,7 @@ DWORD REnumServicesStatusExA(
                             lpStringPtrW,
                             -1,
                             lpStringPtrA,
-                            wcslen(lpStringPtrW),
+                            (int)wcslen(lpStringPtrW),
                             0,
                             0);
 
@@ -5747,15 +5894,17 @@ DWORD REnumServicesStatusExA(
 
         /* Copy the status information */
         memcpy(&lpStatusPtrA->ServiceStatusProcess,
-               &lpStatusPtrW->ServiceStatusProcess,
+               &lpStatusPtrIncrW->ServiceStatusProcess,
                sizeof(SERVICE_STATUS));
 
-        lpStatusPtrA->ServiceStatusProcess.dwProcessId = lpStatusPtrW->ServiceStatusProcess.dwProcessId; /* FIXME */
+        lpStatusPtrA->ServiceStatusProcess.dwProcessId = lpStatusPtrIncrW->ServiceStatusProcess.dwProcessId; /* FIXME */
         lpStatusPtrA->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
+
+        lpStatusPtrIncrW++;
         lpStatusPtrA++;
     }
 
-Done:;
+Done:
     if (pszGroupNameW)
         HeapFree(GetProcessHeap(), 0, pszGroupNameW);
 
@@ -5809,19 +5958,23 @@ DWORD REnumServicesStatusExW(
         return ERROR_INVALID_HANDLE;
     }
 
+    if (pcbBytesNeeded == NULL || lpServicesReturned == NULL)
+    {
+        return ERROR_INVALID_ADDRESS;
+    }
+
     *pcbBytesNeeded = 0;
     *lpServicesReturned = 0;
 
     if ((dwServiceType == 0) ||
-        ((dwServiceType & ~(SERVICE_DRIVER | SERVICE_WIN32)) != 0))
+        ((dwServiceType & ~SERVICE_TYPE_ALL) != 0))
     {
         DPRINT("Not a valid Service Type!\n");
         return ERROR_INVALID_PARAMETER;
     }
 
-    if ((dwServiceState != SERVICE_ACTIVE) &&
-        (dwServiceState != SERVICE_INACTIVE) &&
-        (dwServiceState != SERVICE_STATE_ALL))
+    if ((dwServiceState == 0) ||
+        ((dwServiceState & ~SERVICE_STATE_ALL) != 0))
     {
         DPRINT("Not a valid Service State!\n");
         return ERROR_INVALID_PARAMETER;
@@ -5886,8 +6039,8 @@ DWORD REnumServicesStatusExW(
         }
 
         dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
-                 ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
-                 ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+                 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+                 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
 
         if (dwRequiredSize + dwSize <= cbBufSize)
         {
@@ -5941,8 +6094,8 @@ DWORD REnumServicesStatusExW(
         }
 
         dwRequiredSize += (sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
-                           ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
-                           ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
+                           (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+                           (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
 
         dwError = ERROR_MORE_DATA;
     }
@@ -6001,8 +6154,8 @@ DWORD REnumServicesStatusExW(
         }
 
         dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
-                 ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
-                 ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+                 (DWORD)((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+                 (DWORD)((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
 
         if (dwRequiredSize + dwSize <= cbBufSize)
         {
@@ -6042,7 +6195,7 @@ DWORD REnumServicesStatusExW(
             *lpResumeIndex = 0;
     }
 
-Done:;
+Done:
     /* Unlock the service database */
     ScmUnlockDatabase();