如何以编程方式检查修改权限?

时间:2013-02-18 14:26:35

标签: delphi file-permissions uac

如何以编程方式检查文件夹的创建文件权限? 修改文件权限?删除文件权限?
GetNamedSecurityInfo返回我可以写入C:\Program Files,但UAC说Access Denied (5)
如何有效确定访问权限?

我的代码:

function GetAccessRights(const FileName: String; ObjectType: SE_OBJECT_TYPE; 
  var Access: Cardinal): Cardinal;
var
  SecDesc: PSECURITY_DESCRIPTOR;
  pDacl: PACL;
  Trusteee: TRUSTEE_;
begin
  result := GetNamedSecurityInfo(PChar(FileName), ObjectType, 
    DACL_SECURITY_INFORMATION, nil, nil, @pDacl, nil, SecDesc);
  if ERROR_SUCCESS = result then
  begin
    // the pDacl may be NULL if the object has unrestricted access
    if pDacl <> nil then
    begin
      with Trusteee do
      begin
        pMultipleTrustee := nil;
        MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
        TrusteeForm := TRUSTEE_IS_NAME;
        TrusteeType := TRUSTEE_IS_UNKNOWN;
        ptstrName := 'CURRENT_USER';
      end;
      result := GetEffectiveRightsFromAcl(pDacl^, Trusteee, Access);
    end
    else
    begin
      Access := $FFFFFFFF;
      result := ERROR_SUCCESS;
    end;
    if SecDesc <> nil then
      LocalFree(Cardinal(SecDesc));
  end;
end;

1 个答案:

答案 0 :(得分:9)

我一直在使用NT Utilities。使用Win2K / XP / Vista / 7

为我工作得非常好

来自我的设置项目的示例:

uses unitNTSecurity;

function CheckAccessToFile(DesiredAccess: DWORD; const FileOrDirName: string; ObjectName: string): Boolean;
var
  fo: TNTFileObject;
  acl: TAccessControlList;
  ace: TAccessControlElement;
  name: string;
  i: integer;
begin
  Result := False;
  if FileExists(FileOrDirName) or DirectoryExists(FileOrDirName) then
  begin
    fo := TNTFileObject.Create(FileOrDirName);
    acl := TAccessControlList.Create;
    try
      fo.GetDiscretionaryAccessList(acl);
      for i := 0 to acl.ElementCount - 1 do
      begin
        ace := acl.Element[i];
        name := ace.Name; // format is: BUILTIN\Users
        if (CompareText(ObjectName, name) = 0) and
          (ace.Type_ = aeAccessAllowed) and
          (DesiredAccess = ace.Mask) then
        begin
          Result := True;
          Break;
        end;
      end;
    finally
      fo.Free;
      acl.Free;
    end;
  end;
end;

检查modify权限:

Result := CheckAccessToFile($001301BF, 'C:\foo', 'BUILTIN\Users');

关于我的回答的说明:上述代码回答了OP问题:

  

如何以编程方式检查修改权限

但是,如果您需要做的只是检查您的应用程序能够写入目录,我会去寻找这种ACL解决方案,并实际上尝试写一个临时文件,以便我100%确定我可以写它。

我使用此代码作为我的设置过程的一部分,我需要为某些目录授予modify权限,因此此代码用于检查该目录是否还没有这些权限 - 这可能是一个非常与你的情况不同。

关于这个问题有一些讨论:

因此,您需要根据实际情况选择解决方案。