#pragma once
#include <Windows.h>
#include <WtsApi32.h>
#pragma comment(lib, "Wtsapi32.lib")
bool getCurrentSessions(vector<DWORD>& vecSessionIds,
WTS_CONNECTSTATE_CLASS state = WTSActive) {
bool rc = false;
PWTS_SESSION_INFO pSessionInfo = 0;
DWORD dwCount = 0;
vecSessionIds.clear();
// Get the list of all terminal sessions (If the function fails, the return
// value is zero.)
if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo,
&dwCount))
return rc;
// look over obtained list in search of the active session
for (DWORD i = 0; i < dwCount; ++i) {
WTS_SESSION_INFO si = pSessionInfo[i];
if (state == si.State) {
// If the current session is active � store its ID
vecSessionIds.push_back(si.SessionId);
}
}
// Free session info
WTSFreeMemory((PVOID)pSessionInfo);
rc = true;
return rc;
}
bool impersonateCurrentUser() {
bool rc = false;
HANDLE hToken = NULL, hCurrentProcess = NULL, hProcessToken = NULL,
hCurrentToken = NULL;
vector<DWORD> vecSessionIds;
BOOL bRet = 0;
DWORD dwActiveUserSessionId;
// Get active session(s)
if (!getCurrentSessions(vecSessionIds)) {
goto end;
}
// Attempt to impersonate a user and start the application until it is
// successful.
for (size_t i = 0; i < vecSessionIds.size(); i++) {
dwActiveUserSessionId = vecSessionIds[i];
// Get current process
// GetCurrenProcess() returns a pseudo handle (currently -1) that is
// interpreted as the current process. For compatibility with future OS's,
// it's best to call GetCurrentProcess() rather than hard-coding the -1.
HANDLE hPseudoForCurrentProcess = GetCurrentProcess();
// Convert pseudo handle to a real process handle
if (DuplicateHandle(hPseudoForCurrentProcess, hPseudoForCurrentProcess,
hPseudoForCurrentProcess, &hCurrentProcess, 0, true,
DUPLICATE_SAME_ACCESS) == 0)
return rc;
// Get token for current process
bRet = OpenProcessToken(hCurrentProcess,
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hProcessToken);
if (!bRet) goto end;
// Build privileges we will need (TCB = trusted computer base. Act as part
// of the operating system).
TOKEN_PRIVILEGES tokenPrivs;
bRet = LookupPrivilegeValue(NULL, SE_TCB_NAME,
&tokenPrivs.Privileges[0].Luid);
if (!bRet) goto end;
tokenPrivs.PrivilegeCount = 1;
tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Adjust our privileges for our process
bRet = AdjustTokenPrivileges(hProcessToken, FALSE, &tokenPrivs, 0,
(PTOKEN_PRIVILEGES)NULL, 0);
if (!bRet) goto end;
// Get token of the logged in user by the active session ID
if (!WTSQueryUserToken(dwActiveUserSessionId, &hCurrentToken)) goto end;
// Obtain a token for current user finally
bRet = DuplicateTokenEx(hCurrentToken,
TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0,
SecurityImpersonation, TokenPrimary, &hToken);
if ((bRet == false) || (hToken == 0)) goto end;
// Impersonate the user using the user token
if (ImpersonateLoggedOnUser(hToken)) {
rc = true;
}
// Break out if impersonation was successful
if (rc) break;
} // for loop for session id's
end:
if (hProcessToken) CloseHandle(hProcessToken);
if (hCurrentProcess) CloseHandle(hCurrentProcess);
if (hCurrentToken) CloseHandle(hCurrentToken);
if (hToken) CloseHandle(hToken);
return rc;
}