locked
WTSQueryUserToken() fails with error 1008 if team viewer [and perhaps remote desktop] is running at system boot RRS feed

  • Question

  • I have a windows service which is set to start automatically at system boot. As part of its startup routine, I need to create a process with the token of the interactive user. So I get the session id, either by enumerating all sessions and checking which one is active, or using the WTSGetActiveConsoleSessionId api. However, if team viewer [version 14] is running , I get the same session id using both methods, and both session ids fail when using WTSQueryUserToken with error 1008.

    This happens ONLY at time of booting the system. Any other time, it works ok even if Team viewer is running. That is, there are no problems if I start the service manually after the system has booted. 

    Please let me know how I can bypass this issue. Thanks.https://social.msdn.microsoft.com/Forums/ie/en-US/3fc2175b-ee6f-43e2-8fd8-c039680ca069/wtsqueryusertoken-failed-on-a-remote-desktop-session?forum=windowssecurity 

    suggests the following 

    "Again, WTSGetActiveConsoleSessionId returns the session id of the session bound to the physical machine.

    If you're connecting using remote desktop, the session you're getting is remote (i.e. not bound to the physical machine).

    And since there can be more than one remotely connected user in some configurations, there's no API that returns *the* remotely connected session id.

    Assuming you're on a client SKU of Windows (where only one session can be active at a time), you can enumerate all sessions (using WTSEnumerateSessions) and look for the active one in the returned array. "

    However, I found that both methods [enumerate sessions and WTSQueryUserToken return the same session id , which fails with error 1008]

    The code I use is as below

    HANDLE CProcessManager::GetImpersonationToken() {
    	
    	//The following api call fails to get a valid session id if remote desktop /team viewer is running at startup
    	UINT dwSessionId = WTSGetActiveConsoleSessionId();
    	Report(L"Session id from WTSGetActiveConsoleSessionId:%d", dwSessionId);
    
    	
    	HANDLE hImpersonationToken = NULL;
    	if (!WTSQueryUserToken(dwSessionId, &hImpersonationToken))
    		{
    			//log error
    			DWORD err = GetLastError();
    			Report(L"Exception in WTSQueryUserToken:%d Proceeding to enumerate sessions!", err);
    		}
    		else 
    		{
    			Report(L"Returning Impersonation Token:%d", hImpersonationToken);
    			WCHAR* pUserName;
    			DWORD user_name_len = 0;
    
    			if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE,dwSessionId, WTSUserName, &pUserName, &user_name_len))
    			{
    				Report(L"UserName from sessionId is %s:", pUserName);
    				if (pUserName) WTSFreeMemory(pUserName);
    				return hImpersonationToken;
    				//LocalFree(lpszUserName);
    			}
    			else
    			{
    				DWORD err = GetLastError();
    				Report(L"Exception in WTSQuerySessionInformation:%d! Returning Null Impersonation Token", err);
    				return NULL;
    			}
    
    			
    		}
    	DWORD session_id = -1;
    	DWORD session_count = 0;
    
    	WTS_SESSION_INFOA *pSession = NULL;
    
    	try {
    		if (WTSEnumerateSessionsA(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSession, &session_count))
    		{
    			//log success
    		}
    		else
    		{
    			//log error
    			return NULL;
    		}
    	}
    	catch (...) {}
    	Report(L"Session Count :%d", session_count);
    	Report(L"Begin Enumerating Sesions");
    	for (int i = 0; i < session_count; i++)
    	{
    		{
    			session_id = pSession[i].SessionId;
    			Report(L"SessionId:%d", session_id);
    
    			WTS_CONNECTSTATE_CLASS wts_connect_state = WTSDisconnected;
    			WTS_CONNECTSTATE_CLASS* ptr_wts_connect_state = NULL;
    
    			DWORD bytes_returned = 0;
    			if (::WTSQuerySessionInformation(
    				WTS_CURRENT_SERVER_HANDLE,
    				session_id,
    				WTSConnectState,
    				reinterpret_cast<LPTSTR*>(&ptr_wts_connect_state),
    				&bytes_returned))
    			{
    				wts_connect_state = *ptr_wts_connect_state;
    				::WTSFreeMemory(ptr_wts_connect_state);
    				if (wts_connect_state != WTSActive)
    				{
    					Report(L"wts_connect_state != WTSActive! Continuing ###");
    					continue;
    				}
    			}
    			else
    			{
    				Report(L"Error in WTSQuerySessionInformation:%d: Continuing ###", GetLastError());
    				continue;
    			}
    		}
    		//catch (...) {}
    		Report(L"End Enumerating Sesions");
    		Report(L"Selected Session Id:%d", session_id);
    	}
    	
    	Report(L"session_id from enumerating sessions: %d", session_id);
    	Report(L"Session id from WTSGetActiveConsoleSessionId:%d", dwSessionId);
    	if (session_id == -1) {
    		Report(L"Fatal Error: Failed to get session_id by both methods");
    		return NULL;
    	}
    	if (!WTSQueryUserToken(session_id, &hImpersonationToken))
    	{
    		//log error
    		DWORD err = GetLastError();
    		Report(L"Fatal Error: Failed WTSQueryUserToken on enumerated sessionid: %d", err);
    		return NULL;
    	}
    
    
    	// Get user name of this process
    	//LPTSTR pUserName = NULL;
    	WCHAR* pUserName;
    	DWORD user_name_len = 0;
    
    	if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, session_id, WTSUserName, &pUserName, &user_name_len))
    	{
    		//log username contained in pUserName WCHAR string
    		// char * lpszUserName = WideCharToChar(pUserName);
    		Report(L"UserName from session_id [after enumeration] is %s:",pUserName);
    		//LocalFree(lpszUserName);
    	}
    	else
    	{
    		DWORD err = GetLastError();
    		Report(L"Exception in WTSQuerySessionInformation:%d! Returning Null Impersonation Token", err);
    		return NULL;
    	}
    
    	//Free memory
    	if (pUserName) WTSFreeMemory(pUserName);
    
    	Report(L"Returning Impersonation Token:%d", hImpersonationToken);
    
    	return hImpersonationToken;
    }


    • Edited by Sagar R. Kapadia Wednesday, February 27, 2019 7:05 AM Additional Information: This happens ONLY at time of booting the system.
    Wednesday, February 27, 2019 6:48 AM

Answers

  • Setting the windows service to delayed start automatic resolved the issue. Thanks.
    Wednesday, February 27, 2019 7:13 AM