Как я могу поднять свой процесс во время выполнения под Win XP - PullRequest
2 голосов
/ 30 декабря 2011

Мое приложение должно выполнять некоторые привилегированные операции во время выполнения.Например, когда пользователь впервые запускает мое приложение, мне нужно создать и отформатировать виртуальный диск.Я использую недокументированный api formatex, чтобы выполнить работу fomating, но formatex нужны права администратора.Если ОС Vista или более поздняя, ​​я могу предложить диалоговое окно UAC с «COM Elevation Moniker», и он работает нормально.Но на XP этот метод не подходит, поэтому я использую метод олицетворения.если приложение запускается как пользователь с ограниченными правами, я выполняю форматирование следующим образом:

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

formatex по-прежнему не работает ... Конечно, запустить мое приложение от имени администратора будет работать, но это не хорошо, мое приложение установленокак для пользователя, а не для компьютера, который должен работать в контексте текущего пользователя, даже если пользователь является пользователем с ограниченными правами.

Как я могу правильно поднять свое приложение во время выполнения, чтобы выполнить форматирующую работу?Любая помощь?

1 Ответ

2 голосов
/ 30 декабря 2011

Возможным решением является повторное выполнение приложения с повышенными привилегиями и некоторым параметром командной строки, который даст указание выполнить фактическое форматирование.

Пример кода:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...