我的问题与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://learn.microsoft.com/en-us/windows/win32/services/localsystem-account,在我看来,运行在LocalSystem
帐户下的任何进程都具有这样的特权:
LocalSystem帐户具有以下特权:
那么,我是否需要显式地将此特权添加到我的进程中?还有什么原因会导致我的问题?MTIA!:-)
发布于 2020-11-05 17:01:54
在当前的WTSQueryUserToken
中存在着不完整的短语:
和其他错误一样,GetLastError可以返回以下错误之一。
但是在旧的msdn中是list或错误,这些错误可以返回api:
因此,ERROR_NO_TOKEN
均值可以在下列情况下返回
令牌查询用于没有用户登录的会话。例如,当会话处于空闲状态或SessionId为零时,就会发生这种情况。
如果我们尝试在系统启动时获得用户令牌,当然,还没有任何登录用户。用户是未知的,结果是不存在和用户令牌(比如包含用户sid的令牌--但是用户和未知,sid是未知的,令牌此时不能存在)。但是,如果需要的话,服务可以在某些(任何)用户登录到系统时启动进程。这需要从通过HandlerEx
注册的RegisterServiceCtrlHandlerEx
回调中执行。
我们需要寻找SERVICE_CONTROL_SESSIONCHANGE
事件。用户会话中运行进程的简单代码可以如下所示
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;
}
// ...
}
https://stackoverflow.com/questions/64695743
复制相似问题