如何在VC ++ 2005中使用OpenProcessToken,AdjustTokenPrivileges和GetExitCodeProcess

时间:2012-01-17 16:26:09

标签: c++ windows visual-c++ privileges cross-process

我读了几篇关于如何检查一个进程是否退出其他进程的帖子(我发现有些人在这里挂了语义,但只是幽默我)而且我试图实现它但是我遇到了错误代码5(“ERROR_ACCESS_DENIED”)到处都是。

这就是我的工作。

1)进程1(P1)启动进程2并将共享内存位置写入自己的PID。

2)进程2(P2)从共享内存中读取PID

3)P2使用P1的PID调用OpenProcess(...)以保存稍后可以检查的句柄。

4)P2重复调用带有P1的PID的GetExitCodeProcess(...)并检查STILL_ACTIVE代码。

在上面的方法中,我一直在GetExitCodeProcess上得到ACCESS_DENIED错误。我尝试使用MSDN文档中的以下代码修改P2的权限:

HANDLE proc_h = OpenProcess(SYNCHRONIZE, FALSE, GetCurrentProcessId());
HANDLE hToken;
OpenProcessToken(proc_h, TOKEN_ADJUST_PRIVILEGES, &hToken);

LookupPrivilegeValue(NULL, lpszPrivilege, &luid );

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Enable the privilege
AdjustTokenPrivileges(hToken, 
                      FALSE, 
                      &tp, 
                      sizeof(TOKEN_PRIVILEGES), 
                      (PTOKEN_PRIVILEGES) NULL, 
                      (PDWORD) NULL);

但是我一直在调用OpenProcessToken(...)方法时遇到ACCESS_DENIED错误。那么这是否表明某种系统级障碍?我的机器上有管理员权限,我正在运行XP。

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

传递给GetExitCodeProcess的句柄需要PROCESS_QUERY_INFORMATION访问权限。 以下工作正常:

int main(int a_argc, char** a_argv)
{
    int pid = atoi(*(a_argv + 1));

    HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);

    if (NULL != h)
    {
        Sleep(2000);
        DWORD exit_code;
        if (FALSE == GetExitCodeProcess(h, &exit_code))
        {
            std::cerr << "GetExitCodeProcess() failure: " <<
                GetLastError() << "\n";
        }
        else if (STILL_ACTIVE == exit_code)
        {
            std::cout << "Still running\n";
        }
        else
        {
            std::cout << "exit code=" << exit_code << "\n";
        }
    }
    else
    {
        std::cerr << "OpenProcess() failure: " << GetLastError() << "\n";
    }

    return 0;
}

而不是GetExitCodeProcess上的轮询,而是使用SYNCHRONIZE打开句柄并等待它退出:

int main(int a_argc, char** a_argv)
{
    int pid = atoi(*(a_argv + 1));

    HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid);

    if (NULL != h)
    {
        WaitForSingleObject(h, 5000); // Change to 'INFINITE' wait if req'd
        DWORD exit_code;
        if (FALSE == GetExitCodeProcess(h, &exit_code))
        {
            std::cerr << "GetExitCodeProcess() failure: " <<
                GetLastError() << "\n";
        }
        else if (STILL_ACTIVE == exit_code)
        {
            std::cout << "Still running\n";
        }
        else
        {
            std::cout << "exit code=" << exit_code << "\n";
        }
    }
    else
    {
        std::cerr << "OpenProcess() failure: " << GetLastError() << "\n";
    }

    return 0;
}

答案 1 :(得分:1)

OpenProcesstoken需要PROCESS_QUERY_INFORMATION才能打开只有SYNCHRONIZE访问权限的进程。如果有效,请查看是否添加| PROCESS_QUERY_INFORMATION

答案 2 :(得分:1)

如果你只是希望P2在P1退出时做某事,那么另一种方式可能相当容易:让P1创建一个管道并让P2继承该管道的句柄。在P2中,执行管道读取。当P2对ReadFile的调用返回错误ERROR_BROKEN_PIPE时,P1已退出。