https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cccf26da74008561f184ac379b957bdb7000ac39

commit cccf26da74008561f184ac379b957bdb7000ac39
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Sun Sep 9 22:14:57 2018 +0200
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Sun Sep 9 23:24:04 2018 +0200

    [SERVICES] Re-implement RChangeServiceConfigA() around 
RChangeServiceConfigW(), much as what is done for RCreateServiceA().
---
 base/system/services/rpcserver.c | 342 +++++++++------------------------------
 1 file changed, 73 insertions(+), 269 deletions(-)

diff --git a/base/system/services/rpcserver.c b/base/system/services/rpcserver.c
index 3c5af07499..ae6c721410 100644
--- a/base/system/services/rpcserver.c
+++ b/base/system/services/rpcserver.c
@@ -2019,6 +2019,7 @@ RChangeServiceConfigW(
         goto done;
 
     /* Write service data to the registry */
+
     /* Set the display name */
     if (lpDisplayName != NULL && *lpDisplayName != 0)
     {
@@ -3412,310 +3413,113 @@ RChangeServiceConfigA(
     LPSTR lpDisplayName)
 {
     DWORD dwError = ERROR_SUCCESS;
-    PSERVICE_HANDLE hSvc;
-    PSERVICE lpService = NULL;
-    HKEY hServiceKey = NULL;
-    LPWSTR lpDisplayNameW = NULL;
     LPWSTR lpBinaryPathNameW = NULL;
-    LPWSTR lpCanonicalImagePathW = NULL;
     LPWSTR lpLoadOrderGroupW = NULL;
     LPWSTR lpDependenciesW = NULL;
+    LPWSTR lpServiceStartNameW = NULL;
+    LPWSTR lpDisplayNameW = NULL;
+    DWORD dwDependenciesLength = 0;
+    SIZE_T cchLength;
+    int len;
+    LPCSTR lpStr;
 
-    DPRINT("RChangeServiceConfigA() called\n");
-    DPRINT("dwServiceType = %lu\n", dwServiceType);
-    DPRINT("dwStartType = %lu\n", dwStartType);
-    DPRINT("dwErrorControl = %lu\n", dwErrorControl);
-    DPRINT("lpBinaryPathName = %s\n", lpBinaryPathName);
-    DPRINT("lpLoadOrderGroup = %s\n", lpLoadOrderGroup);
-    DPRINT("lpDisplayName = %s\n", lpDisplayName);
-
-    if (ScmShutdown)
-        return ERROR_SHUTDOWN_IN_PROGRESS;
-
-    hSvc = ScmGetServiceFromHandle(hService);
-    if (hSvc == NULL)
-    {
-        DPRINT1("Invalid service handle!\n");
-        return ERROR_INVALID_HANDLE;
-    }
-
-    if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
-                                  SERVICE_CHANGE_CONFIG))
-    {
-        DPRINT("Insufficient access rights! 0x%lx\n", 
hSvc->Handle.DesiredAccess);
-        return ERROR_ACCESS_DENIED;
-    }
-
-    lpService = hSvc->ServiceEntry;
-    if (lpService == NULL)
-    {
-        DPRINT("lpService == NULL!\n");
-        return ERROR_INVALID_HANDLE;
-    }
-
-    /* Lock the service database exclusively */
-    ScmLockDatabaseExclusive();
-
-    if (lpService->bDeleted)
-    {
-        DPRINT("The service has already been marked for delete!\n");
-        dwError = ERROR_SERVICE_MARKED_FOR_DELETE;
-        goto done;
-    }
-
-    /* Open the service key */
-    dwError = ScmOpenServiceKey(lpService->szServiceName,
-                                KEY_SET_VALUE,
-                                &hServiceKey);
-    if (dwError != ERROR_SUCCESS)
-        goto done;
-
-    /* Write service data to the registry */
-
-    if (lpDisplayName != NULL && *lpDisplayName != 0)
+    if (lpBinaryPathName)
     {
-        /* Set the display name */
-        lpDisplayNameW = HeapAlloc(GetProcessHeap(),
-                                   HEAP_ZERO_MEMORY,
-                                   (strlen(lpDisplayName) + 1) * 
sizeof(WCHAR));
-        if (lpDisplayNameW == NULL)
+        len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
+        lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len 
* sizeof(WCHAR));
+        if (!lpBinaryPathNameW)
         {
-            dwError = ERROR_NOT_ENOUGH_MEMORY;
-            goto done;
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            goto cleanup;
         }
-
-        MultiByteToWideChar(CP_ACP,
-                            0,
-                            lpDisplayName,
-                            -1,
-                            lpDisplayNameW,
-                            (int)(strlen(lpDisplayName) + 1));
-
-        RegSetValueExW(hServiceKey,
-                       L"DisplayName",
-                       0,
-                       REG_SZ,
-                       (LPBYTE)lpDisplayNameW,
-                       (DWORD)((wcslen(lpDisplayNameW) + 1) * sizeof(WCHAR)));
-
-        /* Update lpService->lpDisplayName */
-        if (lpService->lpDisplayName)
-            HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
-
-        lpService->lpDisplayName = lpDisplayNameW;
-    }
-
-    if (dwServiceType != SERVICE_NO_CHANGE)
-    {
-        /* Set the service type */
-        dwError = RegSetValueExW(hServiceKey,
-                                 L"Type",
-                                 0,
-                                 REG_DWORD,
-                                 (LPBYTE)&dwServiceType,
-                                 sizeof(DWORD));
-        if (dwError != ERROR_SUCCESS)
-            goto done;
-
-        lpService->Status.dwServiceType = dwServiceType;
-    }
-
-    if (dwStartType != SERVICE_NO_CHANGE)
-    {
-        /* Set the start value */
-        dwError = RegSetValueExW(hServiceKey,
-                                 L"Start",
-                                 0,
-                                 REG_DWORD,
-                                 (LPBYTE)&dwStartType,
-                                 sizeof(DWORD));
-        if (dwError != ERROR_SUCCESS)
-            goto done;
-
-        lpService->dwStartType = dwStartType;
-    }
-
-    if (dwErrorControl != SERVICE_NO_CHANGE)
-    {
-        /* Set the error control value */
-        dwError = RegSetValueExW(hServiceKey,
-                                 L"ErrorControl",
-                                 0,
-                                 REG_DWORD,
-                                 (LPBYTE)&dwErrorControl,
-                                 sizeof(DWORD));
-        if (dwError != ERROR_SUCCESS)
-            goto done;
-
-        lpService->dwErrorControl = dwErrorControl;
+        MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, 
lpBinaryPathNameW, len);
     }
 
