[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
This commit is contained in:
Hermès Bélusca-Maïto 2016-12-06 23:01:27 +00:00
parent 54e99fcd1b
commit 0b5c61d493

View file

@ -1700,8 +1700,11 @@ ScmStartUserModeService(PSERVICE Service,
ZeroMemory(&ProcessInformation, sizeof(ProcessInformation)); ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
/* Use the interactive desktop if the service is interactive */ /* 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) if (Service->Status.dwServiceType & SERVICE_INTERACTIVE_PROCESS)
StartupInfo.lpDesktop = L"winsta0\\default"; StartupInfo.lpDesktop = L"WinSta0\\Default";
if (Service->lpImage->hToken) if (Service->lpImage->hToken)
{ {
@ -1710,19 +1713,15 @@ ScmStartUserModeService(PSERVICE Service,
if (!CreateEnvironmentBlock(&lpEnvironment, Service->lpImage->hToken, FALSE)) if (!CreateEnvironmentBlock(&lpEnvironment, Service->lpImage->hToken, FALSE))
{ {
/* We failed, run the service with the current environment */ /* We failed, run the service with the current environment */
DPRINT1("CreateEnvironmentBlock() failed with error %d, service '%S' will run with the current environment.\n", DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with the current environment.\n",
Service->lpServiceName, GetLastError()); GetLastError(), Service->lpServiceName);
lpEnvironment = NULL; lpEnvironment = NULL;
} }
/* Impersonate the new user */ /* Impersonate the new user */
if (!ImpersonateLoggedOnUser(Service->lpImage->hToken)) Result = ImpersonateLoggedOnUser(Service->lpImage->hToken);
if (Result)
{ {
dwError = GetLastError();
DPRINT1("ImpersonateLoggedOnUser() failed with error %d\n", GetLastError());
return dwError;
}
/* Launch the process in the user's logon session */ /* Launch the process in the user's logon session */
Result = CreateProcessAsUserW(Service->lpImage->hToken, Result = CreateProcessAsUserW(Service->lpImage->hToken,
NULL, NULL,
@ -1735,19 +1734,27 @@ ScmStartUserModeService(PSERVICE Service,
NULL, NULL,
&StartupInfo, &StartupInfo,
&ProcessInformation); &ProcessInformation);
if (!Result)
dwError = GetLastError();
/* Revert the impersonation */ /* Revert the impersonation */
RevertToSelf(); RevertToSelf();
} }
else else
{
dwError = GetLastError();
DPRINT1("ImpersonateLoggedOnUser() failed with error %d\n", dwError);
}
}
else
{ {
/* No user token: Run the service under the LocalSystem account */ /* No user token: Run the service under the LocalSystem account */
if (!CreateEnvironmentBlock(&lpEnvironment, NULL, TRUE)) if (!CreateEnvironmentBlock(&lpEnvironment, NULL, TRUE))
{ {
/* We failed, run the service with the current environment */ /* We failed, run the service with the current environment */
DPRINT1("CreateEnvironmentBlock() failed with error %d, service '%S' will run with the current environment.\n", DPRINT1("CreateEnvironmentBlock() failed with error %d; service '%S' will run with the current environment.\n",
Service->lpServiceName, GetLastError()); GetLastError(), Service->lpServiceName);
lpEnvironment = NULL; lpEnvironment = NULL;
} }
@ -1761,6 +1768,8 @@ ScmStartUserModeService(PSERVICE Service,
NULL, NULL,
&StartupInfo, &StartupInfo,
&ProcessInformation); &ProcessInformation);
if (!Result)
dwError = GetLastError();
} }
if (lpEnvironment) if (lpEnvironment)
@ -1768,8 +1777,8 @@ ScmStartUserModeService(PSERVICE Service,
if (!Result) if (!Result)
{ {
dwError = GetLastError(); DPRINT1("Starting '%S' failed with error %d\n",
DPRINT1("Starting '%S' failed!\n", Service->lpServiceName); Service->lpServiceName, dwError);
return dwError; return dwError;
} }