1

I am wondering if there is any way to get non-admin user name when running app as admin.

I tried to get it using SHGetKnownFolderPath with null for token and it returns admin username not non-admin user which was currently logged in.

So wondering if I need to use WTSQueryUserToken in order to get non-admin username.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Rocky Choi
  • 13
  • 2

1 Answers1

1

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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for the info Remy ! Basically I would like to get path like `C:\Users\(userName)\AppData\Local` using `SHGetKnownFolderPath()`. Since `WTQueryUserToken()` requires system account, maybe I could use `WTSQuerySessionInformation(WTSUserName)` and replace username in path from `SHGetKnownFolderPath()` with null user token ? – Rocky Choi Dec 06 '19 at 22:00
  • @RockyChoi "*I would like to get path like `C:\Users\(userName)\AppData\Local` using `SHGetKnownFolderPath()`*" - that is not really what your question asked for, though. You asked for just the username, not a path containing the username. In that case, you need a real user token. "*maybe I could use `WTSQuerySessionInformation(WTSUserName)` and replace username in path from `SHGetKnownFolderPath()` with null user token ?*" - that is not a good way to go. There is no guarantee that the two users will have the same folder structure. You need to query the actual path assigned to the target user – Remy Lebeau Dec 07 '19 at 03:58