Конференция "WinAPI" » uac + действия или [D7]
 
  • QAZ (25.01.10 11:17) [0]
    как сделать выполнение команды под админом если прога запущена юзером ? т.е. все надеюсь видели кнопки со щитом, вот я про это
    и соответствено повышение прав дается только под выполнение команды или навсегда для всей проги ?
  • Eraser © (25.01.10 17:09) [1]
    > или навсегда для всей проги ?

    конкретно для какого-то действия нельзя. админские права запрашиваются для всей программы.
  • Дмитрий С © (26.01.10 15:54) [2]

    > Eraser ©   (25.01.10 17:09) [1]

    А на время поднять свои права можно?
  • Eraser © (26.01.10 17:19) [3]
    > [2] Дмитрий С ©   (26.01.10 15:54)

    нельзя вроде как.
  • Rouse_ © (26.01.10 18:04) [4]
    Поднять нельзя. А запрашивать права при старте очень даже просто. Пипшешь вот такой RC файл:

    #define RT_MANIFEST  24
    #define CREATEPROCESS_MANIFEST_RESOURCE_ID  1
    CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST ".\manifest.txt"


    Подключаешь этот RC к своей программе (стандартный манифест только отключи)

    В файл manifest.txt вбиваеш след текст:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
     <assemblyIdentity
        type="win32"
        name="DelphiApplication"
        version="1.0.0.0"
        processorArchitecture="*"/>
     <dependency>
        <dependentAssembly>
          <assemblyIdentity
             type="win32"
             name="Microsoft.Windows.Common-Controls"
             version="6.0.0.0"
             publicKeyToken="6595b64144ccf1df"
             language="*"
             processorArchitecture="*"/>
        </dependentAssembly>
     </dependency>
     <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
          <requestedPrivileges>
             <requestedExecutionLevel
               level="requireAdministrator"
               uiAccess="false"/>
          </requestedPrivileges>
        </security>
     </trustInfo>
    </assembly>



    Получаешь программу со "щитом", которая при старте будет требовать права админа.
    Из минусов - если дельфя запущена без админских прав, дебащить проект с таким манифестом с включенным UAC не получится.
  • Rouse_ © (26.01.10 18:09) [5]
    Вот тебе кстати до кучи код, который показывает имеем ли мы админские права или нет с учетом UAC

    type
     TPrivilegeCheckState = (csError, csLimitedUser, csAdmin);

    function IsAdmin: TPrivilegeCheckState;
    const
     SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
       (Value: (0, 0, 0, 0, 0, 5));
     SECURITY_BUILTIN_DOMAIN_RID = $00000020;
     DOMAIN_ALIAS_RID_ADMINS = $00000220;
     SECURITY_MANDATORY_HIGH_RID = $00003000;
     TokenIntegrityLevel = 25;
    var
     hAccessToken: THandle;
     ptgGroups: PTokenGroups;
     dwInfoBufferSize: DWORD;
     psidAdministrators: PSID;
     I: Integer;
     SubAuthority: DWORD;    
    begin
     Result := csError;
     if Win32Platform <> VER_PLATFORM_WIN32_NT then Exit;
     if not OpenThreadToken(GetCurrentThread,
       TOKEN_QUERY, True, hAccessToken) then
       if not OpenProcessToken(GetCurrentProcess,
         TOKEN_QUERY, hAccessToken) then Exit;
     try
       GetMem(ptgGroups, 1024);
       try
         if Win32MajorVersion < 6 then
         begin
           if not GetTokenInformation(hAccessToken, TokenGroups,
             ptgGroups, 1024, dwInfoBufferSize) then Exit;
           AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
             SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
             0, 0, 0, 0, 0, 0, psidAdministrators);
           try
             Result := csLimitedUser;
             for I := 0 to ptgGroups.GroupCount - 1 do
               if EqualSid(psidAdministrators, ptgGroups.Groups[I].Sid) then
               begin
                 Result := csAdmin;
                 Break;
               end;
           finally
             FreeSid(psidAdministrators);
           end;
         end
         else
         begin
           if GetTokenInformation(hAccessToken, TTokenInformationClass(TokenIntegrityLevel),
             ptgGroups, 1024, dwInfoBufferSize) and
             IsValidSid(PSIDAndAttributes(ptgGroups)^.Sid) then
           begin
             Result := csLimitedUser;
             SubAuthority :=
               GetSidSubAuthorityCount(PSIDAndAttributes(ptgGroups)^.Sid)^ - 1;
             if GetSidSubAuthority(PSIDAndAttributes(ptgGroups)^.Sid,
               SubAuthority)^ >= SECURITY_MANDATORY_HIGH_RID then
               Result := csAdmin;
           end;
         end;
       finally
         FreeMem(ptgGroups);
       end;
     finally
       CloseHandle(hAccessToken);
     end;
    end;

  • Eraser © (26.01.10 18:23) [6]
    в дополнение к  [4] Rouse_ ©   (26.01.10 18:04)
    скажу что, нужно удалить из проекта и других юнитов все упоминания о модуле XPMan (компонент TXPManifest), а то он подсовывает свой манифест, который мешает новому.
  • Eraser © (26.01.10 18:37) [7]
    > [5] Rouse_ ©   (26.01.10 18:09)

    у этого способа (точнее не конретно этого, а такого подхода с перечислением вручную) есть недостаток. у некоторых клиентов при сложной организации прав в домене он отрабатывал не правильно, причем даже на XP. Ховард рекомендует такие проверки делать с пом. CheckTokenMembership.

    Кстати не совсем понял зачем нужен особый способ определения админских прав для UAC? Работает и стандартный вроде.

    до кучи пример с 5 способами проверки админских прав (4 самый корректный) http://slil.ru/28550987

    // CheckTokenMembership.
    function IsAdmin3: Boolean;
    const
     SE_GROUP_ENABLED = $00000004;
     SE_GROUP_USE_FOR_DENY_ONLY  = $00000010;
    var
     psidAdministrators: PSID;
     bIsMember: LongBool;
    begin
     Result := False;
     if Win32Platform <> VER_PLATFORM_WIN32_NT then
     begin
       Result := True;
       Exit;
     end;

     psidAdministrators := nil;
     try
       if AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
         SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
         0, 0, 0, 0, 0, 0, psidAdministrators) then
       begin
         if CheckTokenMembership(0, psidAdministrators, bIsMember) then
           Result := bIsMember;
       end;
     finally
       if psidAdministrators <> nil then
         FreeSid(psidAdministrators);
     end;
    end;

  • Игорь Шевченко © (26.01.10 18:47) [8]

    > до кучи


    Shell32.IsUserAnAdmin
  • Rouse_ © (26.01.10 20:39) [9]

    > Кстати не совсем понял зачем нужен особый способ определения
    > админских прав для UAC? Работает и стандартный вроде.

    У меня не отрабатывал, пришлось допиливать. Точнее как, под Windows 7 возвращал что я с админскими правами, хотя на самом деле приложение было запущено как обычный пользователь.
    Опять-же делалось все в состоянии  "сдать проект нужно еще вчера", поэтому...


    > Игорь Шевченко ©   (26.01.10 18:47) [8]
    > > до кучи
    > Shell32.IsUserAnAdmin

    Танк секретный, наука может и не знать? :)
    Shell32 моя 2007-ая студия не опознает :)
  • Игорь Шевченко © (26.01.10 20:51) [10]
    Rouse_ ©   (26.01.10 20:39) [9]

    Я не знаю, как оно отрабатывает при обычном пользователе, но с поднятыми правами. Наверняка что-то на эту тему есть в Shell32 или в ShlwApi изданием для Vista или Windows 7
  • Rouse_ © (26.01.10 20:56) [11]
    Ну это ты наверно про 2009-ую студию говоришь, ибо в 2007-ой нет модуля Shell32, а в модуле ShlwApi нет IsUserAnAdmin
  • Игорь Шевченко © (26.01.10 21:02) [12]
    Rouse_ ©   (26.01.10 20:56) [11]

    Я говорю про функции в Shell32.dll или в Shlwapi.dll, без разницы, каким средством разработки пользоваться.
  • Rouse_ © (26.01.10 21:05) [13]

    > Игорь Шевченко ©   (26.01.10 21:02) [12]
    > Rouse_ ©   (26.01.10 20:56) [11]
    >
    > Я говорю про функции в Shell32.dll или в Shlwapi.dll

    Мдя... совсем мозги зашорились... :) Ясно :)
  • Eraser © (26.01.10 21:11) [14]
    в примере по ссылке есть
    // IsUserAnAdmin.
    function IsAdmin4: Boolean;
    var
     hShell32: HMODULE;
     _IsUserAnAdmin: function(): BOOL; stdcall;
    begin
     Result := False;

     hShell32 := LoadLibrary('shell32.dll');
     _IsUserAnAdmin := GetProcAddress(hShell32, 'IsUserAnAdmin'); // Do not localize
     if Assigned(_IsUserAnAdmin) then
       Result := _IsUserAnAdmin()
     else
       ShowMessage('Does not supported!');
    end;



    только она тоже не правильно в домене работает иногда.
  • Rouse_ © (26.01.10 21:24) [15]
    Ну мой вариант гарантированно работает всегда, проверял и под вистой и под 2008 сервером и под семеркой (как 32 так и 64 бита)
  • Игорь Шевченко © (26.01.10 21:27) [16]
    к Игорь Шевченко ©   (26.01.10 20:51) [10]

    Все нормально, IsUserAdmin показывает поднятые привилегии тоже.
    http://cc.embarcadero.com/item/24512
  • QAZ (26.01.10 21:41) [17]
    я не про запуск самой проги от админа и манифесты
    а про команды выполняемые под админом,т.е. запись в реестр удал. файлов, когда системой задается вопрос разрешить или нет,а не возвращается типа нет доступа или проглатывается виртуализацией
    при этом изначально прога не под админом,и встречается это частенько
  • Rouse_ © (26.01.10 22:00) [18]
    под UAC все сразу виртуализируется без дополнительных вопросов.
 
Конференция "WinAPI" » uac + действия или [D7]
Есть новые Нет новых   [134432   +18][b:0][p:0.004]