Einzelnen Beitrag anzeigen

Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#1

Schreibrechte einer Datei überprüfen

  Alt 13. Okt 2006, 16:23
Luckie zeigt hier anhand von Nicos Code, wie es möglich ist, herauszufinden, ob man Schreibrechte in einer bestimmten Datei besitzt.

Delphi-Quellcode:
// stuff Delphi might not know...
const
  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;
  (**)

function CheckAccessToFile(DesiredAccess: DWORD; const FileName: WideString): Boolean;
const
  GenericFileMapping : TGenericMapping = (
    GenericRead: FILE_GENERIC_READ;
    GenericWrite: FILE_GENERIC_WRITE;
    GenericExecute: FILE_GENERIC_EXECUTE;
    GenericAll: FILE_ALL_ACCESS
    );
var
  LastError : DWORD;
  LengthNeeded : DWORD;
  SecurityDescriptor : PSecurityDescriptor;
  ClientToken : THandle;
  AccessMask : DWORD;
  PrivilegeSet : TPrivilegeSet;
  PrivilegeSetLength : DWORD;
  GrantedAccess : DWORD;
  AccessStatus : BOOL;
begin
  Result := False;
  LastError := GetLastError;
  if not GetFileSecurityW(PWideChar(FileName), OWNER_SECURITY_INFORMATION or
    GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION, nil, 0,
    LengthNeeded) and (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then
    Exit;
  SetLastError(LastError);
  Inc(LengthNeeded, $1000);
  SecurityDescriptor := PSecurityDescriptor(LocalAlloc(LPTR, LengthNeeded));
  if not Assigned(SecurityDescriptor) then
    Exit;
  try
    if not GetFileSecurityW(PWideChar(FileName), OWNER_SECURITY_INFORMATION or
      GROUP_SECURITY_INFORMATION or DACL_SECURITY_INFORMATION,
      SecurityDescriptor, LengthNeeded, LengthNeeded) then
      Exit;
    if not ImpersonateSelf(SecurityImpersonation) then
      Exit;
    try
      if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY or
        TOKEN_IMPERSONATE or TOKEN_DUPLICATE, False, ClientToken) then
        Exit;
      try
        AccessMask := DesiredAccess;
        MapGenericMask(AccessMask, GenericFileMapping);
        PrivilegeSetLength := SizeOf(TPrivilegeSet);
        if AccessCheck(SecurityDescriptor, ClientToken, AccessMask,
          GenericFileMapping, PrivilegeSet, PrivilegeSetLength, GrantedAccess,
          AccessStatus) then
          Result := AccessStatus;
      finally
        CloseHandle(ClientToken);
      end;
    finally
      RevertToSelf;
    end;
  finally
    LocalFree(HLOCAL(SecurityDescriptor));
  end;
end;
Ein Beispielaufruf wäre folgender:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    ShowMessage(BoolToStr(
      CheckAccessToFile(GENERIC_WRITE, // check for generic write access
      OpenDialog1.FileName), True) + ': ' + SysErrorMessage(GetLastError));
end;
  Mit Zitat antworten Zitat