我的应用程序需要在运行时执行一些特权操作。例如,当用户第一次运行我的应用程序时,我必须创建并格式化虚拟dirve。我使用未记录的api formatex来完成这项工作,但是formatex需要管理员权限。如果操作系统是vista或更高版本,我可以使用“COM Elevation Moniker”提示UAC对话框,它可以正常工作。但是在xp上,这种技术并不合适,所以我使用了模仿方法。 如果app以受限用户身份运行,我会这样形成:
CredUIPromptForCredentials() -> prompt to get administrator credentials
LogonUser()
ImpersonateLoggedOnUser()
formatex()
RevertToSelf()
formatex仍然失败...... 当然,以管理员身份运行我的应用程序是可行的,但它不好,我的应用程序按用户安装,而不是按机器安装,这应该在当前用户上下文下工作,即使用户是 有限的用户。
如何在运行时正确提升我的应用以完成格式化工作?有人帮忙吗?
答案 0 :(得分:2)
一种可能的解决方案是使用提升的权限和一些命令行参数重新执行应用程序,该参数将指示执行实际格式化。
示例代码:
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;
}