From 0b5c61d4932988bd8887398245b88679def67087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 6 Dec 2016 23:01:27 +0000 Subject: [PATCH] [SERVICES]: Addendum to r73433 for ScmStartUserModeService: - Use the correct capitalization for the desktop name (to be consistent with all the rest of our code); - Fix DPRINT1 order of arguments; - Reorganize a bit the code to avoid the memory leak if ImpersonateLoggedOnUser fails and the environment block was already allocated (caught by Ged Murphy). CORE-12414 svn path=/trunk/; revision=73435 --- reactos/base/system/services/database.c | 61 ++++++++++++++----------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/reactos/base/system/services/database.c b/reactos/base/system/services/database.c index fbe1f21b4e7..42b51001a7c 100644 --- a/reactos/base/system/services/database.c +++ b/reactos/base/system/services/database.c @@ -1700,8 +1700,11 @@ ScmStartUserModeService(PSERVICE Service, ZeroMemory(&ProcessInformation, sizeof(ProcessInformation)); /* Use the interactive desktop if the service is interactive */ + // TODO: We should also check the value "NoInteractiveServices ": + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683502(v=vs.85).aspx + // for more details. if (Service->Status.dwServiceType & SERVICE_INTERACTIVE_PROCESS) - StartupInfo.lpDesktop = L"winsta0\\default"; + StartupInfo.lpDesktop = L"WinSta0\\Default"; if (Service->lpImage->hToken) { @@ -1710,34 +1713,38 @@ ScmStartUserModeService(PSERVICE Service, if (!CreateEnvironmentBlock(&lpEnvironment, Service->lpImage->hToken, FALSE)) { /* We failed, run the service with the current environment */ - DPRINT1("CreateEnvironmentBlock() failed with error %d, service '%S' will run with the current environment.\n", - Service->lpServiceName, GetLastError()); + DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with the current environment.\n", + GetLastError(), Service->lpServiceName); lpEnvironment = NULL; } /* Impersonate the new user */ - if (!ImpersonateLoggedOnUser(Service->lpImage->hToken)) + Result = ImpersonateLoggedOnUser(Service->lpImage->hToken); + if (Result) + { + /* Launch the process in the user's logon session */ + Result = CreateProcessAsUserW(Service->lpImage->hToken, + NULL, + Service->lpImage->pszImagePath, + NULL, + NULL, + FALSE, + CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS | CREATE_SUSPENDED, + lpEnvironment, + NULL, + &StartupInfo, + &ProcessInformation); + if (!Result) + dwError = GetLastError(); + + /* Revert the impersonation */ + RevertToSelf(); + } + else { dwError = GetLastError(); - DPRINT1("ImpersonateLoggedOnUser() failed with error %d\n", GetLastError()); - return dwError; + DPRINT1("ImpersonateLoggedOnUser() failed with error %d\n", dwError); } - - /* Launch the process in the user's logon session */ - Result = CreateProcessAsUserW(Service->lpImage->hToken, - NULL, - Service->lpImage->pszImagePath, - NULL, - NULL, - FALSE, - CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS | CREATE_SUSPENDED, - lpEnvironment, - NULL, - &StartupInfo, - &ProcessInformation); - - /* Revert the impersonation */ - RevertToSelf(); } else { @@ -1746,8 +1753,8 @@ ScmStartUserModeService(PSERVICE Service, if (!CreateEnvironmentBlock(&lpEnvironment, NULL, TRUE)) { /* We failed, run the service with the current environment */ - DPRINT1("CreateEnvironmentBlock() failed with error %d, service '%S' will run with the current environment.\n", - Service->lpServiceName, GetLastError()); + DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with the current environment.\n", + GetLastError(), Service->lpServiceName); lpEnvironment = NULL; } @@ -1761,6 +1768,8 @@ ScmStartUserModeService(PSERVICE Service, NULL, &StartupInfo, &ProcessInformation); + if (!Result) + dwError = GetLastError(); } if (lpEnvironment) @@ -1768,8 +1777,8 @@ ScmStartUserModeService(PSERVICE Service, if (!Result) { - dwError = GetLastError(); - DPRINT1("Starting '%S' failed!\n", Service->lpServiceName); + DPRINT1("Starting '%S' failed with error %d\n", + Service->lpServiceName, dwError); return dwError; }