windows 在 C++ 中获取用户的登录会话

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12718578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 15:53:31  来源:igfitidea点击:

Get the logon session of a user in C++

c++windowswinapisessionidpid

提问by phantomsays

I want to get a handle on the current logon session of processes whose parent is explorer.exe.

我想处理父进程为 explorer.exe 的当前登录会话。

If we run a process as administrator or a service it won't have a logon session. The reason I want to get the logon session is that I have a program (.exe) which I want to restrict opening when a user tries to open it via (right click on the .exe--> run as administrator) and when a user opens it via administrator we don't have a logon session associated with it whereas when a user opens it by double clicking on it, it has a logon session associated with it.

如果我们以管理员或服务的身份运行一个进程,它将没有登录会话。我想获得登录会话的原因是我有一个程序 (.exe),当用户尝试通过(右键单击 .exe--> 以管理员身份运行)打开它时,我想限制打开它,并且当用户通过管理员打开它,我们没有与之关联的登录会话,而当用户通过双击打开它时,它有一个与之关联的登录会话。

I searched quite some places, but I just get the process for getting the logon SID. If someone wants more information, you can download http://technet.microsoft.com/en-us/sysinternals/bb896653and under the explorer --> right click on any program executing --> security. Here you will find the logon session.

我搜索了很多地方,但我只得到了获取登录 SID 的过程。如果有人想了解更多信息,您可以下载http://technet.microsoft.com/en-us/sysinternals/bb896653并在资源管理器下 --> 右键单击​​正在执行的任何程序 --> 安全性。您将在此处找到登录会话。

回答by Jo?o Mendes

You can call GetCurrentProcessto get a handle to the current process, then use that to call OpenProcessTokento have an access token for the current process. Once you have that, you can call GetTokenInformationto request the TokenSessionId.

您可以调用GetCurrentProcess来获取当前进程的句柄,然后使用它来调用OpenProcessToken以获得当前进程的访问令牌。一旦你有了它,你就可以调用GetTokenInformation来请求TokenSessionId

Edit:

编辑:

I just thought of something else you can try: Instead of the session ID, you can request the TokenOwner, and once you have that, you have a security descriptor. You can then call LookupAccountSidto get the account name associated with the descriptor. Then, you can check that against "Administrator" or some such.

我只是想到了一些你可以尝试的东西:你可以请求TokenOwner而不是会话 ID,一旦你有了它,你就有了一个安全描述符。然后,您可以调用LookupAccountSid来获取与描述符关联的帐户名称。然后,您可以根据“管理员”或类似内容进行检查。

回答by Harry Johnston

You can get the logon session associated with a process by using OpenProcessTokenfollowed by GetTokenInformationwith the TokenStatisticsoption. However, this is not a sensible way of finding out whether or not a process was launched using "run as administrator" because there is no straightforward way to determine whether a particular logon session is elevated or not. It is not true that a process launched with "run as administrator" will not have a logon session.

您可以通过使用OpenProcessToken后跟GetTokenInformationTokenStatistics选项来获取与进程关联的登录会话。但是,这不是确定进程是否使用“以管理员身份运行”启动的明智方法,因为没有直接的方法来确定特定登录会话是否被提升。以“以管理员身份运行”启动的进程没有登录会话是不正确的。

To find out whether a process was "run as administrator" use the TokenElevationTypeoption. This should return TokenElevationTypeFullif and only if "run as administrator" was used.

要确定进程是否“以管理员身份运行”,请使用该TokenElevationType选项。TokenElevationTypeFull当且仅当使用“以管理员身份运行”时,它才应该返回。

(One caveat: I'm not certain what TokenElevationTypewill return if a non-administrative user uses "run as administrator" and then enters an administrator username and password. You should test this scenario. You might want to use TokenElevationrather than TokenElevationType.)

(一个警告:TokenElevationType如果非管理用户使用“以管理员身份运行”然后输入管理员用户名和密码,我不确定会返回什么。您应该测试这种情况。您可能想要使用TokenElevation而不是TokenElevationType。)

If what you really want to know is whether the process has administrative privilege, you should use CheckTokenMembershipinstead. Look for the Administrators group. The MSDN documentationhas sample code that does exactly this.

如果您真正想知道该进程是否具有管理权限,则应CheckTokenMembership改用。查找管理员组。在MSDN文档有示例代码正是这样做的。

The distinction here is what you want to happen if UAC is disabled (and the user is an administrator) or if the user is the local Administrator. In these cases there is no "run as administrator" option, all processes are run with administrator privilege automatically. If you want to detect these cases, use CheckTokenMembership. If you only want to detect the cases where the user explicitly said "run as administrator" use TokenElevationType.

如果 UAC 被禁用(并且用户是管理员)或者如果用户是本地管理员,这里的区别就是您希望发生的情况。在这些情况下,没有“以管理员身份运行”选项,所有进程都自动以管理员权限运行。如果要检测这些情况,请使用CheckTokenMembership. 如果您只想检测用户明确说“以管理员身份运行”的情况,请使用TokenElevationType.