One of the frequently asked questions in here is how to get the name of the interactive user. I see two workable solutions; both of them work only locally.

The nice way is to write a GINA stub to keep track of logons and logoffs; the other method relies on the fact that Winlogon (well, Winlogon and GINA and userinit.exe) starts at least one process for an interactive user, and that this process will have, in its token's group list, all of those:

This sample goes through the process list (after getting the PIDs from PSAPI.DLL), opens each process, and then takes a close look at the token. If all three of the SIDs above are present, it calls a process interactive. You will probably want to record, at that point, the TokenUser (the user, for whom this process was created) and the token source. The token source is usually "user32", padded with blanks to eight characters, for interactive processes; this should help in telling the difference between a process created by the Winlogon and one created by an imitating call to CreateProcessAsUser().

9 Sep 1999: Chris Scheers <> reported a bug (and provided the fix) -- at the point where a large-enough buffer was finally allocated, nPIDs contained the number of PIDs I reserved memory for, and I failed to adjust it downwards to the actual number of PIDs that were returned in the buffer. Thanks, Chris!

opt_gti.cpp, 12 KB