1

我正在尝试编写一个函数来告诉我特定用户是否对文件夹具有特定权限。到目前为止,我在这里找到了一个关于如何执行此操作的示例,因此我尝试在 delphi 中编写此代码。

unit SysCommonUnit;

interface

uses
  SysUtils,
  Classes,
  System.Math,
  Winapi.Windows,
  WinTypes;

const
  NERR_SUCCESS                     = 0;
  MAX_NR_USERS                     = 1000;
  FILTER_TEMP_DUPLICATE_ACCOUNT    = $0001;
  FILTER_NORMAL_ACCOUNT            = $0002;
  FILTER_PROXY_ACCOUNT             = $0004;
  FILTER_INTERDOMAIN_TRUST_ACCOUNT = $0008;
  FILTER_WORKSTATION_TRUST_ACCOUNT = $0010;
  FILTER_SERVER_TRUST_ACCOUNT      = $0020;

  AUTHZ_RM_FLAG_NO_AUDIT    = $1;
  {$EXTERNALSYM AUTHZ_RM_FLAG_NO_AUDIT}

  FILE_READ_DATA            = $0001; // file & pipe
  FILE_LIST_DIRECTORY       = $0001; // directory
  FILE_WRITE_DATA           = $0002; // file & pipe
  FILE_ADD_FILE             = $0002; // directory
  FILE_APPEND_DATA          = $0004; // file
  FILE_ADD_SUBDIRECTORY     = $0004; // directory
  FILE_CREATE_PIPE_INSTANCE = $0004; // named pipe
  FILE_READ_EA              = $0008; // file & directory
  FILE_WRITE_EA             = $0010; // file & directory
  FILE_EXECUTE              = $0020; // file
  FILE_TRAVERSE             = $0020; // directory
  FILE_DELETE_CHILD         = $0040; // directory
  FILE_READ_ATTRIBUTES      = $0080; // all
  FILE_WRITE_ATTRIBUTES     = $0100; // all

  FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or
                    SYNCHRONIZE or
                    $1FF;

  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;

type
  ACE_HEADER = record
    AceType: BYTE;
    AceFlags: BYTE;
    AceSize: WORD;
  end;

  PPSECURITY_DESCRIPTOR = ^PSECURITY_DESCRIPTOR;

  PACE_HEADER = ^ACE_HEADER;

  PAUTHZ_ACCESS_REQUEST = ^AUTHZ_ACCESS_REQUEST;

  POBJECT_TYPE_LIST = ^OBJECT_TYPE_LIST;

  _OBJECT_TYPE_LIST = record
    Level: WORD;
    Sbz: WORD;
    ObjectType: PGUID;
  end;

  OBJECT_TYPE_LIST = _OBJECT_TYPE_LIST;

  TObjectTypeList = OBJECT_TYPE_LIST;
  PObjectTypeList = POBJECT_TYPE_LIST;

  _AUTHZ_ACCESS_REQUEST = record
    DesiredAccess: ACCESS_MASK;
    PrincipalSelfSid: PSID;
    ObjectTypeList: POBJECT_TYPE_LIST;
    ObjectTypeListLength: DWORD;
    OptionalArguments: PVOID;
  end;

  AUTHZ_ACCESS_REQUEST = _AUTHZ_ACCESS_REQUEST;

  TAuthzAccessRequest = AUTHZ_ACCESS_REQUEST;
  PAuthzAccessRequest = PAUTHZ_ACCESS_REQUEST;

  PAUTHZ_ACCESS_REPLY = ^AUTHZ_ACCESS_REPLY;

  _AUTHZ_ACCESS_REPLY = record
    ResultListLength: DWORD;
    GrantedAccessMask: PACCESS_MASK;
    SaclEvaluationResults: PDWORD;
    Error: PDWORD;
  end;

  AUTHZ_ACCESS_REPLY = _AUTHZ_ACCESS_REPLY;

  TAuthzAccessReply = AUTHZ_ACCESS_REPLY;
  PAuthzAccessReply = PAUTHZ_ACCESS_REPLY;

  TCHAR = char;

  AUTHZ_RESOURCE_MANAGER_HANDLE = THANDLE;

  AUTHZ_CLIENT_CONTEXT_HANDLE = THANDLE;

  AUTHZ_AUDIT_EVENT_HANDLE = THANDLE;

  PAUTHZ_RESOURCE_MANAGER_HANDLE = ^AUTHZ_RESOURCE_MANAGER_HANDLE;

  PAUTHZ_CLIENT_CONTEXT_HANDLE = ^AUTHZ_CLIENT_CONTEXT_HANDLE;

  PFN_AUTHZ_DYNAMIC_ACCESS_CHECK = function(hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE;
                                            pAce: PACE_HEADER;
                                            pArgs: PVOID;
                                            var pbAceApplicable: BOOL): BOOL; stdcall;

  PFnAuthzDynamicAccessCheck = PFN_AUTHZ_DYNAMIC_ACCESS_CHECK;

  PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS = function(hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE;
                                              Args: PVOID;
                                              var pSidAttrArray: PSIDAndAttributes;
                                              var pSidCount: DWORD;
                                              var pRestrictedSidAttrArray: PSIDAndAttributes;
                                              var pRestrictedSidCount: DWORD): BOOL; stdcall;

  PFnAuthzComputeDynamicGroups = PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS;

  PFN_AUTHZ_FREE_DYNAMIC_GROUPS = procedure(pSidAttrArray: PSIDAndAttributes); stdcall;

  PFnAuthzFreeDynamicGroups = PFN_AUTHZ_FREE_DYNAMIC_GROUPS;

  AUTHZ_ACCESS_CHECK_RESULTS_HANDLE = THANDLE;

  PAUTHZ_ACCESS_CHECK_RESULTS_HANDLE = ^AUTHZ_ACCESS_CHECK_RESULTS_HANDLE;


  SE_OBJECT_TYPE = (SE_UNKNOWN_OBJECT_TYPE,
                    SE_FILE_OBJECT,
                    SE_SERVICE,
                    SE_PRINTER,
                    SE_REGISTRY_KEY,
                    SE_LMSHARE,
                    SE_KERNEL_OBJECT,
                    SE_WINDOW_OBJECT,
                    SE_DS_OBJECT,
                    SE_DS_OBJECT_ALL,
                    SE_PROVIDER_DEFINED_OBJECT,
                    SE_WMIGUID_OBJECT);


