我尝试将代码herehere混合使用,以从通过QtService初始化的服务中运行GUI exe,但是每当下面运行代码时,我都会从CreateProcessAsUser中收到错误5。

另外,我看到了类似问题here on StackOverflow的答案,但无法弄清楚DACL与该问题如何相关,并且无法使用Harry Johnson的答案,因为我没有用户的登录信息。

因此,有人可以帮助我理解为什么我从下面的代码中收到错误5(拒绝访问)吗?

if(initUiWin())
    log->write("InitUiWin executed.");
else {
    QString errorNumber = QString::number(GetLastError());
    log->write("InitUiWin error: " + errorNumber);
}


--

bool initUiWin()
{
    // obtain the currently active session id; every logged on
    // User in the system has a unique session id
    uint dwSessionId = WTSGetActiveConsoleSessionId();

    // obtain the process id of the winlogon process that
    // is running within the currently active session
    QString processName("winlogon.exe");
    DWORD winlogonPID = FindProcessId(processName.toStdWString(),dwSessionId);
    if( winlogonPID != 0 ) {
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, winlogonPID);
    HANDLE hToken;
    OpenProcessToken(hProcess,TOKEN_READ,&hToken);

    // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
    SECURITY_ATTRIBUTES sa;
    sa.nLength = static_cast<DWORD>(sizeof(SECURITY_ATTRIBUTES));

    // copy the access token of the winlogon process;
    // the newly created token will be a primary token
    HANDLE hUserTokenDup;
    if (!DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,&sa,
                            SecurityIdentification,TokenPrimary,&hUserTokenDup)) {
        CloseHandle(hProcess);
        CloseHandle(hToken);
        return false;
    }

    // Get Handle to the interactive window station
    HWINSTA hwinsta = NULL;
    hwinsta = OpenWindowStation(
           _T(L"winsta0"),                   // the interactive window station
           FALSE,                       // handle is not inheritable
           READ_CONTROL | WRITE_DAC);   // rights to read/write the DACL
    if(hwinsta == NULL)
        return false;

    // To get the correct default desktop, set the caller's
    // window station to the interactive window station.
    if (!SetProcessWindowStation(hwinsta))
        return false;

    // Get a handle to the interactive desktop.
    HDESK hdesk = NULL;
    hdesk = OpenDesktop(
          _T(L"default"),     // the interactive window station
          0,             // no interaction with other desktop processes
          FALSE,         // handle is not inheritable
          READ_CONTROL | // request the rights to read and write the DACL
          WRITE_DAC |
          DESKTOP_WRITEOBJECTS |
          DESKTOP_READOBJECTS);
    if(hdesk == NULL)
        return false;

    // Get the SID for the client's logon session.
    PSID pSid = NULL;
    if (!GetLogonSID(hUserTokenDup, &pSid))
          return false;

    // Allow logon SID full access to interactive window station.
    if (!AddAceToWindowStation(hwinsta, pSid) )
          return false;

    // Allow logon SID full access to interactive desktop.
    if (!AddAceToDesktop(hdesk, pSid) )
          return false;

    // Impersonate client to ensure access to executable file.
    if (!ImpersonateLoggedOnUser(hUserTokenDup) )
          return false;

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = static_cast<DWORD>(sizeof(STARTUPINFO));

    // interactive window station parameter; basically this indicates
    // that the process created can display a GUI on the desktop
    wchar_t auxBuffer[16] = L"winsta0\\default";
    si.lpDesktop = auxBuffer;

    // flags that specify the priority and creation method of the process
    int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB;

    // create a new process in the current User's logon session
    bool result = CreateProcessAsUser(hUserTokenDup,  // client's access token
                                    L"test-ui-systray.exe",             // file to execute
                                    NULL,  // command line
                                    &sa,           // pointer to process SECURITY_ATTRIBUTES
                                    &sa,           // pointer to thread SECURITY_ATTRIBUTES
                                    false,            // handles are not inheritable
                                    dwCreationFlags,  // creation flags
                                    NULL,      // pointer to new environment block
                                    NULL,             // name of current directory
                                    &si,           // pointer to STARTUPINFO structure
                                    &pi      // receives information about new process
                                    );

    if (pSid)
          FreeLogonSID(&pSid);
    if (hdesk)
          CloseDesktop(hdesk);
    if (hwinsta)
          CloseWindowStation(hwinsta);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    return result;
}

return false;

}

最佳答案

将其放在此处以提高知名度。哈里·约翰斯顿在评论中回答。问题是OpenProcessToken中的标志,我刚刚更改了

OpenProcessToken(hProcess,TOKEN_READ,&hToken)




OpenProcessToken(hProcess,TOKEN_READ|TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY,&hToken)

关于c++ - CreateProcessAsUser生成错误5,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32638655/

10-14 23:57