如何检查特定用户是否对Delphi中的文件夹/文件具有特定的访问权限

时间:2013-08-14 13:22:32

标签: delphi winapi delphi-xe3

我正在尝试编写一个函数,告诉我特定用户是否对文件夹具有特定权限。到目前为止,我已经找到了一个如何执行此操作的示例here所以我尝试在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很新,这可能是一个初学者的错误,但我不知道如何解决这个问题,所以任何帮助或建议将不胜感激。

1 个答案:

答案 0 :(得分:3)

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

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

{$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解决此任务的难易程度。