首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WTSQueryUserToken抛出错误1008,即使在LocalSystem下运行也是如此。

WTSQueryUserToken抛出错误1008,即使在LocalSystem下运行也是如此。
EN

Stack Overflow用户
提问于 2020-11-05 10:55:32
回答 1查看 1.9K关注 0票数 0

我的问题与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()函数的相关部分:

代码语言:javascript
运行
复制
    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://learn.microsoft.com/en-us/windows/win32/services/localsystem-account,在我看来,运行在LocalSystem帐户下的任何进程都具有这样的特权:

LocalSystem帐户具有以下特权:

  • SE_ASSIGNPRIMARYTOKEN_NAME (disabled)
  • SE_AUDIT_NAME (enabled)
  • SE_BACKUP_NAME (disabled)
  • ...many others
  • SE_TCB_NAME (enabled)

那么,我是否需要显式地将此特权添加到我的进程中?还有什么原因会导致我的问题?MTIA!:-)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-05 17:01:54

在当前的WTSQueryUserToken中存在着不完整的短语:

和其他错误一样,GetLastError可以返回以下错误之一。

但是在旧的msdn中是list或错误,这些错误可以返回api:

因此,ERROR_NO_TOKEN均值可以在下列情况下返回

令牌查询用于没有用户登录的会话。例如,当会话处于空闲状态或SessionId为零时,就会发生这种情况。

如果我们尝试在系统启动时获得用户令牌,当然,还没有任何登录用户。用户是未知的,结果是不存在和用户令牌(比如包含用户sid的令牌--但是用户和未知,sid是未知的,令牌此时不能存在)。但是,如果需要的话,服务可以在某些(任何)用户登录到系统时启动进程。这需要从通过HandlerEx注册的RegisterServiceCtrlHandlerEx回调中执行。

我们需要寻找SERVICE_CONTROL_SESSIONCHANGE事件。用户会话中运行进程的简单代码可以如下所示

代码语言:javascript
运行
复制
DWORD WINAPI HandlerEx(
                       DWORD dwControl,
                       DWORD dwEventType,
                       PVOID lpEventData,
                       PVOID lpContext
                       )
{

    switch (dwControl)
    {
    case SERVICE_CONTROL_SESSIONCHANGE:

        if (dwEventType == WTS_SESSION_LOGON)
        {
            HANDLE hToken;
            if (WTSQueryUserToken(reinterpret_cast<PWTSSESSION_NOTIFICATION>(lpEventData)->dwSessionId, &hToken))
            {
                PVOID lpEnvironment;
                if (CreateEnvironmentBlock(&lpEnvironment, hToken, FALSE))
                {
                    STARTUPINFOW si = { sizeof(si) };
                    PROCESS_INFORMATION pi;
                    if (CreateProcessAsUserW(hToken, 
                        L"c:\\windows\\notepad.exe", 0, 0, 0, 0, 
                        CREATE_UNICODE_ENVIRONMENT, lpEnvironment, 0, &si, &pi))
                    {
                        CloseHandle(pi.hThread);
                        CloseHandle(pi.hProcess);
                    }
                    DestroyEnvironmentBlock(lpEnvironment);
                }
                CloseHandle(hToken);
            }
        }
        break;
    }

    // ...
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64695743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档