From 0adb2c35cff3bc67e57d2ca9cc6e41746352398b Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 23 Oct 2005 19:50:05 +0000 Subject: [PATCH] - Implement ScmrChangeServiceConfigW stub. - CreateServiceW calls ScmrCreateServiceW. svn path=/trunk/; revision=18723 --- reactos/lib/advapi32/service/scm.c | 97 +++++++++++------- reactos/subsys/system/services/config.c | 103 ++++++++++++++++++++ reactos/subsys/system/services/rpcserver.c | 46 +++++---- reactos/subsys/system/services/services.h | 12 ++- reactos/subsys/system/services/services.xml | 1 + 5 files changed, 205 insertions(+), 54 deletions(-) create mode 100644 reactos/subsys/system/services/config.c diff --git a/reactos/lib/advapi32/service/scm.c b/reactos/lib/advapi32/service/scm.c index 3aa83313c89..36a9285a2d1 100644 --- a/reactos/lib/advapi32/service/scm.c +++ b/reactos/lib/advapi32/service/scm.c @@ -106,26 +106,68 @@ ChangeServiceConfigA( /********************************************************************** * ChangeServiceConfigW * - * @unimplemented + * @implemented */ -BOOL -STDCALL -ChangeServiceConfigW( - SC_HANDLE hService, - DWORD dwServiceType, - DWORD dwStartType, - DWORD dwErrorControl, - LPCWSTR lpBinaryPathName, - LPCWSTR lpLoadOrderGroup, - LPDWORD lpdwTagId, - LPCWSTR lpDependencies, - LPCWSTR lpServiceStartName, - LPCWSTR lpPassword, - LPCWSTR lpDisplayName) +BOOL STDCALL +ChangeServiceConfigW(SC_HANDLE hService, + DWORD dwServiceType, + DWORD dwStartType, + DWORD dwErrorControl, + LPCWSTR lpBinaryPathName, + LPCWSTR lpLoadOrderGroup, + LPDWORD lpdwTagId, + LPCWSTR lpDependencies, + LPCWSTR lpServiceStartName, + LPCWSTR lpPassword, + LPCWSTR lpDisplayName) { - DPRINT1("ChangeServiceConfigW is unimplemented\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD dwError; + DWORD dwDependenciesLength = 0; + DWORD dwLength; + LPWSTR lpStr; + + DPRINT1("ChangeServiceConfigW() called\n"); + + /* Calculate the Dependencies length*/ + if (lpDependencies != NULL) + { + lpStr = (LPWSTR)lpDependencies; + while (*lpStr) + { + dwLength = wcslen(lpStr) + 1; + dwDependenciesLength += dwLength; + lpStr = lpStr + dwLength; + } + dwDependenciesLength++; + } + + /* FIXME: Encrypt the password */ + + HandleBind(); + + /* Call to services.exe using RPC */ + dwError = ScmrChangeServiceConfigW(BindingHandle, + (unsigned int)hService, + dwServiceType, + dwStartType, + dwErrorControl, + (LPWSTR)lpBinaryPathName, + (LPWSTR)lpLoadOrderGroup, + lpdwTagId, + (LPWSTR)lpDependencies, + dwDependenciesLength, + (LPWSTR)lpServiceStartName, + NULL, /* FIXME: lpPassword */ + 0, /* FIXME: dwPasswordLength */ + (LPWSTR)lpDisplayName); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("ScmrChangeServiceConfigW() failed (Error %lu)\n", dwError); + SetLastError(dwError); + return FALSE; + } + + return TRUE; } @@ -243,7 +285,7 @@ CreateServiceA( /********************************************************************** * CreateServiceW * - * @unimplemented + * @implemented */ SC_HANDLE STDCALL CreateServiceW(SC_HANDLE hSCManager, @@ -262,7 +304,6 @@ CreateServiceW(SC_HANDLE hSCManager, { SC_HANDLE hService = NULL; DWORD dwError; - HKEY hEnumKey, hKey; DWORD dwDependenciesLength = 0; DWORD dwLength; LPWSTR lpStr; @@ -284,7 +325,6 @@ CreateServiceW(SC_HANDLE hSCManager, /* FIXME: Encrypt the password */ -#if 0 HandleBind(); /* Call to services.exe using RPC */ @@ -299,25 +339,12 @@ CreateServiceW(SC_HANDLE hSCManager, (LPWSTR)lpBinaryPathName, (LPWSTR)lpLoadOrderGroup, lpdwTagId, - lpDependencies, + (LPWSTR)lpDependencies, dwDependenciesLength, (LPWSTR)lpServiceStartName, NULL, /* FIXME: lpPassword */ 0, /* FIXME: dwPasswordLength */ (unsigned int *)&hService); -#else - RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, KEY_ENUMERATE_SUB_KEYS, &hEnumKey); - RegCreateKeyExW(hEnumKey, lpServiceName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL); - RegCloseKey(hEnumKey); - if (lpLoadOrderGroup) - RegSetValueExW(hKey, L"Group", 0, REG_SZ, (const BYTE*)lpLoadOrderGroup, (wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR)); - RegSetValueExW(hKey, L"ImagePath", 0, REG_EXPAND_SZ, (const BYTE*)lpBinaryPathName, (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR)); - RegSetValueExW(hKey, L"ErrorControl", 0, REG_DWORD, (const BYTE*)&dwErrorControl, sizeof(dwErrorControl)); - RegSetValueExW(hKey, L"Start", 0, REG_DWORD, (const BYTE*)&dwStartType, sizeof(dwStartType)); - RegSetValueExW(hKey, L"Type", 0, REG_DWORD, (const BYTE*)&dwStartType, sizeof(dwStartType)); - RegCloseKey(hKey); - hService = INVALID_HANDLE_VALUE; dwError = ERROR_SUCCESS; -#endif if (dwError != ERROR_SUCCESS) { DPRINT1("ScmrCreateServiceW() failed (Error %lu)\n", dwError); diff --git a/reactos/subsys/system/services/config.c b/reactos/subsys/system/services/config.c new file mode 100644 index 00000000000..3e406f7a6aa --- /dev/null +++ b/reactos/subsys/system/services/config.c @@ -0,0 +1,103 @@ +/* + * config.c + */ + +/* INCLUDES *****************************************************************/ + +#include "services.h" + +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +DWORD +ScmWriteDependencies(HKEY hServiceKey, + LPWSTR lpDependencies, + DWORD dwDependenciesLength) +{ + DWORD dwError = ERROR_SUCCESS; + DWORD dwGroupLength = 0; + DWORD dwServiceLength = 0; + DWORD dwLength; + LPWSTR lpGroupDeps; + LPWSTR lpServiceDeps; + LPWSTR lpSrc; + LPWSTR lpDst; + + if (*lpDependencies == 0) + { + RegDeleteValue(hServiceKey, + L"DependOnService"); + RegDeleteValue(hServiceKey, + L"DependOnGroup"); + } + else + { + lpGroupDeps = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + (dwDependenciesLength + 2) * sizeof(WCHAR)); + if (lpGroupDeps == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + lpSrc = lpDependencies; + lpDst = lpGroupDeps; + while (*lpSrc != 0) + { + dwLength = wcslen(lpSrc); + if (*lpSrc == SC_GROUP_IDENTIFIERW) + { + lpSrc++; + dwGroupLength += dwLength; + wcscpy(lpDst, lpSrc); + lpDst = lpDst + dwLength; + } + + lpSrc = lpSrc + dwLength; + } + *lpDst = 0; + lpDst++; + dwGroupLength++; + + lpSrc = lpDependencies; + lpServiceDeps = lpDst; + while (*lpSrc != 0) + { + dwLength = wcslen(lpSrc) + 1; + if (*lpSrc != SC_GROUP_IDENTIFIERW) + { + dwServiceLength += dwLength; + wcscpy(lpDst, lpSrc); + lpDst = lpDst + dwLength; + } + + lpSrc = lpSrc + dwLength; + } + *lpDst = 0; + dwServiceLength++; + + dwError = RegSetValueExW(hServiceKey, + L"DependOnGroup", + 0, + REG_MULTI_SZ, + (LPBYTE)lpGroupDeps, + dwGroupLength * sizeof(WCHAR)); + + if (dwError == ERROR_SUCCESS) + { + dwError = RegSetValueExW(hServiceKey, + L"DependOnService", + 0, + REG_MULTI_SZ, + (LPBYTE)lpServiceDeps, + dwServiceLength * sizeof(WCHAR)); + } + + HeapFree(GetProcessHeap(), 0, lpGroupDeps); + } + + return dwError; +} + +/* EOF */ + diff --git a/reactos/subsys/system/services/rpcserver.c b/reactos/subsys/system/services/rpcserver.c index 800b10f6132..64da1b8731f 100644 --- a/reactos/subsys/system/services/rpcserver.c +++ b/reactos/subsys/system/services/rpcserver.c @@ -472,25 +472,32 @@ ScmrNotifyBootConfigStatus(handle_t BindingHandle, /* Function 11 */ -#if 0 unsigned long -ScmrChangeServiceConfigW([in] handle_t BiningHandle, - [in] SC_HANDLE hService, - [in] DWORD dwServiceType, - [in] DWORD dwStartType, - [in] DWORD dwErrorControl, - [in, string, unique] LPCWSTR lpBinaryPathName, - [in, string, unique] LPCWSTR lpLoadOrderGroup, - [in, out, unique] LPDWORD lpdwTagId, - [in, size_is(dwDependenciesLength), unique] LPCWSTR lpDependencies, - [in] DWORD dwDependenciesLength, - [in, string, unique] LPCWSTR lpServiceStartName, - [in, size_is(dwPasswordLength), unique] LPCWSTR lpPassword, - [in] DWORD dwPasswordLength, - [in, string, unique] LPCWSTR lpDisplayName) +ScmrChangeServiceConfigW(handle_t BiningHandle, + unsigned int hService, + unsigned long dwServiceType, + unsigned long dwStartType, + unsigned long dwErrorControl, + wchar_t *lpBinaryPathName, + wchar_t *lpLoadOrderGroup, + unsigned long *lpdwTagId, /* in, out, unique */ + wchar_t *lpDependencies, + unsigned long dwDependenciesLength, + wchar_t *lpServiceStartName, + wchar_t *lpPassword, + unsigned long dwPasswordLength, + wchar_t *lpDisplayName) { + DPRINT1("ScmrChangeServiceConfigW() called\n"); + DPRINT1("dwServiceType = %lu\n", dwServiceType); + DPRINT1("dwStartType = %lu\n", dwStartType); + DPRINT1("dwErrorControl = %lu\n", dwErrorControl); + DPRINT1("lpBinaryPathName = %S\n", lpBinaryPathName); + DPRINT1("lpLoadOrderGroup = %S\n", lpLoadOrderGroup); + DPRINT1("lpDisplayName = %S\n", lpDisplayName); + + return ERROR_SUCCESS; } -#endif static DWORD @@ -710,9 +717,14 @@ ScmrCreateServiceW(handle_t BindingHandle, /* FIXME: Write tag */ } + /* Write dependencies */ if (lpDependencies != NULL && *lpDependencies != 0) { - /* FIXME: Write dependencies */ + dwError = ScmWriteDependencies(hServiceKey, + lpDependencies, + dwDependenciesLength); + if (dwError != ERROR_SUCCESS) + goto done; } if (lpPassword != NULL) diff --git a/reactos/subsys/system/services/services.h b/reactos/subsys/system/services/services.h index 766d38fd421..fcecdc28d4c 100644 --- a/reactos/subsys/system/services/services.h +++ b/reactos/subsys/system/services/services.h @@ -32,9 +32,11 @@ typedef struct _SERVICE } SERVICE, *PSERVICE; -/* services.c */ +/* config.c */ -VOID PrintString(LPCSTR fmt, ...); +DWORD ScmWriteDependencies(HKEY hServiceKey, + LPWSTR lpDependencies, + DWORD dwDependenciesLength); /* database.c */ @@ -54,5 +56,11 @@ DWORD ScmMarkServiceForDelete(PSERVICE pService); VOID ScmStartRpcServer(VOID); +/* services.c */ + +VOID PrintString(LPCSTR fmt, ...); + + + /* EOF */ diff --git a/reactos/subsys/system/services/services.xml b/reactos/subsys/system/services/services.xml index 6139f5cbeaa..ac9ae45ee6e 100644 --- a/reactos/subsys/system/services/services.xml +++ b/reactos/subsys/system/services/services.xml @@ -10,6 +10,7 @@ user32 advapi32 rpcrt4 + config.c database.c rpcserver.c services.c