ImpersonateLoggedOnUser在windows服务中不工作

ImpersonateLoggedOnUser not working in windows service

本文关键字:工作 服务 windows ImpersonateLoggedOnUser      更新时间:2023-10-16

我正试图从一个windows服务(以SYSTEM运行(中调用一个windows api(它似乎只在登录用户的上下文中工作(。我可以为登录用户获取令牌。当我调用ImpersonateLoggedOnUser((时,我没有得到任何错误,它返回true。但是DoSomethingInUserContext((仍然在SYSTEM上下文中执行。我做错了什么?

DWORD sessionIdDw = WTSGetActiveConsoleSessionId();
 
HANDLE hToken;
if (!WTSQueryUserToken(sessionIdDw, &hToken))
  LOG() << "WTSQueryUserToken failed: " << GetLastError();
 
HANDLE hDuplicated = NULL;
if (!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenImpersonation, &hDuplicated)) {
  LOG() << "DuplicateTokenEx failed: " <<GetLastError();
}
 
if (!ImpersonateLoggedOnUser(hDuplicated)) {
  LOG() << "ImpersonateLoggedOnUser failed " << GetLastError();
}
else {
      DoSomethingInUserContext();
      if (!RevertToSelf()) {
           LOG() << "RevertToSelf failed" << GetLastError();
      }
}
               
CloseHandle(hDuplicated);
CloseHandle(hToken);

注释足够详细,可以指出原因,EnumWindows按会话枚举。

创建用户服务是一种可行的方法。以下方法也是有效的:

TCHAR Command[MAX_PATH] = L"C:\EnumWindows.exe";
DWORD sessionIdDw = WTSGetActiveConsoleSessionId();
logfile(sessionIdDw);
HANDLE hToken;
if (!WTSQueryUserToken(sessionIdDw, &hToken))
LOG() << "WTSQueryUserToken failed: " << GetLastError();
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if(!CreateProcessAsUser(hToken,NULL,Command,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
LOG() << "CreateProcessAsUser failed: " << GetLastError();
else
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}

新进程正在用户会话中运行。

编辑:

感谢@Eryk指出,窗口站:

每个会话都与自己的交互式窗口站相关联

SetThreadDesktop:

桌面必须与过程

SetProcessWindowStation:

窗口工作站必须与当前会话相关联。

所以SetThreadDesktop在这里不起作用。