From cccf26da74008561f184ac379b957bdb7000ac39 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 9 Sep 2018 22:14:57 +0200 Subject: [PATCH] [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 3c5af07499d..ae6c721410a 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; } -- 2.17.1