Autor Beitrag
Ares
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 128



BeitragVerfasst: Di 12.10.10 14:09 
Hallo!

Gibt es eine zuverlässige Möglichkeit zu prüfen ob das laufende Programm über die Zugriffsrechte für einen bestimmten Ordne oder eine Datei verfügt?

Der Hintergrund ist, dass ein Programm auf eine Systemdatei zugriffen soll für die Admin-Rechte notwendig sind. Wird das Programm mit User-Rechten gestartet und versucht die Datei in einem Stream zu öffnen führt dies zu einer Exception EFOpenError.

Wird das Programm hingegen mit Admin-Rechten gestartet gelingt der Zugriff. Dies gilt aber nur, wenn die Datei nicht in Verwendung ist. Dann scheitert der Zugriff ebenfalls mit der Exception EFOpenError.

An der Exception alleine kann ich also nur erkennen, dass der Zugriff gescheitert ist, aber nicht warum. Allerdings lautet die Nachricht der Exeption in beiden Fällen anders. Im ersten Fall wird "Zugriff Verweigert" angegeben und im zweiten "Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird".

Eine Unterscheidung wäre also möglich, der Meldungstext ist nicht wirklich zuverlässig und würde unter einem indischen Windows wohl anders lauten. Eine andere Methode die beiden Exceptions zu unterscheiden konnte ich bislang nicht erkennen. Gibt es also eine Funktion HabIchZugriffsrechte(Datei.xyz) die mir sagt ob der Zugriff an mangelnden Rechten scheitert?
Tropby
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 71
Erhaltene Danke: 4

Vista, Win XP, Win 89
Turbo Delphi Ex.
BeitragVerfasst: Di 12.10.10 14:14 
Hallo,

das Thema hatten wir gerade in einem anderem zusammenhang so der 4. oder 5. Post geht auf das Thema ein.

www.delphi-forum.de/viewtopic.php?t=102011

user profile iconjaenicke
Zitat:

Es gibt da ab XP eine viel viel einfachere Möglichkeit schon im System. Die Funktion IsUserAnAdmin nämlich...msdn.microsoft.com/e...bb776463(VS.85).aspx
Die funktioniert auch mit UAC usw. korrekt.

_________________
Tropby
Ares Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 128



BeitragVerfasst: Di 12.10.10 14:18 
Hallo!

Vielen Dank für die Info. Das Problem tritt aber nicht nur auf, wenn die AdminRechte fehlen. Ist eine Datei nur für UserA freigegeben kann das Programm das mit UserB Rechten läuft nicht auf die Datei zugreifen. Das UserA und UserB beides keine Admins sind, hat darauf keinen Einfluss.
Tropby
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 71
Erhaltene Danke: 4

Vista, Win XP, Win 89
Turbo Delphi Ex.
BeitragVerfasst: Di 12.10.10 14:27 
Dafür habe ich mal eine Funktion gefunden. Aber habe das damals dann anders gelöst.

Ich weiß noch nichtmal ob die Funktion so läuft.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
function CheckAccessRights(const UserName, Filename: string): ACCESS_MASK;
var
  DACL: PACL;
  SecDesc: PSECURITY_DESCRIPTOR;
  User: TRUSTEE;
  ActualUser: string;
begin
  DACL := nil;
  SecDesc := nil;
  Win32Check(GetNamedSecurityInfo(PChar(FileName), SE_FILE_OBJECT,
    DACL_SECURITY_INFORMATION,
    nilnil, @DACL, nil, SecDesc) = ERROR_SUCCESS);
  try
    if Assigned(DACL) then
      begin
        FillChar(User, SizeOf(User), 0);
        User.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
        User.TrusteeForm := TRUSTEE_IS_NAME;
        User.TrusteeType := TRUSTEE_IS_USER;
        if Length(UserName) > 0 then
          ActualUser := PChar(UserName)
        else
          ActualUser := PChar(LoggedOnUser);
        User.ptstrName := PChar(ActualUser);
        Win32Check(GetEffectiveRightsFromAcl(DACL^, User, Result) =
ERROR_SUCCESS);
      end
    else
      Result := 0;
  finally
    Win32Check(LocalFree(Cardinal(SecDesc)) = 0);
  end;
end;

{
Instead of Win32Check, try this:

procedure SecurityCheck(ErrCode: DWord);
begin
  if ErrCode <> Error_Success then RaiseLastOSError(ErrCode);
end;


If your version of Delphi doesn't have a one-argument RaiseLastOSError, then implement it like this:

procedure RaiseLastOSError(ErrCode: DWord);
begin
  SetLastError(ErrCode);
  SysUtils.RaiseLastOSError;
end;
}

_________________
Tropby