ImpersonateLoggedOnUser在Windows服务中不起作用

我正在尝试从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);
RERR555 回答:ImpersonateLoggedOnUser在Windows服务中不起作用

评论足够详细,可以指出原因,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,FALSE,&si,&pi))
    LOG() << "CreateProcessAsUser failed: " << GetLastError();
else
{
    WaitForSingleObject(pi.hProcess,INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}

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

编辑:

感谢@Eryk指出Window Stations

  

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

SetThreadDesktop

  

桌面必须与当前窗口工作站关联,   过程。

SetProcessWindowStation

  

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

所以SetThreadDesktop在这里不起作用。

本文链接:https://www.f2er.com/3143147.html

大家都在问