如何在winxp运行时提升我的进程?

How can i elevate my process at runtime under win xp

本文关键字:我的 进程 运行时 winxp      更新时间:2023-10-16

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

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

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

我怎样才能在运行时正确地提升我的应用程序来完成格式化工作?有人帮忙吗?

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

示例代码:

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