【问题标题】:How can i elevate my process at runtime under win xp我如何在win xp下在运行时提升我的进程
【发布时间】:2011-12-30 03:58:49
【问题描述】:

我的应用需要在运行时执行一些特权操作。例如,当用户第一次运行我的应用程序时,我必须创建并格式化一个虚拟驱动器。我使用未记录的 api formatex 来完成格式化工作,但 formatex 需要管理员权限。如果操作系统是 vista 或更高版本,我可以使用“COM Elevation Moniker”提示 UAC 对话框,它工作正常。但在 xp 上,这种技术不适合,所以我使用模拟方法。 如果应用程序以受限用户身份运行,我会像这样格式化:

CredUIPromptForCredentials() -> prompt to get administrator credentials
LogonUser()
ImpersonateLoggedOnUser()
formatex()
RevertToSelf()

formatex 仍然失败... 当然,以管理员身份运行我的应用程序可以,但这并不好,我的应用程序是按用户安装的,而不是按机器安装的,它应该在当前用户上下文下工作,即使用户是 受限用户。

如何在运行时正确提升我的应用程序以完成格式化工作?有人帮忙吗?

【问题讨论】:

    标签: c++ windows security winapi


    【解决方案1】:

    一个可能的解决方案是使用提升的权限和一些命令行参数重新执行应用程序,这些参数将指示执行实际的格式化。

    示例代码:

    if (!IsUserAdmin()) {
         RunAsAdmin(hwnd, exeName, "--do-format");
    } else {
         DoFormat();
    }
    ...
    
    BOOL RunAsAdmin(HWND hWnd, LPCTSTR lpFile, LPCTSTR lpParameters)
    {
        SHELLEXECUTEINFO sei;
        ZeroMemory(&sei, sizeof(sei));
    
        sei.cbSize          = sizeof(SHELLEXECUTEINFOW);
        sei.hwnd            = hWnd;
        sei.fMask           = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
        sei.lpVerb          = _TEXT("runas");
        sei.lpFile          = lpFile;
        sei.lpParameters    = lpParameters;
        sei.nShow           = SW_SHOWNORMAL;
    
        if (!ShellExecuteEx(&sei)) {
                return FALSE;
        }
        return TRUE;
    }
    
    BOOL IsUserAdmin(VOID)
    {
        BOOL b;
        SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
        PSID AdministratorsGroup;
        b = AllocateAndInitializeSid(
                &NtAuthority,
                2,
                SECURITY_BUILTIN_DOMAIN_RID,
                DOMAIN_ALIAS_RID_ADMINS,
                0, 0, 0, 0, 0, 0,
                &AdministratorsGroup);
        if (b) {
                if (!CheckTokenMembership( NULL, AdministratorsGroup, &b)) {
                        b = FALSE;
                }
                FreeSid(AdministratorsGroup);
        }
    
        return b;
    }
    

    【讨论】:

    • 这就是我在我的应用程序中所做的(虽然没有检查 IsUserAdmin() - 我让 Win32 API 函数向我报告 ERROR_ELEVATION_NEEDED),而且效果很好。
    • 感谢 dimitri 的回答。我最终使用了 dimitri 提出的方法,但有点不同。我使用 CredUIPromptForCredentials() ->LogonUser()-> IsUserAdmin(my function) -> CreateProcessWithLogonW 循环来确保管理员凭据。现在一切顺利。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多