https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cccf26da74008561f184a…
commit cccf26da74008561f184ac379b957bdb7000ac39
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Sep 9 22:14:57 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
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;
}