mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[SERVICES] Re-implement RChangeServiceConfigA() around RChangeServiceConfigW(), much as what is done for RCreateServiceA().
This commit is contained in:
parent
d6e577ced9
commit
cccf26da74
1 changed files with 84 additions and 280 deletions
|
@ -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)
|
||||
if (lpBinaryPathName)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* 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;
|
||||
MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
|
||||
}
|
||||
|
||||
if (dwServiceType != SERVICE_NO_CHANGE)
|
||||
if (lpLoadOrderGroup)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (lpBinaryPathName != NULL && *lpBinaryPathName != 0)
|
||||
{
|
||||
/* Set the image path */
|
||||
lpBinaryPathNameW = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
(strlen(lpBinaryPathName) + 1) * sizeof(WCHAR));
|
||||
if (lpBinaryPathNameW == NULL)
|
||||
len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
|
||||
lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
|
||||
if (!lpLoadOrderGroupW)
|
||||
{
|
||||
dwError = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto done;
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
|
||||
}
|
||||
|
||||
MultiByteToWideChar(CP_ACP,
|
||||
0,
|
||||
lpBinaryPathName,
|
||||
-1,
|
||||
lpBinaryPathNameW,
|
||||
(int)(strlen(lpBinaryPathName) + 1));
|
||||
|
||||
if (lpService->Status.dwServiceType & SERVICE_DRIVER)
|
||||
if (lpDependencies)
|
||||
{
|
||||
lpStr = (LPCSTR)lpDependencies;
|
||||
while (*lpStr)
|
||||
{
|
||||
dwError = ScmCanonDriverImagePath(lpService->dwStartType,
|
||||
lpBinaryPathNameW,
|
||||
&lpCanonicalImagePathW);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
|
||||
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
lpBinaryPathNameW = lpCanonicalImagePathW;
|
||||
cchLength = strlen(lpStr) + 1;
|
||||
dwDependenciesLength += (DWORD)cchLength;
|
||||
lpStr = lpStr + cchLength;
|
||||
}
|
||||
dwDependenciesLength++;
|
||||
|
||||
dwError = RegSetValueExW(hServiceKey,
|
||||
L"ImagePath",
|
||||
0,
|
||||
REG_EXPAND_SZ,
|
||||
(LPBYTE)lpBinaryPathNameW,
|
||||
(DWORD)((wcslen(lpBinaryPathNameW) + 1) * sizeof(WCHAR)));
|
||||
lpDependenciesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDependenciesLength * sizeof(WCHAR));
|
||||
if (!lpDependenciesW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
|
||||
}
|
||||
|
||||
if (lpServiceStartName)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
if (lpDisplayName)
|
||||
{
|
||||
len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
|
||||
lpDisplayNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
|
||||
if (!lpDisplayNameW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
|
||||
}
|
||||
|
||||
dwError = RChangeServiceConfigW(hService,
|
||||
dwServiceType,
|
||||
dwStartType,
|
||||
dwErrorControl,
|
||||
lpBinaryPathNameW,
|
||||
lpLoadOrderGroupW,
|
||||
lpdwTagId,
|
||||
(LPBYTE)lpDependenciesW,
|
||||
dwDependenciesLength,
|
||||
lpServiceStartNameW,
|
||||
lpPassword,
|
||||
dwPwSize,
|
||||
lpDisplayNameW);
|
||||
|
||||
cleanup:
|
||||
if (lpBinaryPathNameW != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
|
||||
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Set the group name */
|
||||
if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
|
||||
{
|
||||
lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
(strlen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
|
||||
if (lpLoadOrderGroupW == NULL)
|
||||
{
|
||||
dwError = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
|
||||
goto done;
|
||||
}
|
||||
|
||||
dwError = ScmSetServiceGroup(lpService,
|
||||
lpLoadOrderGroupW);
|
||||
|
||||
if (lpLoadOrderGroupW != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
|
||||
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (lpdwTagId != NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* Write dependencies */
|
||||
if (lpDependencies != NULL && *lpDependencies != 0)
|
||||
{
|
||||
lpDependenciesW = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
(strlen((LPSTR)lpDependencies) + 1) * sizeof(WCHAR));
|
||||
if (lpDependenciesW == NULL)
|
||||
{
|
||||
dwError = ERROR_NOT_ENOUGH_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
MultiByteToWideChar(CP_ACP,
|
||||
0,
|
||||
(LPSTR)lpDependencies,
|
||||
dwDependSize,
|
||||
lpDependenciesW,
|
||||
(int)(strlen((LPSTR)lpDependencies) + 1));
|
||||
|
||||
dwError = ScmWriteDependencies(hServiceKey,
|
||||
(LPWSTR)lpDependenciesW,
|
||||
dwDependSize);
|
||||
|
||||
if (lpDependenciesW != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, lpDependenciesW);
|
||||
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
}
|
||||
if (lpServiceStartNameW != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
|
||||
|
||||
if (lpPassword != NULL)
|
||||
{
|
||||
if (wcslen((LPWSTR)lpPassword) != 0)
|
||||
{
|
||||
/* FIXME: Decrypt the password */
|
||||
|
||||
/* 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;
|
||||
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
/* Unlock the service database */
|
||||
ScmUnlockDatabase();
|
||||
|
||||
if (hServiceKey != NULL)
|
||||
RegCloseKey(hServiceKey);
|
||||
|
||||
DPRINT("RChangeServiceConfigA() done (Error %lu)\n", dwError);
|
||||
if (lpDisplayNameW != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue