The purpose is to create a new process in session 0 from a process in non 0 console session. I know some methods that fulfill the purpose, but I want to know why the method described below does not, despite msdn says it should work.
unsigned FindProcessInSession(unsigned SessionId,const wchar_t*ProcessName)
{
PWTS_PROCESS_INFOW pinfo;DWORD Count,Result=0;
if(WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE,0,1,&pinfo,&Count)){
for(unsigned i=0;i<Count;++i)if(pinfo[i].SessionId==SessionId&&_wcsicmp(pinfo[i].pProcessName,ProcessName)==0){
Result=pinfo[i].ProcessId;break;
}
WTSFreeMemory(pinfo);
}
return Result;
}
int main()
{
HANDLE hProcess=OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,0,FindProcessInSession(0,L"smss.exe")),ProcessToken,NewToken;
if(hProcess&&OpenProcessToken(hProcess,TOKEN_DUPLICATE,&ProcessToken)&&DuplicateTokenEx(ProcessToken,MAXIMUM_ALLOWED,0,SecurityImpersonation,TokenImpersonation,&NewToken)){
static STARTUPINFOW si={sizeof(STARTUPINFOW)};PROCESS_INFORMATION pi;DWORD SessionId,l;
printf("GetTokenInformation %d\n",GetTokenInformation(NewToken,TokenSessionId,&SessionId,sizeof SessionId,&l));
printf("SessionId %d\n",SessionId);
printf("CreateProcessWithTokenW %d\n",CreateProcessWithTokenW(NewToken,0,L"c:\\windows\\system32\\cmd.exe",0,0,0,0,&si,&pi));
}
}
During testing on my pc,GetTokenInformation successfully output SessionId=0 and CreateProcessWithTokenW created a new process in SYSTEM username, with all privileges from smss.exe. but the new process still ran in whatever session the calling process was in. msdn on CreateProcessWithTokenW notes
Terminal Services: The process is run in the session specified in the token. By default, this is the same session that called LogonUser. To change the session, use the SetTokenInformation function.
Apparantly the secondary logon service CreateProcessWithTokenW relies on not does not follow the documentation