Author: ekohl
Date: Tue Dec 6 17:29:30 2016
New Revision: 73433
URL:
http://svn.reactos.org/svn/reactos?rev=73433&view=rev
Log:
[SERVICES]
Create a new environment block when a service process is started.
Patch by Hermès BÉLUSCA - MAÏTO.
CORE-12414
Modified:
trunk/reactos/base/system/services/CMakeLists.txt
trunk/reactos/base/system/services/database.c
Modified: trunk/reactos/base/system/services/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/CMake…
==============================================================================
--- trunk/reactos/base/system/services/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/CMakeLists.txt [iso-8859-1] Tue Dec 6 17:29:30
2016
@@ -26,6 +26,6 @@
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)
Modified: trunk/reactos/base/system/services/database.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/datab…
==============================================================================
--- trunk/reactos/base/system/services/database.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/database.c [iso-8859-1] Tue Dec 6 17:29:30 2016
@@ -14,7 +14,7 @@
#include "services.h"
-#include <winuser.h>
+#include <userenv.h>
#define NDEBUG
#include <debug.h>
@@ -1681,6 +1681,7 @@
{
PROCESS_INFORMATION ProcessInformation;
STARTUPINFOW StartupInfo;
+ LPVOID lpEnvironment;
BOOL Result;
DWORD dwError = ERROR_SUCCESS;
@@ -1698,17 +1699,73 @@
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();