首页 > 解决方案 > Win7 C++ - 从以用户身份登录的服务中以用户身份启动可执行文件

问题描述

我正在解决一个 Windows 服务的问题,到目前为止,它在模拟当前用户并在该用户的会话中启动可执行文件时没有问题。

我最初的问题是我无法访问有关已安装驱动器或其上文件的信息。所以我发现我需要定义服务以用户身份登录。

一旦我这样做了,我就不再有访问这些文件的问题,但是启动可执行文件的模拟不再起作用。或者更具体地说,我的调用WTSQueryUserToken()不再有效,而是返回 false,并GetLastError()返回 ERROR_PRIVILEGE_NOT_HELD。

我还不知道我是否会遇到DuplicateTokenEx()or的任何问题CreateProcessAsUserA(),但一次一件事。

我的代码如下(在此之前检索到dwSessId并且是正确的):

if (dwSessId >= 0)
{
    HANDLE hCurrentToken;
    HANDLE hPrimaryToken;
    BOOL ok = WTSQueryUserToken(dwSessId, &hCurrentToken);
    if (ok)
    {
        ok = DuplicateTokenEx(hCurrentToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &hPrimaryToken);
        // now we start the executable process as the current user
        STARTUPINFOA si;
        ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_SHOWNORMAL;
        ret = (CreateProcessAsUserA(hPrimaryToken, procname.c_str(), NULL, 0, 0, false, CREATE_NO_WINDOW, 0, 0, &si, &m_pProcInfo) != 0);
    }
}
else
{
    int err = GetLastError();
    return false;
}

标签: c++serviceimpersonation

解决方案


根据WTSQueryUserToken()文档:

要成功调用此函数,调用应用程序必须在LocalSystem帐户的上下文中运行并具有SE_TCB_NAME权限。

换句话说,您不能将服务配置为以任何特定用户身份运行。但是,它当然可以在需要时模拟用户,只要调用的线程在调用WTSQueryUserToken()时没有模拟用户。


推荐阅读