function GetNamedSecurityInfoW( pObjectName: PWideChar;
                                ObjectType: SE_OBJECT_TYPE;
                                SecurityInfo: SECURITY_INFORMATION;
                                var ppSidOwner: PSID;
                                var ppSidGroup: PSID;
                                var ppDacl: PACL;
                                var ppSacl: PACL;
                                var ppSecurityDescriptor: PSECURITY_DESCRIPTOR): DWORD; stdcall; external 'Advapi32.dll';

function AuthzInitializeResourceManagerWrapper( nFlags: DWORD;
                                                pfnDynamicAccessCheck: PFN_AUTHZ_DYNAMIC_ACCESS_CHECK;
                                                pfnComputeDynamicGroups: PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS;
                                                pfnFreeDynamicGroups: PFN_AUTHZ_FREE_DYNAMIC_GROUPS;
                                                szResourceManagerName: string;
                                                var hAuthzResourceManager: AUTHZ_RESOURCE_MANAGER_HANDLE): Boolean;

function AuthzInitializeContextFromSidWrapper(Flags: DWORD;
                                              UserSid: PSID;
                                              hAuthzResourceManager: AUTHZ_RESOURCE_MANAGER_HANDLE;
                                              pExpirationTime: PLargeInteger;
                                              Identifier: LUID;
                                              DynamicGroupArgs: PVOID;
                                              var hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE): Boolean;

function AuthzFreeResourceManagerWrapper(hAuthzResourceManager: AUTHZ_RESOURCE_MANAGER_HANDLE): Boolean;

function AuthzFreeContextWrapper(hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE): Boolean;

function AuthzAccessCheckWrapper( Flags: DWORD;
                                  hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE;
                                  var pRequest: AUTHZ_ACCESS_REQUEST;
                                  hAuditEvent: AUTHZ_AUDIT_EVENT_HANDLE;
                                  var pSecurityDescriptor: SECURITY_DESCRIPTOR;
                                  var OptionalSecurityDescriptorArray: PSECURITY_DESCRIPTOR;
                                  OptionalSecurityDescriptorCount: DWORD;
                                  var pReply: AUTHZ_ACCESS_REPLY;
                                  var phAccessCheckResultsOPTIONAL: AUTHZ_ACCESS_CHECK_RESULTS_HANDLE): Boolean;

function ConvertUsernameToBinarySID(p_pAccountName: string): PSID;

function HasRightsForUser(p_hManager: AUTHZ_RESOURCE_MANAGER_HANDLE;
                          p_oPsd: PSECURITY_DESCRIPTOR;
                          p_sUsername: string;
                          p_nDesiredRights: DWORD): Boolean;

function HasAccess(p_hAuthzClient: AUTHZ_CLIENT_CONTEXT_HANDLE; p_oPsd: PSECURITY_DESCRIPTOR; p_nDesiredRights: DWORD): Boolean;

function HasAccessRights(p_nDesiredRights: Integer; p_sFileName: string; p_sUsername: string): Boolean;

implementation

function AuthzInitializeResourceManagerWrapper( nFlags: DWORD;
                                                pfnDynamicAccessCheck: PFN_AUTHZ_DYNAMIC_ACCESS_CHECK;
                                                pfnComputeDynamicGroups: PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS;
                                                pfnFreeDynamicGroups: PFN_AUTHZ_FREE_DYNAMIC_GROUPS;
                                                szResourceManagerName: string;
                                                var hAuthzResourceManager: AUTHZ_RESOURCE_MANAGER_HANDLE): Boolean;
var
  DLLHandle                       : THandle;
  wResourceManagerName            : array[0..1024] of Widechar;
  AuthzInitializeResourceManager  : function (nFlags: DWORD;
                                              pfnDynamicAccessCheck: PFN_AUTHZ_DYNAMIC_ACCESS_CHECK;
                                              pfnComputeDynamicGroups: PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS;
                                              pfnFreeDynamicGroups: PFN_AUTHZ_FREE_DYNAMIC_GROUPS;
                                              szResourceManagerName: PWideChar;
                                              phAuthzResourceManager: PAUTHZ_RESOURCE_MANAGER_HANDLE): BOOL; cdecl stdcall;
begin
  Result    := False;
  DLLHandle := LoadLibrary('authz.dll');
  if DLLHandle >= 32 then
  begin
    @AuthzInitializeResourceManager := GetProcAddress(DLLHandle, 'AuthzInitializeResourceManager');

    StringToWideChar(szResourceManagerName, wResourceManagerName, sizeof(wResourceManagerName));

    Result := AuthzInitializeResourceManager( nFlags,
                                              pfnDynamicAccessCheck,
                                              pfnComputeDynamicGroups,
                                              pfnFreeDynamicGroups,
                                              wResourceManagerName,
                                              @hAuthzResourceManager);
    FreeLibrary(DLLHandle);
  end;
end;

function AuthzInitializeContextFromSidWrapper(Flags: DWORD;
                                              UserSid: PSID;
                                              hAuthzResourceManager: AUTHZ_RESOURCE_MANAGER_HANDLE;
                                              pExpirationTime: PLargeInteger;
                                              Identifier: LUID;
                                              DynamicGroupArgs: PVOID;
                                              var hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE): Boolean;
var
  DLLHandle                       : THandle;
  AuthzInitializeContextFromSid   : function (Flags: DWORD;
                                              UserSid: PSID;
                                              hAuthzResourceManager: AUTHZ_RESOURCE_MANAGER_HANDLE;
                                              pExpirationTime: PLargeInteger;
                                              Identifier: LUID;
                                              DynamicGroupArgs: PVOID;
                                              hAuthzClientContext: PAUTHZ_CLIENT_CONTEXT_HANDLE): BOOL; cdecl stdcall;
begin
  Result    := False;
  DLLHandle := LoadLibrary('authz.dll');

  if DLLHandle >= 32 then
  begin
    @AuthzInitializeContextFromSid := GetProcAddress(DLLHandle, 'AuthzInitializeContextFromSid');
    Result := AuthzInitializeContextFromSid(Flags,
                                            UserSid,
                                            hAuthzResourceManager,
                                            pExpirationTime,
                                            Identifier,
                                            DynamicGroupArgs,
                                            @hAuthzClientContext);
    FreeLibrary(DLLHandle);
  end;
end;

function AuthzFreeResourceManagerWrapper(hAuthzResourceManager: AUTHZ_RESOURCE_MANAGER_HANDLE): Boolean;
var
  DLLHandle                       : THandle;
  AuthzFreeResourceManager        : function(hAuthzResourceManager: AUTHZ_RESOURCE_MANAGER_HANDLE): BOOL; cdecl stdcall;
begin
  Result    := False;
  DLLHandle := LoadLibrary('authz.dll');

  if DLLHandle >= 32 then
  begin
    @AuthzFreeResourceManager := GetProcAddress(DLLHandle, 'AuthzFreeResourceManager');
    Result := AuthzFreeResourceManager(hAuthzResourceManager);

    FreeLibrary(DLLHandle);
  end;
end;

function AuthzFreeContextWrapper(hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE): Boolean;
var
  DLLHandle               : THandle;
  AuthzFreeContext        : function(hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE): BOOL; cdecl stdcall;
begin
  Result    := False;
  DLLHandle := LoadLibrary('authz.dll');

  if DLLHandle >= 32 then
  begin
    @AuthzFreeContext := GetProcAddress(DLLHandle, 'AuthzFreeResourceManager');
    Result := AuthzFreeContext(hAuthzClientContext);

    FreeLibrary(DLLHandle);
  end;
end;


function AuthzAccessCheckWrapper( Flags: DWORD;
                                  hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE;
                                  var pRequest: AUTHZ_ACCESS_REQUEST;
                                  hAuditEvent: AUTHZ_AUDIT_EVENT_HANDLE;
                                  var pSecurityDescriptor: SECURITY_DESCRIPTOR;
                                  var OptionalSecurityDescriptorArray: PSECURITY_DESCRIPTOR;
                                  OptionalSecurityDescriptorCount: DWORD;
                                  var pReply: AUTHZ_ACCESS_REPLY;
                                  var phAccessCheckResultsOPTIONAL: AUTHZ_ACCESS_CHECK_RESULTS_HANDLE): Boolean;
var
  nError                  : Integer;
  DLLHandle               : THandle;
  AuthzAccessCheck        : function( Flags: DWORD;
                                      hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE;
                                      pRequest: PAUTHZ_ACCESS_REQUEST;
                                      hAuditEvent: AUTHZ_AUDIT_EVENT_HANDLE;
                                      pSecurityDescriptor: PSECURITY_DESCRIPTOR ;
                                      OptionalSecurityDescriptorArray: PPSECURITY_DESCRIPTOR;
                                      OptionalSecurityDescriptorCount: DWORD;
                                      pReply: PAUTHZ_ACCESS_REPLY;
                                      phAccessCheckResultsOPTIONAL: PAUTHZ_ACCESS_CHECK_RESULTS_HANDLE): BOOL; cdecl stdcall;
begin
  Result    := False;
  DLLHandle := LoadLibrary('authz.dll');

  if DLLHandle >= 32 then
  begin
    @AuthzAccessCheck := GetProcAddress(DLLHandle, 'AuthzAccessCheck');
    Result := AuthzAccessCheck(Flags,
                               hAuthzClientContext,
                               @pRequest,
                               hAuditEvent,
                               @pSecurityDescriptor,
                               @OptionalSecurityDescriptorArray,
                               OptionalSecurityDescriptorCount,
                               @pReply,
                               @phAccessCheckResultsOPTIONAL);

    if not Result then
      nError := GetLastError;

    FreeLibrary(DLLHandle);
  end;
end;


function HasAccessRights(p_nDesiredRights: Integer; p_sFileName: string; p_sUsername: string): Boolean;
var
  nDW      : DWORD;
  pSidOwner: PSID;
  pSidGroup: PSID;
  pPsd     : PSECURITY_DESCRIPTOR;
  oDAcl    : PACL;
  oSAcl    : PACL;
  hManager : AUTHZ_RESOURCE_MANAGER_HANDLE;
  bRes     : Boolean;
begin
  oSAcl     := nil;
  oDAcl     := nil;
  pSidOwner := nil;
  pSidGroup := nil;
  pPsd      := nil;

  hManager  := 0;

  Result    := False;

  try
    nDW := GetNamedSecurityInfoW( PWideChar(p_sFileName),
                                  SE_FILE_OBJECT,
                                  DACL_SECURITY_INFORMATION or OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION,
                                  pSidOwner,
                                  pSidGroup,
                                  oDAcl,
                                  oSAcl,
                                  pPsd);

    if nDW <> ERROR_SUCCESS then
      Exit;

    bRes := AuthzInitializeResourceManagerWrapper(AUTHZ_RM_FLAG_NO_AUDIT, nil, nil, nil, PWideChar(EmptyStr), hManager);
    if not bRes then
      Exit;

    bRes := HasRightsForUser(hManager, pPsd, p_sUsername, p_nDesiredRights);
    if not bRes then
      Exit;

    Result := True;

  finally
    AuthzFreeResourceManagerWrapper(hManager);
    if Assigned(pPsd) then
      LocalFree(HLOCAL(pPsd));

  end;
end;

function HasRightsForUser(p_hManager: AUTHZ_RESOURCE_MANAGER_HANDLE;
                          p_oPsd: PSECURITY_DESCRIPTOR;
                          p_sUsername: string;
                          p_nDesiredRights: DWORD): Boolean;
var
  hAuthzClientContext: AUTHZ_CLIENT_CONTEXT_HANDLE;
  bResult            : Boolean;
  n_UnusedID         : LUID;
  oSid               : PSID;
begin
  hAuthzClientContext := 0;
  Result              := false;
  n_UnusedID.LowPart  := 0;
  n_UnusedID.HighPart := 0;

  oSid := ConvertUsernameToBinarySID(p_sUsername);

  if Assigned(oSid) then
  begin
    try
      bResult := AuthzInitializeContextFromSidWrapper(0, oSid, p_hManager, nil, n_UnusedID, nil, hAuthzClientContext);

      if not bResult then
        Exit;

      bResult := HasAccess(hAuthzClientContext, p_oPsd, p_nDesiredRights);

      if bResult then
        Result := True;

    finally
      if Assigned(oSid) then
        LocalFree(HLOCAL(oSid));

      AuthzFreeContextWrapper(hAuthzClientContext);
    end;
  end;
end;

function ConvertUsernameToBinarySID(p_pAccountName: string): PSID;
var
  psDomainName   : LPTSTR;
  nDomainNameSize: DWORD;
  oSid           : PSID;
  nSidSize       : DWORD;
  eSidType       : SID_NAME_USE;
  bResult        : Boolean;
begin
  Result          := nil;
  psDomainName    := nil;
  nDomainNameSize := 0;
  oSid            := nil;
  bResult         := false;

  try
    LookupAccountName(nil,             // lpServerName: look up on local system
      PWideChar(p_pAccountName), oSid, // buffer to receive name
      nSidSize, psDomainName, nDomainNameSize, eSidType);

    if GetLastError = ERROR_INSUFFICIENT_BUFFER then
    begin
      oSid := LPTSTR(LocalAlloc(LPTR, nSidSize * SizeOf(TCHAR)));
      if not Assigned(oSid) then
        Exit;

      psDomainName := LPTSTR(LocalAlloc(LPTR, nDomainNameSize * SizeOf(TCHAR)));
      if not Assigned(psDomainName) then
        Exit;

      bResult := LookupAccountName( nil,  // lpServerName: look up on local system
                                    PWideChar(p_pAccountName),
                                    oSid, // buffer to receive name
                                    nSidSize,
                                    psDomainName,
                                    nDomainNameSize,
                                    eSidType);
      if bResult then
        Result := oSid;

    end
    else
      Exit;
  finally
    if Assigned(psDomainName) then
    begin
      LocalFree(HLOCAL(psDomainName));
    end;
    // Free pSid only if failed;
    // otherwise, the caller has to free it after use.
    if (bResult = false) and Assigned(oSid) then
    begin
      LocalFree(HLOCAL(oSid));
    end;
  end;
end;

function HasAccess(p_hAuthzClient: AUTHZ_CLIENT_CONTEXT_HANDLE; p_oPsd: PSECURITY_DESCRIPTOR; p_nDesiredRights: DWORD): Boolean;
var
  oDescArray    : Pointer;
  oCheckResults : AUTHZ_ACCESS_CHECK_RESULTS_HANDLE;
  oAccessRequest: AUTHZ_ACCESS_REQUEST;
  oAccessReply  : AUTHZ_ACCESS_REPLY;
  a_nBuffer     : array [0 .. 1024] of BYTE;
  bResult       : Boolean;
  oPsd          : SECURITY_DESCRIPTOR;
