WTSQueryUserToken failing
Hello Everyone,
I have written a service that runs under the system account. At some event i have to launch an executable under the current logged in user context from the service. I am using:
WTSGetActiveConsoleSessionId to get the session id for the current logged in user and then
calling WTSQueryUserToken to get the token of the user and then
using CreateProcessAsUser to launch the exe under the user context.
but i a facing some strange behaviors i.e. WTSQueryUserToken is failing on some machine while successful in returning the token on other machines. I have Windows XP with SP2 on all the machines.
GetLastError gives me the following error description:
"The operation being requested was not performed because the user has not logged on to the network.
The specified service does not exists."
Can anyone please guide me where is the problem exists, as WTSQueryToken is successful on some machines and fails on other machines. Is there any sort of configurations problem or anything else. Please guide me to cater this issue.
Thanking in advance.
Regards,
Ghazanfar.
Re: WTSQueryUserToken failing
Error 1245 happens when active console session id is 0, and no user is logged in.
To analyse your situation a bit more detailed (verbose :)) test case description required.
Re: WTSQueryUserToken failing
Thanks for your reply,
The user has logged in the system, when the service launches another application.
The details are as, i have my application(Service) running under system context, the user request a application(Service) to perform some task, the application(Service) in response launches the application(Desktop) running under current logged in user context. The problem I am facing is that when my service calls WTSQueryUserToken it fails with the error "The operation being requested was not performed because the user has not logged on to the network. The specified service does not exists."
Please guide me where i am going wrong as this issue is not consistent i.e. on some machines it is working fine while on some machines it fails.
Following is the code that i am using to launch the application
///Code Start Here
DWORD dwSessionId = 0;
HANDLE hUserToken = NULL, hTokenDup = NULL;
PWTS_SESSION_INFO pSessionInfo;
DWORD dwCount;
// Enumerate all of the current sessions
WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
PWTS_SESSION_INFO pSession = pSessionInfo;
TCHAR s[10];
// Find the new session that has just started
for(int i = 0; i < dwCount; i++)
{
_ultot(pSession->SessionId, s, 10);
// Is this the new session?
if(WTSActive == pSession->State)
{
dwSessionId = pSession->SessionId;
break;
}
pSession++;
}
// Find the primary token of the user that has just logged on
BOOL bRet = WTSQueryUserToken(dwSessionId, &hUserToken);
if(!bRet)
{
CString szErrorMessage = _T("Error occurred while querying the user token. Reason: ") + GetErrorDescription(GetLastError());
MessageBox(szErrorMessage, _T("Token Tester"), MB_ICONERROR);
}
bRet = DuplicateTokenEx(hUserToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
if(!bRet)
{
CString szErrorMessage = _T("Error occurred while duplicating the user token. Reason: ") + GetErrorDescription(GetLastError());
MessageBox(szErrorMessage, _T("Token Tester"), MB_ICONERROR);
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof( STARTUPINFO ) );
si.cb = sizeof( STARTUPINFO );
si.lpDesktop = _T("WinSta0\\Default");
LPVOID pEnv = NULL;
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
bRet = CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
if(bRet)
dwCreationFlag |= CREATE_UNICODE_ENVIRONMENT;
else
pEnv = NULL;
ZeroMemory( &pi,sizeof(pi));
if ( !CreateProcessAsUser(hTokenDup, _T("D:\\Windows\\System32\\notepad.exe"), NULL, NULL, NULL, FALSE, dwCreationFlag, pEnv,
NULL, &si, &pi) )
{
CloseHandle(hTokenDup);
CString szErrorMessage = _T("Error occurred while launching the process as user. Reason: ") + GetErrorDescription(GetLastError());
MessageBox(szErrorMessage, _T("Token Tester"), MB_ICONERROR);
}
CloseHandle(hTokenDup);
if(pi.hProcess)
CloseHandle(pi.hProcess);
if(pi.hThread)
CloseHandle(pi.hThread);
/// Code Ends Here
Please guide me, as i am running behind the project deadline. Thanking in advance.
Regards,
Ghazanfar.
Re: WTSQueryUserToken failing
[ remove duplicate thread ]
Please do not make multiple threads about the same issue.
Re: WTSQueryUserToken failing
Quote:
///Code Start Here
DWORD dwSessionId = 0;
HANDLE hUserToken = NULL, hTokenDup = NULL;
PWTS_SESSION_INFO pSessionInfo;
DWORD dwCount;
// Enumerate all of the current sessions
WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);
// Find the new session that has just started
for(int i = 0; i < dwCount; i++)
{
// Is this the new session?
if(WTSActive == pSession->State)
{
dwSessionId = pSession->SessionId;
break;
}
pSession++;
}
// Here, once we have not found any active session, dwSessionId is still 0 !!!
// This means, we're trying to obtain the token for inactive session :D
// Find the primary token of the user that has just logged on
BOOL bRet = WTSQueryUserToken(dwSessionId, &hUserToken);
Your code has the flaw I've descibed.
I tested your code in available systems (xp/2k3) - and found no problem.