Sunday, March 29, 2009

Vista session 0 isolation, launching UI based applications from Windows Services in Vista.

/*
After going thru few samples, I came up with the following code which worked for me. I used a service running in Local System Account to test this sample.

http://blogs.technet.com/askperf/archive/2007/04/27/application-compatibility-session-0-isolation.aspx

*/

BOOL LaunchAppIntoInteractiveSession(CHAR *szCommandline, DWORD &dwExitCode)
{
BOOL bResult = TRUE;
DWORD dwSessionId = 0;
HANDLE hUserToken = NULL, hUserTokenDup = NULL;
DWORD dwCreationFlags = 0;

// Get active session
dwSessionId = WTSGetActiveConsoleSessionId();

if (!WTSQueryUserToken(dwSessionId, &hUserToken))
{
//handle the error
goto Cleanup;
}

if (!DuplicateTokenEx(hUserToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hUserTokenDup))
{
//handle the error
goto Cleanup;
}

LPVOID lpEnvironment = NULL;

/*if(CreateEnvironmentBlock(&lpEnvironment, hUserTokenDup, TRUE))
{
dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
}
else
{
lpEnvironment = NULL;
}*/

PROCESS_INFORMATION pi;
STARTUPINFO si;
dwCreationFlags = NORMAL_PRIORITY_CLASS CREATE_NEW_CONSOLE;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";
ZeroMemory(&pi, sizeof(pi));

// Launch the process in the client's logon session.
if (!CreateProcessAsUser(
hUserTokenDup, // client's access token
NULL, // file name
szCommandline, // commandline to execute
NULL, // pointer to process SECURITY_ATTRIBUTES
NULL, // pointer to thread SECURITY_ATTRIBUTES
FALSE, // handles are not inheritable
dwCreationFlags, // creation flags
lpEnvironment, // pointer to new environment block
NULL, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
))
{
//handle the error
}

//Wait until process exits.
WaitForSingleObject(pi.hProcess, INFINITE);

//Get the process exit code.
if (!GetExitCodeProcess(pi.hProcess, &dwExitCode))
{
//handle the error
goto Cleanup;
}

/*if (!DestroyEnvironmentBlock(lpEnvironment))
{
//handle the error
goto Cleanup;
}
*/

Cleanup:

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread );

CloseHandle(hUserToken);
CloseHandle(hUserTokenDup);

return bResult;
}

0 comments: