From f86f34bda5bcaadd45842ff8e6d78b72e368227b Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 23 Oct 2005 06:19:15 +0000 Subject: [PATCH] Improvements to ScmrCreateServiceW: - Allocate a service record for the new service. - Fix registry value types and sizes. - Fail if the new service already exists. svn path=/trunk/; revision=18693 --- reactos/subsys/system/services/database.c | 39 +++++++++- reactos/subsys/system/services/rpcserver.c | 82 ++++++++++++++++------ reactos/subsys/system/services/services.h | 2 + 3 files changed, 101 insertions(+), 22 deletions(-) diff --git a/reactos/subsys/system/services/database.c b/reactos/subsys/system/services/database.c index 6c3b9f1622e..2c28e9da7eb 100644 --- a/reactos/subsys/system/services/database.c +++ b/reactos/subsys/system/services/database.c @@ -186,11 +186,10 @@ static NTSTATUS STDCALL CreateServiceListEntry(LPWSTR lpServiceName) { RTL_QUERY_REGISTRY_TABLE QueryTable[6]; - UNICODE_STRING ServiceName; PSERVICE Service = NULL; NTSTATUS Status; - DPRINT("Service: '%wZ'\n", ServiceName); + DPRINT("Service: '%S'\n", lpServiceName); /* Allocate service entry */ @@ -265,6 +264,42 @@ CreateServiceListEntry(LPWSTR lpServiceName) } +DWORD +ScmCreateNewServiceRecord(LPWSTR lpServiceName, + PSERVICE *lpServiceRecord) +{ + PSERVICE lpService = NULL; + + DPRINT("Service: '%S'\n", lpServiceName); + + /* Allocate service entry */ + lpService = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(SERVICE) + ((wcslen(lpServiceName) + 1) * sizeof(WCHAR))); + if (lpService == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + *lpServiceRecord = lpService; + + /* Copy service name */ + wcscpy(lpService->szServiceName, lpServiceName); + lpService->lpServiceName = lpService->szServiceName; + + /* Append service entry */ + InsertTailList(&ServiceListHead, + &lpService->ServiceListEntry); + + lpService->Status.dwCurrentState = SERVICE_STOPPED; + lpService->Status.dwControlsAccepted = 0; + lpService->Status.dwWin32ExitCode = ERROR_SERVICE_NEVER_STARTED; + lpService->Status.dwServiceSpecificExitCode = 0; + lpService->Status.dwCheckPoint = 0; + lpService->Status.dwWaitHint = 2000; /* 2 seconds */ + + return ERROR_SUCCESS; +} + + NTSTATUS ScmCreateServiceDataBase(VOID) { diff --git a/reactos/subsys/system/services/rpcserver.c b/reactos/subsys/system/services/rpcserver.c index 01417340a0b..800b10f6132 100644 --- a/reactos/subsys/system/services/rpcserver.c +++ b/reactos/subsys/system/services/rpcserver.c @@ -493,9 +493,9 @@ ScmrChangeServiceConfigW([in] handle_t BiningHandle, #endif -#if 0 static DWORD -CreateServiceKey(LPWSTR lpServiceName, PHKEY phKey) +CreateServiceKey(LPWSTR lpServiceName, + PHKEY phKey) { HKEY hServicesKey = NULL; DWORD dwDisposition; @@ -520,6 +520,7 @@ CreateServiceKey(LPWSTR lpServiceName, PHKEY phKey) NULL, phKey, &dwDisposition); +#if 0 if ((dwError == ERROR_SUCCESS) && (dwDisposition == REG_OPENED_EXISTING_KEY)) { @@ -527,12 +528,12 @@ CreateServiceKey(LPWSTR lpServiceName, PHKEY phKey) *phKey = NULL; dwError = ERROR_SERVICE_EXISTS; } +#endif RegCloseKey(hServicesKey); return dwError; } -#endif /* Function 12 */ @@ -557,10 +558,10 @@ ScmrCreateServiceW(handle_t BindingHandle, { PMANAGER_HANDLE hManager; DWORD dwError = ERROR_SUCCESS; -#if 0 - HKEY hServiceKey = NULL; + PSERVICE lpService = NULL; + SC_HANDLE hServiceHandle = NULL; LPWSTR lpImagePath = NULL; -#endif + HKEY hServiceKey = NULL; DPRINT1("ScmrCreateServiceW() called\n"); DPRINT1("lpServiceName = %S\n", lpServiceName); @@ -588,15 +589,16 @@ ScmrCreateServiceW(handle_t BindingHandle, return ERROR_ACCESS_DENIED; } - /* FIXME: Fail if the service already exists! */ + /* Fail if the service already exists! */ + if (ScmGetServiceEntryByName(lpServiceName) != NULL) + return ERROR_SERVICE_EXISTS; -#if 0 if (dwServiceType & SERVICE_DRIVER) { /* FIXME: Adjust the image path */ lpImagePath = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - wcslen(lpBinaryPathName) + sizeof(WCHAR)); + (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR)); if (lpImagePath == NULL) { dwError = ERROR_NOT_ENOUGH_MEMORY; @@ -605,14 +607,18 @@ ScmrCreateServiceW(handle_t BindingHandle, wcscpy(lpImagePath, lpBinaryPathName); } - /* FIXME: Allocate and fill a service entry */ -// dwError = CreateNewServiceListEntry(lpServiceName, -// &lpServiceEntry) + /* Allocate a new service entry */ + dwError = ScmCreateNewServiceRecord(lpServiceName, + &lpService); + if (dwError != ERROR_SUCCESS) + goto done; -// if (lpdwTagId != NULL) -// *lpdwTagId = 0; + /* Fill the new service entry */ + lpService->Status.dwServiceType = dwServiceType; + lpService->dwStartType = dwStartType; + lpService->dwErrorControl = dwErrorControl; -// *hService = 0; + /* FIXME: set lpLoadOrderGroup, lpDependencies etc. */ /* Write service data to the registry */ @@ -621,6 +627,7 @@ ScmrCreateServiceW(handle_t BindingHandle, if (dwError != ERROR_SUCCESS) goto done; + /* Set the display name */ if (lpDisplayName != NULL && *lpDisplayName != 0) { RegSetValueExW(hServiceKey, @@ -667,7 +674,7 @@ ScmrCreateServiceW(handle_t BindingHandle, dwError = RegSetValueExW(hServiceKey, L"ImagePath", 0, - REG_SZ, + REG_EXPAND_SZ, (LPBYTE)lpBinaryPathName, (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR)); if (dwError != ERROR_SUCCESS) @@ -675,13 +682,12 @@ ScmrCreateServiceW(handle_t BindingHandle, } else if (dwServiceType & SERVICE_DRIVER) { - /* FIXME: Adjust the path name */ dwError = RegSetValueExW(hServiceKey, L"ImagePath", 0, - REG_SZ, + REG_EXPAND_SZ, (LPBYTE)lpImagePath, - (wcslen(lpImagePath) + 1) *sizeof(WCHAR)); + (wcslen(lpImagePath) + 1) *sizeof(WCHAR)); if (dwError != ERROR_SUCCESS) goto done; } @@ -699,6 +705,11 @@ ScmrCreateServiceW(handle_t BindingHandle, goto done; } + if (lpdwTagId != NULL) + { + /* FIXME: Write tag */ + } + if (lpDependencies != NULL && *lpDependencies != 0) { /* FIXME: Write dependencies */ @@ -709,13 +720,44 @@ ScmrCreateServiceW(handle_t BindingHandle, /* FIXME: Write password */ } + dwError = ScmCreateServiceHandle(lpService, + &hServiceHandle); + if (dwError != ERROR_SUCCESS) + goto done; + + dwError = ScmCheckAccess(hServiceHandle, + dwDesiredAccess); + if (dwError != ERROR_SUCCESS) + goto done; + done:; if (hServiceKey != NULL) RegCloseKey(hServiceKey); + if (dwError == ERROR_SUCCESS) + { + DPRINT1("hService %lx\n", hServiceHandle); + *hService = (unsigned int)hServiceHandle; + + if (lpdwTagId != NULL) + *lpdwTagId = 0; /* FIXME */ + } + else + { + if (hServiceHandle != NULL) + { + /* Remove the service handle */ + HeapFree(GetProcessHeap(), 0, hServiceHandle); + } + + if (lpService != NULL) + { + /* FIXME: remove the service entry */ + } + } + if (lpImagePath != NULL) HeapFree(GetProcessHeap(), 0, lpImagePath); -#endif DPRINT1("ScmrCreateServiceW() done (Error %lu)\n", dwError); diff --git a/reactos/subsys/system/services/services.h b/reactos/subsys/system/services/services.h index 93a667f9e76..766d38fd421 100644 --- a/reactos/subsys/system/services/services.h +++ b/reactos/subsys/system/services/services.h @@ -44,6 +44,8 @@ VOID ScmGetBootAndSystemDriverState(VOID); VOID ScmAutoStartServices(VOID); PSERVICE ScmGetServiceEntryByName(LPWSTR lpServiceName); +DWORD ScmCreateNewServiceRecord(LPWSTR lpServiceName, + PSERVICE *lpServiceRecord); DWORD ScmMarkServiceForDelete(PSERVICE pService);