【发布时间】:2020-11-05 10:55:32
【问题描述】:
我遇到了与WTSQueryUserToken always throws "An attempt was made to reference a token that does not exist" on Windows 7 in C# 中讨论的几乎相同的问题,但与该问题的 OP 不同,我在 Windows 10 上使用 C++ 并在开始编写我的解决方案之前正确阅读了文档。所以我的服务肯定是在LocalSystem 帐户下运行的。
这是我的SvcInit() 函数的相关部分:
HANDLE hToken;
// Returns 1, just like in the linked question
DWORD sessionId = WTSGetActiveConsoleSessionId();
if (!WTSQueryUserToken(sessionId, &hToken)) {
// LogError() takes the name of an error-causing function and calls
// GetLastError() and FormatMessage() to get the system-defined error
// message, then logs all of that to a file
LogError("WTSQueryUserToken");
return;
}
文档还提到您的服务进程需要拥有SE_TCB_NAME 权限。其他问题引用的同一段:
获取会话 ID 指定的登录用户的主要访问令牌。要成功调用此函数,调用应用程序必须在 LocalSystem 帐户的上下文中运行并具有 SE_TCB_NAME 权限。
但是通过阅读https://docs.microsoft.com/en-us/windows/win32/services/localsystem-account,在我看来,在LocalSystem 帐户下运行的任何进程都会自动拥有此特权:
LocalSystem 帐户具有以下权限:
- SE_ASSIGNPRIMARYTOKEN_NAME(已禁用)
- SE_AUDIT_NAME(已启用)
- SE_BACKUP_NAME(已禁用)
- ...许多其他人
- SE_TCB_NAME(已启用)
那么我是否需要明确地将此权限添加到我的进程中?还有什么可能是我的问题的原因?大都会! :-)
【问题讨论】:
-
ERROR_NO_TOKEN- 令牌查询是针对没有用户登录的会话。例如,当会话处于空闲状态或 SessionId 为零时,就会发生这种情况。 -
@RbMm 你从哪里得到的描述?根据docs.microsoft.com/en-us/windows/win32/debug/…,错误1008的描述是“试图引用一个不存在的令牌”,这也是我从
FormatMessage()得到的以及链接问题的状态。但是该描述并没有真正解释 为什么 令牌不存在,或者我应该错误地引用它。我将在问题中添加一个代码 sn-p,希望能提供更多见解。 -
i.imgur.com/UcUOPpv.png - 更好地展示你的相关代码
-
会话 1 中的 csrss.exe,winlogon.exe 已经启动。所以终端 1 会话已经存在。但还没有任何登录用户。并简单地提问-此时您需要什么用户令牌?如果系统中存在多个用户 - 您认为必须获得哪个具体的用户令牌?只有这个问题显示设计错误。你需要开始的关键问题 - 你需要一些用户令牌?
-
无论如何你都需要等到某个用户登录。在服务中,在 HandlerEx 例程中你会收到会话通知 -
SERVICE_CONTROL_SESSIONCHANGE- 看看WTS_SESSION_LOGON和@987654334 @你将拥有dwSessionId。
标签: windows windows-services c++17