-    if (lpBinaryPathName != NULL && *lpBinaryPathName != 0)
+    if (lpLoadOrderGroup)
     {
-        /* Set the image path */
-        lpBinaryPathNameW = HeapAlloc(GetProcessHeap(),
-                                      HEAP_ZERO_MEMORY,
-                                      (strlen(lpBinaryPathName) + 1) * 
sizeof(WCHAR));
-        if (lpBinaryPathNameW == NULL)
-        {
-            dwError = ERROR_NOT_ENOUGH_MEMORY;
-            goto done;
-        }
-
-        MultiByteToWideChar(CP_ACP,
-                            0,
-                            lpBinaryPathName,
-                            -1,
-                            lpBinaryPathNameW,
-                            (int)(strlen(lpBinaryPathName) + 1));
-
-        if (lpService->Status.dwServiceType & SERVICE_DRIVER)
+        len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
+        lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len 
* sizeof(WCHAR));
+        if (!lpLoadOrderGroupW)
         {
-            dwError = ScmCanonDriverImagePath(lpService->dwStartType,
-                                              lpBinaryPathNameW,
-                                              &lpCanonicalImagePathW);
-
-            HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
-
-            if (dwError != ERROR_SUCCESS)
-                goto done;
-
-            lpBinaryPathNameW = lpCanonicalImagePathW;
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            goto cleanup;
         }
-
-        dwError = RegSetValueExW(hServiceKey,
-                                 L"ImagePath",
-                                 0,
-                                 REG_EXPAND_SZ,
-                                 (LPBYTE)lpBinaryPathNameW,
-                                 (DWORD)((wcslen(lpBinaryPathNameW) + 1) * 
sizeof(WCHAR)));
-
-        HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
-
-        if (dwError != ERROR_SUCCESS)
-            goto done;
+        MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, 
lpLoadOrderGroupW, len);
     }
 
-    /* Set the group name */
-    if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
+    if (lpDependencies)
     {
-        lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(),
-                                      HEAP_ZERO_MEMORY,
-                                      (strlen(lpLoadOrderGroup) + 1) * 
sizeof(WCHAR));
-        if (lpLoadOrderGroupW == NULL)
+        lpStr = (LPCSTR)lpDependencies;
+        while (*lpStr)
         {
-            dwError = ERROR_NOT_ENOUGH_MEMORY;
-            goto done;
+            cchLength = strlen(lpStr) + 1;
+            dwDependenciesLength += (DWORD)cchLength;
+            lpStr = lpStr + cchLength;
         }
+        dwDependenciesLength++;
 
