c++ - ImpersonateLoggedOnUser 无法在 Windows 服务中工作

标签 c++ windows winapi impersonation

我正在尝试从 Windows 服务(以 SYSTEM 身份运行)调用 Windows API(似乎只能在登录用户的上下文中工作)。我能够获得登录用户的 token 。当我调用 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按 session 枚举。

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

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);
}

新进程正在用户 session 中运行。

编辑:

感谢@Eryk 指出,Window Stations :

Each session is associated with its own interactive window station

SetThreadDesktop :

The desktop must be associated with the current window station for the process.

SetProcessWindowStation :

The window station must be associated with the current session.

所以 SetThreadDesktop 在这里不起作用。

关于c++ - ImpersonateLoggedOnUser 无法在 Windows 服务中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58753029/

相关文章:

windows - 如何获得新式 Windows 拖放光标

c++如何实现这种类结构?

c++ - 防止 Hook dll加载

windows - 批处理文件: Processing files in alphbetical (Numerical maybe>) Order

c++ - 串行端口 : ReadFile and CloseHandle

c++ - 如何在 MFC 中创建一个线程,用于相对于正在播放的音频文件移动 slider 控件?

c++ - 从文件加载后,顶点着色器和片段着色器均未编译

c++ - C++ 中的多态性本质上不是只有一个 "kind"吗?

windows - 为什么 fsutil.exe 将大文件写入磁盘所花费的时间比以编程方式花费的时间少?

c++ - CComModule 取消注册服务器错误?