Как получить уровень разрешений для папки? - PullRequest
1 голос
/ 02 августа 2011

Я хочу определить папку, если требуется уровень привилегий администратора (используя Delphi).Возможно ли это?

Я написал этот кодекс.Это именно то, что я хочу.Но я хочу сделать это, используя стандартные функции Windows.

// Check if You need Administrator-level access to create a folder
try
  mkdir(SDirectory + '\~TEST');
except
  on E: exception do
  begin
    if E.message = 'File access denied' then
    begin
      MessageBox(self.Handle,
        'You need Administrator-level access to create this folder', '', MB_ICONERROR);
      exit;
    end;
  end;
end;
RmDir(SDirectory + '\~TEST');

Ответы [ 2 ]

6 голосов
/ 02 августа 2011

Следующий пример переведен с этой статьи .Его можно использовать для определения, имеет ли файл или каталог права доступа, отмеченные в этой статье для каждого пользователя, поэтому, если я запрашиваю FILE_ALL_ACCESS, то это означает, что у всех есть полный доступ к нужному файлу или каталогу.,Обратите внимание, что в следующем коде нет обработки исключений, и я даже не могу вспомнить, когда я использовал VB в прошлый раз, так что это может быть неправильно, поэтому воспринимайте это как вдохновение и не стесняйтесь изменять этот пост.

const
  FILE_READ_DATA = $0001;
  FILE_WRITE_DATA = $0002;
  FILE_APPEND_DATA = $0004;
  FILE_READ_EA = $0008;
  FILE_WRITE_EA = $0010;
  FILE_EXECUTE = $0020;
  FILE_READ_ATTRIBUTES = $0080;
  FILE_WRITE_ATTRIBUTES = $0100;
  FILE_GENERIC_READ = (STANDARD_RIGHTS_READ or FILE_READ_DATA or
    FILE_READ_ATTRIBUTES or FILE_READ_EA or SYNCHRONIZE);
  FILE_GENERIC_WRITE = (STANDARD_RIGHTS_WRITE or FILE_WRITE_DATA or
    FILE_WRITE_ATTRIBUTES or FILE_WRITE_EA or FILE_APPEND_DATA or SYNCHRONIZE);
  FILE_GENERIC_EXECUTE = (STANDARD_RIGHTS_EXECUTE or FILE_READ_ATTRIBUTES or
    FILE_EXECUTE or SYNCHRONIZE);
  FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $1FF;

function CheckFileAccess(const FileName: string; const CheckedAccess: Cardinal): Cardinal;
var Token: Cardinal;
    Status: LongBool;
    Access: Cardinal;
    SecDescSize: Cardinal;
    PrivSetSize: Cardinal;
    PrivSet: PRIVILEGE_SET;
    Mapping: GENERIC_MAPPING;
    SecDesc: PSECURITY_DESCRIPTOR;
begin
  Result := 0;
  GetFileSecurity(PChar(Filename), OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION, nil, 0, SecDescSize);
  SecDesc := GetMemory(SecDescSize);

  if GetFileSecurity(PChar(Filename), OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION, SecDesc, SecDescSize, SecDescSize) then
  begin
    ImpersonateSelf(SecurityImpersonation);
    OpenThreadToken(GetCurrentThread, TOKEN_QUERY, False, Token);
    if Token <> 0 then
    begin
      Mapping.GenericRead := FILE_GENERIC_READ;
      Mapping.GenericWrite := FILE_GENERIC_WRITE;
      Mapping.GenericExecute := FILE_GENERIC_EXECUTE;
      Mapping.GenericAll := FILE_ALL_ACCESS;

      MapGenericMask(Access, Mapping);
      PrivSetSize := SizeOf(PrivSet);
      AccessCheck(SecDesc, Token, CheckedAccess, Mapping, PrivSet, PrivSetSize, Access, Status);
      CloseHandle(Token);
      if Status then
        Result := Access;
    end;
  end;

  FreeMem(SecDesc, SecDescSize);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if CheckFileAccess('C:\Windows', FILE_ALL_ACCESS) = FILE_ALL_ACCESS then
    ShowMessage('C:\Windows has full access for everyone')
  else
    ShowMessage('Someone has no full access to C:\Windows');
end;

enter image description here
с Delphi 2007 на 64-битной Windows 7 Enterprise SP 1


В любом случае, намного проще было бы загрузить JEDI Windows Security Code Library и следуйте примеру, подобному этому (я надеюсь, что он работает и для каталогов, но я почти уверен, что это будет).

2 голосов
/ 05 июня 2013

Небольшое изменение в примере выше для тех, кто перешел на Delphi XE2 и выше (токен больше не работает с Cardinal, должен быть THandle).

function getFileAccess(...):Cardinal;
var
    Token: THandle;//No longer Cardinal
begin
    { ... code ...}
    if GetFileSecurity({...params...}) then
    begin
        //... more stuff
        OpenThreadToken(GetCurrentThread,TOKEN_QUERY,false,Token);
        if Token<>0 then
        begin
            //... more stuff
            AccessCheck(SecDesc,Token,CheckedAccess,Mapping,PrivSet,PrivSetSize,Access,Status);
            CloseHandle(Token);
            //... more stuff
        end;
    end;
    //....more stuff
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...