According to some MS documents (e.g. http://www.microsoft.com/whdc/system/vista/services.mspx), it should be possible to use CreateProcessAsUser() API in a Vista service to create a process in user session. I am trying to achive this, but the function returns error code 1307 (ERROR_INVALID_OWNER) = "This security ID may not be assigned as the owner of this object."
Does it work for somebody Many thanks in advance.

Calling CreateProcessAsUser() from service
bitbonk
Mine was the same senerio, calling CreateProcessAsUser from service.
I followed the steps given by you, and it really worked for me thanks
HANDLE hTokenNew = NULL, hTokenDup = NULL;
HMODULE hmod = LoadLibrary("kernel32.dll");
...
Hi !
Could you tell me what sort of libraries did you included to make this piece of code working When I pasted it in VS a lot of errors occured...
For sure there were libraries: WtsApi32.h, windows.h and variables declarations STARTUPINFO si; PROCESS_INFORMATION pi;,
but others I cannot guess...
Creating process , using this function is very important for me, so I'd be grateful for an answer... :)
Kitty Butler
The TS session in which the process is started will be based on the session id of the token passed to CreateProcessAsUser. If the token is for an interactive logged on user, it should already have the correct session id.
The windowstation/desktop can be specified in the STARTUPINFO structure. "Winsta0\Default" is the default user's desktop.
Gordonn
Dennis Mulder - dennismulder.net
When I use Remote Desktop to debug, the session id is 3, however WTSQueryUserToken() failed with the same error 1008.
Dmitry Pavlov
Did you use start windbg.exe in session 0 and make the service interactive
Dbgview has to run in the same session as the process being traced...
Windbg doesn't have this restriction by the way. You can debug/attach accross session boundary and use it as dbgview.
MSDN with regards to WTSQueryUserToken:
1008
Was a user logged on in session 3 at the time of the call
Raoul_BennetH
prasindo
There's a small mistake in this code:
WTSQueryUserToken(dwSessionId, &hToken);
DuplicateTokenEx(hTokenNew,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hTokenDup);
The output of the WTSQueryUserToken (i.e. hToken) should become the first parameter to DuplicateTokenEx but it's not in this case.
Note that the token duplication is not really necessary because WTSQueryUserToken yields a primary token already.
Sai A
Mark See
Mine was the same senerio, calling CreateProcessAsUser from service.
I followed the steps given by you, and it really worked for me thanks
HANDLE hTokenNew = NULL, hTokenDup = NULL;
HMODULE hmod = LoadLibrary("kernel32.dll");
WTSGETACTIVECONSOLESESSIONID lpfnWTSGetActiveConsoleSessionId = (WTSGETACTIVECONSOLESESSIONID)GetProcAddress(hmod,"WTSGetActiveConsoleSessionId");
DWORD dwSessionId = lpfnWTSGetActiveConsoleSessionId();
WTSQueryUserToken(dwSessionId, &hToken);
DuplicateTokenEx(hTokenNew,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hTokenDup);
//
WriteToLog("Calling lpfnCreateEnvironmentBlock");
ZeroMemory( &si, sizeof( STARTUPINFO ) );
si.cb = sizeof( STARTUPINFO );
si.lpDesktop = "winsta0\\default";
LPVOID pEnv = NULL;
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
HMODULE hModule = LoadLibrary("Userenv.dll");
if(hModule )
{
LPFN_CreateEnvironmentBlock lpfnCreateEnvironmentBlock = (LPFN_CreateEnvironmentBlock)GetProcAddress( hModule, "CreateEnvironmentBlock" );
if( lpfnCreateEnvironmentBlock != NULL )
{
if(lpfnCreateEnvironmentBlock(&pEnv, hTokenDup, FALSE))
{
WriteToLog("CreateEnvironmentBlock Ok");
dwCreationFlag |= CREATE_UNICODE_ENVIRONMENT;
}
else
{
pEnv = NULL;
}
}
}
//
ZeroMemory( &pi,sizeof(pi));
if ( !CreateProcessAsUser(
hTokenDup,
NULL,
( char * )pszCmd,
NULL,
NULL,
FALSE,
dwCreationFlag,
pEnv,
NULL,
&si,
&pi
) )
{
goto RESTORE;
}
Joo Park
The same code works for us on Vista as on XP, etc. The service is running as the Local System.
1. use WTSGetActiveConsoleSessionId to get the ID of the current active Windows session at the console (i.e. the machine keyboard and display, as opposed to WTS sessions).
2. use WTSQueryUserToken to get the token for that session.
3. use DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary, &hTokenDup) to duplicate that token.
4. use CreateEnvironmentBlock to create an environment that you will be passing to the process.
5. use CreateProcessAsUser with the duplicated token and the created environment. Actually, we use CreateProcessAsUserW, since the A version had some sort of bug on some older systems.
6. Don't forget to CloseHandle on the various tokens, etc, and to DestroyEnvironmentBlock the environment.
S_A_S
WTSQueryUserToken with 0 as the session id will always fail on Vista, because no user ever logs on in that session anymore.
WTSGetActiveConsoleSessionId() returning 0 may happen under some rare circumstances.
Is there anything special about the moment when you call that API
kiran1234
I am doing basically the same thing, but I get "CreateProcessAsUser failed with 123"
I have tried everything I cn think of with no luck
fya
Any way I am able to launch process (using CreateProcessAsUser) but it is getting launch in another desktop
i.e., is Session0, this is the place where my service is running. I am not able to launch in Session1 (users desktop).
I am trying to get some help from
http://weblogs.asp.net/kennykerr/archive/2006/09/29/Windows-Vista-for-Developers-_1320_-Part-4-_1320_-User-Account-Control.aspx
may this help you. If you could, let me know.
Thanks
Jeffrey Brown