I have used GetUserName() METHOD , but the username it returned is 'SYSTEM' in a SYSTEM process.How can I get the active username in a SYSTEM process? THIS IS MY CODE:
void getComputerUsername(char * username,char * domainname)
{
HANDLE hp , htoken;
char buff[1024];
unsigned long size = 1024;
TOKEN_USER *tuser;
PSID sid;
TCHAR * user = new TCHAR[256];
TCHAR * domain=new TCHAR[256];
SID_NAME_USE snu;
hp = htoken = INVALID_HANDLE_VALUE;
hp = GetCurrentProcess();
if(OpenProcessToken(hp, TOKEN_QUERY, &htoken))
{
if(GetTokenInformation(htoken, TokenUser, (void*)buff, size, &size))
{
tuser = (TOKEN_USER*)buff;
sid = tuser->User.Sid;
size = 256;
if(LookupAccountSid(NULL, sid, user, &size, domain, &size, &snu))
{
int iLength = WideCharToMultiByte(CP_ACP, 0, user, -1, NULL, 0, NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, user, -1, username, iLength, NULL, NULL);
iLength = WideCharToMultiByte(CP_ACP, 0, domain, -1, NULL, 0, NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, domain, -1, domainname, iLength, NULL, NULL);
//strcpy( user,username);
}
}
}
}
Enumerate the desktops and find the "Default" desktop. Get the user SID from that desktop. Maybe you have to try to find the correct access rights; I tried the code from an interactive process only.
You need to enumerate through all the running processes using EnumProcesses
Then see this answer to get the username from the process:
https://stackoverflow.com/a/2686150/203244
Enumerating all processes is a way to do it but it has certain issues:
1) You can't enumerate both x86 and x64 processes in the same service process using documented Windows APIs. An x86 service can only enumerate x86 processes and an x64 service can only enumerate x64 processes. A way to circumvent that is to have an x86 service launch an x64 helper process (and vice versa) to do the rest of the enumeration task.
2) The only process that is always present for a logged on user across different Windows versions (e.g. Vista to Windows 10) is explorer.exe however that process is x64 on x64 OS platforms and x32 on x32 OS platforms and its presence does not mean that the user is actively logged in.
A better way is to enumerate sessions, find the active interactive session or sessions that is also connected and then get the user name of that session.
The code below does much more than that, including impersonation of that user and running a process as that user all from a windows service, but if you are just interested in the user name please look for the second instance the WTSQuerySessionInformation() function is called.
If you want to know who is logged onto the physical console, you can call
WTSGetActiveConsoleSessionId
to get the terminal services (aka "fast user switching" aka "remote desktop") session ID that is currently active.You can then call
WTSQuerySessionInformation
withWTSUserName
to get the username.(If the user you're interested in might be logged on via Remote Desktop, this approach will not work.)