My app needs to do some privileged operations at runtime. For example,when the user is first time to run my app, i have to create and format a virtual dirve. I use the undocumented api formatex to do the fomating job, but formatex need administrator privileges. If OS is vista or later, i can prompt UAC dialog with 'COM Elevation Moniker' and it works fine. But on xp, this technique is not suitable, so i use the impersonate method.
if app is run as limited user, i do formating like this:
CredUIPromptForCredentials() -> prompt to get administrator credentials
LogonUser()
ImpersonateLoggedOnUser()
formatex()
RevertToSelf()
formatex still fail...
Of course, run my app as administrator will works, but it is not good, my app is installed as per user, not per machine, which should work under current user context, even if the user is a
limited user.
How can i correctly elevate my app at runtime to do the formating job? Any one help?
A possible solution is to re-execute the application with elevated privileges and some command line parameter which will instruct to perform actual formatting.
Example code:
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;
}