views:

738

answers:

5

Hello

I wish to enumerate all desktops in a system and get the logged in user name for that desktop. So far I have the following code snippit as an example of obtaining a HDESK handle and trying to determine the user name associated with it (if any), but the call to LookupAccountSid fails with ERROR_NONE_MAPPED ("No mapping between account names and security IDs was done").

HDESK desk = OpenDesktop( "Default", 0, FALSE, READ_CONTROL | DESKTOP_READOBJECTS );

DWORD size = 4096;

SID * sid  = (SID *)malloc( size );

GetUserObjectInformation( desk , UOI_USER_SID, sid, size, &size );

char name[512], domain[512];
int namesz = 512, domainsz = 512;

LookupAccountSid( NULL, sid, &name, &namesz, &domain, &domainsz, &s);

It might be because I am pulling out a logon SID via GetUserObjectInformation rather then a user SID. If so can I convert that to the logged in users SID?

Can anybody point me in the right direction for getting the logged in user name for an arbitrary desktop (via either it's respective HDESK or HNWD handle or even the desktop's stations HWINSTA handle)? thanks in advance.

+1  A: 

If what you want is the user information then this will work.

call WTSEnumerateSessions to obtain an array of WTS_SESSION_INFO structures. for each structure, pass the SessionId member to WTSQuerySessionInformation with the WTSInfoClass member set to WTSUserName. This will give you the name of the user (if there is one) associated with the session.

Alternatively you can set the WTSInfoClass to WTSSessionInfo and get a WTSINFO structure back. This contains a lot of information including the user name and domain. Look at the header file definition of WTSINFO though as the MSDN page is wrong.

You have to call WTSEnumerateSessions twice, once to get the required buffer size and then once to get your information.

Relationships: One or more Desktop objects are in a Windows Station. A Windows Station is associated with a Session.

janglin
Thanks, good suggestion but after trying it. while I can list the sessions and their associated usernames(if any) the session's station name is always the RDP session name not the windows station name (see WTSWinStationName definition in http://msdn.microsoft.com/en-us/library/aa383861%28VS.85%29.aspx). If I could link a session ID to a windows station though this technique would be perfect, but I cant find how to do so.
QAZ
@QAZ that doesn't work every session has a winsta0 window station which is the window station that has all the visible widnows (the only other window station of interest is the secure deaktop for that session).
Joshua
+1  A: 

The problem is that desktops aren't associated with users at all. Try using psexec to run Notepad under the SYSTEM account. It's running on your window station, on your desktop. Otherwise, you wouldn't be able to see it.

But if you want to get the session associated with the window station, then yes it's possible. You need to call NtQueryObject with ObjectNameInformation to get the name of the object. For example, here's what I get: \Sessions\1\Windows\WindowStations\WinSta0. There's your session ID.

wj32
thanks, good point. I do want to be able to get the logged on user to the desktop if one exists so this might be useful in combination with janglin's answer. I will test tomorrow and report back.
QAZ
A: 

This is not a solution but is a good description of station/desktop. From http://www.microsoft.com/technet/security/bulletin/fq00-020.mspx

What's a windows station? A windows station is a secure container that contains a clipboard, some global information, and a set of one or more desktops. A Windows 2000 session will have several windows stations, one assigned to the logon session of the interactive user, and others assigned to the Winlogon process, the secure screen saver process, and any service that runs in a security context other than that of the interactive user. The interactive window station assigned to the logon session of the interactive user also contains the keyboard, mouse, and display device. The interactive window station is visible to the user and can receive input from the user. All other window stations are noninteractive, which means that they cannot be made visible to the user, and cannot receive user input.

What's a desktop? A desktop is a secure container object that is contained within a window station. There may be many desktops contained within a windows station. A desktop has a logical display surface and contains windows, menus, and hooks. Only the desktops of the interactive window station can be visible and receive user input. On the interactive window station, only one desktop at a time is active. This active desktop, also known as the input desktop, is the one that is currently visible to the user and that receives user input.

fupsduck
I'm sure the OP knows what they are already...
wj32
Meant to help clarify what contains what and relationship to one another
fupsduck
A: 

You could extract it from the end of the %USERPROFILE% environment variable

BlueRaja - Danny Pflughoeft
A: 

nbtstat used to be able to do this from the command line, with either a machine name or IP address. It's been a long time since I looked at it, though.

TREE