Reputation: 6894
Environment - VS2008, Vista SP1.
I have written a process management service which can launch applications either in session 0 or the interactive console (usually 1). Please note this is NOT the normal mode of operation, it's for in-house debug purposes only. In the field, these processes will be safely hidden away in session 0. Security concerns do not apply.
I use the following code to do this:
ZeroMemory (&sui, sizeof(STARTUPINFO));
sui.cb = sizeof (STARTUPINFO);
sui.wShowWindow = pTask->GetWinStartState() ;
sui.dwFlags = STARTF_USESHOWWINDOW ;
ZeroMemory (&pi,sizeof(pi));
if (bInteractive)
{
HANDLE hToken = NULL;
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
WTSQueryUserToken (dwSessionId, &hToken);
sui.lpDesktop = TEXT("winsta0\\default");
LPVOID pEnv = NULL;
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
HMODULE hModu = LoadLibrary(TEXT("Userenv.dll"));
if (hModu )
{
if (CreateEnvironmentBlock (&pEnv, hToken, FALSE))
dwCreationFlag |= CREATE_UNICODE_ENVIRONMENT;
else
pEnv = NULL;
}
bCreatedOk = CreateProcessAsUser (hToken,
NULL,
(LPTSTR)(pTask->GetExeName()),
NULL,
NULL,
FALSE,
dwCreationFlag,
pEnv,
NULL,
&sui,
&pi);
}
else
{
bCreatedOk = CreateProcess (NULL, ... blah...);
}
This all works fine and I can run and monitor native processes both in the Vista service session and the console. Great. Cakes and ale for everyone.
So here's the problem. If I try to run a winforms (C#) app interactively like this, it appears to run, shows up in Process Explorer as running in session 1, but on the desktop... nada. No window appears at all. The process runs up and shuts down all fine, but no window ever appears. The exact same winform exe run from explorer also shows up in session 1, but this time appears on the desktop just fine.
Any ideas ?
Upvotes: 1
Views: 1780
Reputation: 9645
Despite the evident hysteria there is nothing wrong with launching an application from a service into an interactive session provided it is done with the same privileges as the interactive user or lower. Since you are launching as the interactive user there can be no privilege escalation.
What you are doing does work. I suspect that the issue has something to do with your STARTUPINFO struct. You appear to be creating your sui on the stack but you don't show what you are doing with it. Are you initializing it to all 0s, if not you may be getting some garbage from the stack that is causing the window not to show or to show at some co-ordinates off the screen.
Upvotes: 1
Reputation: 93424
In a word, "don't".
Services typically run with reduced privileges and NOT as the current user. As such, in Vista+ they're not allowed to interact with the users desktop. On top of all that, services get a null Window Station.
You used to be able to check a box that said something like "Allow to interact with the desktop" but not anymore. It's bad practice.
Your best bet is to create a helper app that runs in the users context and communicates with the service via a named pipe, LRPC or a socket, then have your helper app launch the program for the user. This is the way most anti-virus now works.
Also, read this whitepaper from Microsoft on the subject. Services can't run in anything other than session 0.
NOTE: a little research seems to indicate that you need to duplicate the token using something like this:
DuplicateTokenEx(hTokenNew,MAXIMUM_ALLOWED,NULL,
SecurityIdentification,TokenPrimary,&hTokenDup);
Upvotes: 0
Reputation: 2634
It looks as if you're trying to break Session Isolation. Like Mystere Man said, I don't think it's the right thing to do.
http://support.microsoft.com/?scid=kb%3Ben-us%3B165194&x=5&y=3 might be useful if you really want to do this. In the code sample over there, they seem to initialize more thing than you do.
EDIT If it's for debugging purposes, i-e VS 2008 step-in, just add a wait loop at the beginning, and launch VS with administrator rights. You can attach to your service process without encountering system isolation.
Upvotes: 0