I am trying to run process as other user from my service using CreateProcessAsUser function. The example of code was found here CreateProcessAsUser from c++ service creates process but no console. OS - Windows 10
My code is working fine, when i run it in main service process. But I need run same code from child service process. And in this case CreateProcessAsUser returns 0 and GetLastError = 5 (Access Dennied).
Child service process is created by next call
CreateProcess(NULL, "d:\\child.exe", NULL, NULL, FALSE, 0u, NULL, NULL, &si.StartupInfo, &pi)
My code is working inside "child.exe" binary and should just create one more process, that starts "d:\test.exe" binary in this way
CreateProcessAsUser(hUserTokenDup,
NULL,
"d:\\test.exe",
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE | /*CREATE_BREAKAWAY_FROM_JOB |*/ NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&si,
&pi);
For test I moved code to start "test.exe" to same place where "child.exe" is starting (to service main process) and "test.exe" starts fine. For test I replaced CreateProcessAsUser on CreateProcess with same parameters (except user token) and test.exe also starts fine.
But I need start "test.exe" from service child process (from "child.exe") and start it by CreateProcessAsUser. I tryed a lot of solutions from internet (add CREATE_BREAKAWAY_FROM_JOB, use DuplicateTokenEx, use linkedToken, enable all possible privilegies and so on) but no solution helped. I do not expected any difference between service process and child process. But looks like something different and I cannot find what it is.
Can anybody advice, what is a difference between main server process and its child process?
My colleagues found the solution.
I publish it here:
Service child process could start sub-process after flags JOB_OBJECT_LIMIT_BREAKAWAY_OK|JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK has been passed to SetInformationJobObject function in server process before creating service child process. After that calls
WTSGetActiveConsoleSessionId(..
WTSQueryUserToken(...
CreateProcessAsUser(...CREATE_BREAKAWAY_FROM_JOB
work fine event without creating duplicate handle