First off, why are you using SHGetKnownFolderPath()
to determine a username? That is not what that API is meant for. There are other APIs better suited for getting usernames.
Passing a NULL
token handle to SHGetKnownFolderPath()
(or any other API that takes a user token as input) will use the user account that is associated with the calling thread, which in this case is an admin user. For what you are asking, you need to pass in an actual token for the logged-in user instead. Or else impersonate the logged-in user before calling such an API with a NULL
user token.
WTQueryUserToken()
can certainly be used to get a user token, however it can only be used inside a service that is running under the SYSTEM
account. If your app is not running as such a service, you would have to create such a service for your app to communicate with.
Otherwise, you will just have to get the username from some another API.
For instance, you can use ProcessIdToSessionId()
to get the ID of the session that your app is running in (see Getting the Session ID of the Current Process), and then you can use WTSQuerySessionInformation(WTSUserName)
to get the logged-in username of that session.
Or, you can enumerate all running processes, looking for processes that are running in the same session ID as your app, until you find the explorer.exe
process, and then you can use OpenProcess()
and OpenProcessHandle()
to get the user's access token for that process, and then use GetTokenInformation()
(TokenUser
or TokenOwner
) to get the SID of that token, and then finally use LookupAccountSid()
to get the username of that SID.