begin
  Result := False;

  //  Do AccessCheck.
  oAccessRequest.DesiredAccess        := FILE_TRAVERSE;
  oAccessRequest.PrincipalSelfSid     := nil;
  oAccessRequest.ObjectTypeList       := nil;
  oAccessRequest.OptionalArguments    := nil;
  oAccessRequest.ObjectTypeListLength := 0;

  ZeroMemory(@a_nBuffer, sizeof(a_nBuffer));

  oAccessReply.ResultListLength       := 1;
  oAccessReply.GrantedAccessMask      := PACCESS_MASK(@a_nBuffer);
  oAccessReply.Error                  := PDWORD(Cardinal(@a_nBuffer) + sizeof(ACCESS_MASK));

  oPsd    := SECURITY_DESCRIPTOR(p_oPsd^);
  bResult := AuthzAccessCheckWrapper( 0,
                                      p_hAuthzClient,
                                      oAccessRequest,
                                      0,
                                      oPsd,
                                      oDescArray,
                                      0,
                                      oAccessReply,
                                      oCheckResults);
  if bResult then
    Result := True;
end;

end.

我的问题在 AuthzAccessCheckWrapper 的第 348 行

Result := AuthzAccessCheck(Flags,
                               hAuthzClientContext,
                               @pRequest,
                               hAuditEvent,
                               @pSecurityDescriptor,
                               @OptionalSecurityDescriptorArray,
                               OptionalSecurityDescriptorCount,
                               @pReply,
                               @phAccessCheckResultsOPTIONAL);

if not Result then
  nError := GetLastError;

我在哪里得到错误 87 (ERROR_INVALID_PARAMETER)

我对 Delphi 很陌生,这可能是初学者的错误,但我不知道如何解决这个问题,所以任何帮助或建议将不胜感激。

4

1 回答 1

3

如果您只想编写一个简单的函数来检索用户对文件夹或文件的权限,您可以尝试 WMI,在这种情况下,要获取逻辑文件或目录的安全设置,您可以使用Win32_LogicalFileSecuritySetting WMI 类和GetSecurityDescriptor 方法

检查此示例代码。这将检查特定用户是否有权访问文件夹(或文件)。

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  ComObj,
  Windows,
  Variants;

procedure  GetDirectoryAccess(const Path, UserName : string);
const
  WbemUser            ='';
  WbemPassword        ='';
  WbemComputer        ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  objSD         : OleVariant;
  LIndex        : Integer;
  LAccessMask   : DWORD;
  objAce        : OleVariant;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\cimv2', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.Get(Format('Win32_LogicalFileSecuritySetting="%s"', [StringReplace(Path,'\','\\', [rfReplaceAll])]));
  if FWbemObjectSet.GetSecurityDescriptor(objSD)=0 then
  for LIndex:= VarArrayLowBound(objSD.DACL,1) to VarArrayHighBound(objSD.DACL,1) do
  if SameText(UserName, objSD.DACL[LIndex].Trustee.Name) then
  begin
     objAce:=objSD.DACL[LIndex];
     Writeln(Format('Trustee  Name     %s',[objAce.Trustee.Name]));
     Writeln(Format('Trustee  Domain   %s',[objAce.Trustee.Domain]));
     Writeln(Format('Ace Flags         %d',[Integer(objAce.AceFlags)]));
     Writeln(Format('Access Mask       %d',[Integer(objAce.AccessMask)]));

     LAccessMask:=objAce.AccessMask;
      if (LAccessMask and 1048576)=1048576 then
          Writeln('  Synchronize');
      if (LAccessMask and 524288 )=524288 then
          Writeln('  Write Owner');
      if (LAccessMask and 262144)=262144 Then
          Writeln('  Write ACL');
      if (LAccessMask and 131072)=131072 Then
          Writeln('  Read Security');
      if (LAccessMask and 65536)=65536 Then
          Writeln('  Delete');
      if (LAccessMask and 256)=256 Then
          Writeln('  Write Attributes');
      if (LAccessMask and 128)=128 Then
          Writeln('  Read Attributes');
      if (LAccessMask and 64)=64 Then
          Writeln('  Delete Dir');
      if (LAccessMask and 32)=32 Then
          Writeln('  Execute');
      if (LAccessMask and 16)=16 Then
          Writeln('  Write extended attributes');
      if (LAccessMask and 8)=8 Then
          Writeln('  Read   extended attributes');
      if (LAccessMask and 4)=4 Then
          Writeln('  Append');
      if (LAccessMask and 2)=2 Then
          Writeln('  Write');
      if (LAccessMask and 1)=1 Then
          Writeln('  Read');
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      GetDirectoryAccess('c:\lazarus','RRUZ');;
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.

注意:使用 WinAPI 也没有什么问题,但是这个示例显示了使用 WMI 解决这个任务是多么容易。

于 2013-08-14T16:22:18.607 回答