mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[SERVICES]
Create a new environment block when a service process is started. Patch by Hermès BÉLUSCA - MAÏTO. CORE-12414 svn path=/trunk/; revision=73433
This commit is contained in:
parent
c5e734fdd8
commit
cce01fa95c
2 changed files with 70 additions and 13 deletions
|
@ -26,6 +26,6 @@ if(NOT MSVC)
|
|||
endif()
|
||||
|
||||
set_module_type(services win32gui UNICODE)
|
||||
add_importlibs(services user32 advapi32 rpcrt4 msvcrt kernel32 ntdll)
|
||||
add_importlibs(services userenv user32 advapi32 rpcrt4 msvcrt kernel32 ntdll)
|
||||
add_pch(services services.h SOURCE)
|
||||
add_cd_file(TARGET services DESTINATION reactos/system32 FOR all)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "services.h"
|
||||
|
||||
#include <winuser.h>
|
||||
#include <userenv.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -1681,6 +1681,7 @@ ScmStartUserModeService(PSERVICE Service,
|
|||
{
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
STARTUPINFOW StartupInfo;
|
||||
LPVOID lpEnvironment;
|
||||
BOOL Result;
|
||||
DWORD dwError = ERROR_SUCCESS;
|
||||
|
||||
|
@ -1698,17 +1699,73 @@ ScmStartUserModeService(PSERVICE Service,
|
|||
StartupInfo.cb = sizeof(StartupInfo);
|
||||
ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
|
||||
|
||||
Result = CreateProcessAsUserW(Service->lpImage->hToken,
|
||||
NULL,
|
||||
Service->lpImage->pszImagePath,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
DETACHED_PROCESS | CREATE_SUSPENDED,
|
||||
NULL,
|
||||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation);
|
||||
/* Use the interactive desktop if the service is interactive */
|
||||
if (Service->Status.dwServiceType & SERVICE_INTERACTIVE_PROCESS)
|
||||
StartupInfo.lpDesktop = L"winsta0\\default";
|
||||
|
||||
if (Service->lpImage->hToken)
|
||||
{
|
||||
/* User token: Run the service under the user account */
|
||||
|
||||
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());
|
||||
lpEnvironment = NULL;
|
||||
}
|
||||
|
||||
/* Impersonate the new user */
|
||||
if (!ImpersonateLoggedOnUser(Service->lpImage->hToken))
|
||||
{
|
||||
dwError = GetLastError();
|
||||
DPRINT1("ImpersonateLoggedOnUser() failed with error %d\n", GetLastError());
|
||||
return 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
|
||||
{
|
||||
/* No user token: Run the service under the LocalSystem account */
|
||||
|
||||
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());
|
||||
lpEnvironment = NULL;
|
||||
}
|
||||
|
||||
Result = CreateProcessW(NULL,
|
||||
Service->lpImage->pszImagePath,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS | CREATE_SUSPENDED,
|
||||
lpEnvironment,
|
||||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation);
|
||||
}
|
||||
|
||||
if (lpEnvironment)
|
||||
DestroyEnvironmentBlock(lpEnvironment);
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
|
|
Loading…
Reference in a new issue