Конференция "WinAPI" » Приложение с запросом на повышение привилегий
 
  • SPeller © (12.07.10 08:32) [0]
    Всем доброго времени суток!
    Никогда не работал с UAC, но тут понадобилось.
    Основная программа создает пайп и ивент и запускает дочерний процесс которому передается разрешение на наследование хэндлов и в переменных окружения передаются сами хэндлы на объекты. Основной процесс ждет установки ивента. Когда дочерний процесс готов работать он дергает ивент и приложения общаются через пайп. Сейчас это все пока под ХР-2000, проблем нет, но нужно чтобы на висте и семерке иногда выводился запрос на повышение привилегий. Т.е. одни действия выполняются из-под ограниченной по дефолту учетки, а на другие надо просить разрешения админских прав. Вопрос: можно ли переиначить такую систему с использованием CreateProcess чтобы по требованию просить привилегий? Или же нужно делать исключительно через ShellExecuteEx-RunAs и передавать имена объектов (пайпа и ивента) в параметрах? Вобщем, наставьте на путь истинный, я в этом пока дуб дубом )
  • Alex Konshin © (13.07.10 13:18) [1]
    CreateProcess при вызове любого приложения, которое требует elevation тупо обламывает с кодом вроде 740 (это на вскидку, точно не помню). Никаких запросов к юзеру не выдается, просто облом и всё. Запрос умеет выдавать ShellExecute*, а через CreateProcess - никак (поубивав бы тех в MS, кто это придумал). Это, кстати, одна из причин, почему хуча программ перестало работать в Windows 6+ при включеном UAC. Например, Java не умеет создавать процессы иначе чем через CreateProcess, да и большинство других средств разработки тоже.

    Пути борьбы... Почитай сначала побольше про UAC, чтобы понимать, что там происходит. Рекомендую посмотреть на занятный пример:
    http://www.codeproject.com/KB/vista-security/UAC__The_Definitive_Guide.aspx?display=Print
  • SPeller © (14.07.10 03:34) [2]
    Большое спасибо за ссылочку, весьма занятно и интересно. Обязательно поковыряю, что там за magic реализован )  Про UAC читал, в общих чертах вроде понимаю и представляю что он и для чего и как. Но вот шаг в сторону от  шаблонных примеров с манифестом или runas уперся в стену отсутствия инфы и толковых инструментов реализации.

    Вторая задачка возникла - самостоятельно вызвать показ окошка "Установка программы от имени другого пользователя" под ХР (желательно и 2000) при запуске из-под ограниченной учетки как это делает система при запуске setup.exe (runas показывает диалог "Запуск программы от имени другого ползователя", он другой).
  • dreamse © (16.11.11 14:04) [3]
    > SPeller


    uses
     shellapi;




    function RunAsAdmin(hWnd: HWND; filename: string; Parameters: string): Boolean;
    {
      See Step 3: Redesign for UAC Compatibility (UAC)
       <a href="http://msdn.microsoft.com/en-us/library/bb756922.aspx" title="http://msdn.microsoft.com/en-us/library/bb756922.aspx">http://msdn.microsoft.com/en-us/library/bb756922.aspx</a>
    }

    var
     sei: TShellExecuteInfo;
    begin
     ZeroMemory(@sei, SizeOf(sei));
     sei.cbSize := SizeOf(TShellExecuteInfo);
     sei.Wnd := hwnd;
     sei.fMask := SEE_MASK_FLAG_DDEWAIT or SEE_MASK_FLAG_NO_UI;
     sei.lpVerb := PChar('runas');
     sei.lpFile := PChar(Filename); // PAnsiChar;
     if parameters <> '' then
       sei.lpParameters := PChar(parameters); // PAnsiChar;
     sei.nShow := SW_SHOWNORMAL; //Integer;
     Result := ShellExecuteEx(@sei);
    end;



    Вариант с ожиданием заверщения приложения + таймаут работы.


    function VistaExecElevated(FileName, CLParams, Dir : String; var ExitCode: DWORD; const Wait: DWORD = 0): LongWord;
    var
    shExecInfo : TShellExecuteInfo;
    iWaitRes: DWORD;
    begin
    Result := 0;
    if FileName <> '' then
     begin
      FillChar(shExecInfo, SizeOf(shExecInfo), 0);
      shExecInfo.cbSize := SizeOf(shExecInfo);
      {if hHandle <> null then
       shExecInfo.WND := Hhandle;}

      shExecInfo.fMask  := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_NO_UI;
      //shExecInfo.hInstApp := NULL;
      shExecInfo.lpVerb := PChar('runas');
      shExecInfo.lpFile := PChar(FileName);
      if CLParams <> '' then
       shExecInfo.lpParameters := PChar(CLParams);
      if Dir <> '' then
       shExecInfo.lpDirectory := pchar(Dir);
      shExecInfo.nShow := SW_SHOW;   {SW_SHOW}
      ShellExecuteEx(@shExecInfo);
      Result := shExecInfo.hInstApp;
      if Result > 32 then
       begin
        // wait on process ?
        if (Wait > 0) then
         begin
          iWaitRes := WaitForSingleObject(shExecInfo.hProcess, Wait);
          // timeout reached ?
          if (iWaitRes = WAIT_TIMEOUT) then
           begin
             //Result := 0;
             TerminateProcess(shExecInfo.hProcess, 0);
           end;
          // get the exitcode
          GetExitCodeProcess(shExecInfo.hProcess, ExitCode);
         end;
        // close handle, because SEE_MASK_NOCLOSEPROCESS was set
        CloseHandle(shExecInfo.hProcess);
       end;
    end;
    end;

  • DiamondShark © (26.11.11 15:27) [4]
    Удалено модератором
    Примечание: не в пивной
 
Конференция "WinAPI" » Приложение с запросом на повышение привилегий
Есть новые Нет новых   [134430   +4][b:0][p:0.002]