-        MultiByteToWideChar(CP_ACP,
-                            0,
-                            lpLoadOrderGroup,
-                            -1,
-                            lpLoadOrderGroupW,
-                            (int)(strlen(lpLoadOrderGroup) + 1));
-
-        dwError = RegSetValueExW(hServiceKey,
-                                 L"Group",
-                                 0,
-                                 REG_SZ,
-                                 (LPBYTE)lpLoadOrderGroupW,
-                                 (DWORD)((wcslen(lpLoadOrderGroupW) + 1) * 
sizeof(WCHAR)));
-        if (dwError != ERROR_SUCCESS)
+        lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
dwDependenciesLength * sizeof(WCHAR));
+        if (!lpDependenciesW)
         {
-            HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
-            goto done;
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            goto cleanup;
         }
-
-        dwError = ScmSetServiceGroup(lpService,
-                                     lpLoadOrderGroupW);
-
-        HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
-
-        if (dwError != ERROR_SUCCESS)
-            goto done;
+        MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, 
dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
     }
 
-    if (lpdwTagId != NULL)
+    if (lpServiceStartName)
     {
-        dwError = ScmAssignNewTag(lpService);
-        if (dwError != ERROR_SUCCESS)
-            goto done;
-
-        dwError = RegSetValueExW(hServiceKey,
-                                 L"Tag",
-                                 0,
-                                 REG_DWORD,
-                                 (LPBYTE)&lpService->dwTag,
-                                 sizeof(DWORD));
-        if (dwError != ERROR_SUCCESS)
-            goto done;
-
-        *lpdwTagId = lpService->dwTag;
+        len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
+        lpServiceStartNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
len * sizeof(WCHAR));
+        if (!lpServiceStartNameW)
+        {
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            goto cleanup;
+        }
+        MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, 
lpServiceStartNameW, len);
     }
 
-    /* Write dependencies */
-    if (lpDependencies != NULL && *lpDependencies != 0)
+    if (lpDisplayName)
     {
-        lpDependenciesW = HeapAlloc(GetProcessHeap(),
-                                    HEAP_ZERO_MEMORY,
-                                    (strlen((LPSTR)lpDependencies) + 1) * 
sizeof(WCHAR));
-        if (lpDependenciesW == NULL)
+        len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
+        lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * 
sizeof(WCHAR));
+        if (!lpDisplayNameW)
         {
-            dwError = ERROR_NOT_ENOUGH_MEMORY;
-            goto done;
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            goto cleanup;
         }
-
-        MultiByteToWideChar(CP_ACP,
-                            0,
-                            (LPSTR)lpDependencies,
-                            dwDependSize,
-                            lpDependenciesW,
-                            (int)(strlen((LPSTR)lpDependencies) + 1));
-
-        dwError = ScmWriteDependencies(hServiceKey,
-                                       (LPWSTR)lpDependenciesW,
-                                       dwDependSize);
-
-        HeapFree(GetProcessHeap(), 0, lpDependenciesW);
-
-        if (dwError != ERROR_SUCCESS)
-            goto done;
+        MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
     }
 
-    if (lpPassword != NULL)
-    {
-        if (wcslen((LPWSTR)lpPassword) != 0)
-        {
-            /* FIXME: Decrypt the password */
+    dwError = RChangeServiceConfigW(hService,
+                                    dwServiceType,
+                                    dwStartType,
+                                    dwErrorControl,
+                                    lpBinaryPathNameW,
+                                    lpLoadOrderGroupW,
+                                    lpdwTagId,
+                                    (LPBYTE)lpDependenciesW,
+                                    dwDependenciesLength,
+                                    lpServiceStartNameW,
+                                    lpPassword,
+                                    dwPwSize,
+                                    lpDisplayNameW);
 
-            /* Write the password */
-            dwError = ScmSetServicePassword(lpService->szServiceName,
-                                            (LPCWSTR)lpPassword);
-            if (dwError != ERROR_SUCCESS)
-                goto done;
-        }
-        else
-        {
-            /* Delete the password */
-            dwError = ScmSetServicePassword(lpService->szServiceName,
-                                            NULL);
-            if (dwError == ERROR_FILE_NOT_FOUND)
-                dwError = ERROR_SUCCESS;
+cleanup:
+    if (lpBinaryPathNameW != NULL)
+        HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
 
-            if (dwError != ERROR_SUCCESS)
-                goto done;
-        }
-    }
+    if (lpLoadOrderGroupW != NULL)
+        HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
 
-done:
-    /* Unlock the service database */
-    ScmUnlockDatabase();
+    if (lpDependenciesW != NULL)
+        HeapFree(GetProcessHeap(), 0, lpDependenciesW);
 
-    if (hServiceKey != NULL)
-        RegCloseKey(hServiceKey);
+    if (lpServiceStartNameW != NULL)
+        HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
 
-    DPRINT("RChangeServiceConfigA() done (Error %lu)\n", dwError);
+    if (lpDisplayNameW != NULL)
+        HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
 
     return dwError;
 }

Reply via email to