AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Delphi Standard-Dialog für Zugriffsrechte in eigenen Programmen

Standard-Dialog für Zugriffsrechte in eigenen Programmen

Ein Tutorial von Ghostwalker · begonnen am 16. Feb 2007 · letzter Beitrag vom 21. Feb 2007
Antwort Antwort
Seite 1 von 2  1 2   
Ghostwalker
Registriert seit: 16. Jun 2003
So...es ist Geschafft. Teil eins ist fertig und hängt an diesem Beitrag drann. Natürlich incl. Beispiel-Code.

Das Tutorial zeigt euch die Grundlagen, wie ihr diesen Dialog nutzen könnt. In den Fortsetzungen werde ich (sofern gewünscht) auf spezielle Aspekte eingehen und einiges näher erleutern.

Feedback ist natürlich immer erwünscht
Angehängte Dateien
Dateityp: zip aclacedlg_1_329.zip (39,9 KB, 129x aufgerufen)
e=mc² or energy = milk * coffee²
 
Benutzerbild von f.siebler
f.siebler

 
Delphi 2006 Professional
 
#2
  Alt 16. Feb 2007, 11:23
hm, es online zu lesen wäre schon schön gewesen.
  Mit Zitat antworten Zitat
Ghostwalker

 
Delphi 10.3 Rio
 
#3
  Alt 16. Feb 2007, 12:42
Naja...ein Thread der über 7 DinA4-Seiten hat ?????
Uwe
  Mit Zitat antworten Zitat
Benutzerbild von f.siebler
f.siebler

 
Delphi 2006 Professional
 
#4
  Alt 16. Feb 2007, 12:48
naja, immer noch besser als "runterladen" -> "entpacken" -> "irgendwo ablegen"
denn wenn es im Forum ist taucht es in der Suche auf usw... von daher macht es schon Sinn...
  Mit Zitat antworten Zitat
Ghostwalker

 
Delphi 10.3 Rio
 
#5
  Alt 16. Feb 2007, 23:36
Na mal sehen was ich tun kann
Uwe
  Mit Zitat antworten Zitat
Alter Mann

 
Delphi 10.2 Tokyo Professional
 
#6
  Alt 17. Feb 2007, 05:15
Hi,

habe da einen kleinen Fehler...
Miniaturansicht angehängter Grafiken
filesecurity_137.jpg  
  Mit Zitat antworten Zitat
Benutzerbild von Jowo
Jowo

 
Delphi 7 Personal
 
#7
  Alt 17. Feb 2007, 08:52
Zitat:
Jetzt wollen wir mal in die Hände spuken [...]
Also mir gefällt das Tutorial. Gut gemacht.
  Mit Zitat antworten Zitat
Ghostwalker

 
Delphi 10.3 Rio
 
#8
  Alt 17. Feb 2007, 11:05
So..hier nun die Online-Variante

Zugriffsrechtedialog von Windows nutzen.
(Teil 1: Readonly-Anzeige der Dateirechte)


1. Einleitung

Wer kenn das nicht. Man ärgert sich mal wieder, das man die Rechte an einer Datei oder einem anderen Objekt des Systems nicht vom Anwender einstellen lassen kann. Es gibt natürlich einige Dialoge anderer Hersteller, mit denen man das Einbauen kann. Aber warum Fremdware nutzen wenn Windows sowas schon hat ? Ich werde hier also eine Methode vorstellen, wie man diesen Dialog von Delphi aus nutzen kann. Ich werde die Funktion der einzelnen Methoden vorstellen. An vielen Stellen werde ich aber auf die entsprechenden Eintragungen der MSDN verweisen, da hier die Informationen zu den entsprechenden API-Funktionen wesentlich besser erklärt sind.

2. Vorbereitungen

Nach langem Kampf durch die Wüste des Netzes, immer auf der Suche nach Informationen zum Thema, hab ich es dann endlich doch geschafft, den Dialog wie gewünscht anzuzeigen.Zuerstmal sollte man sich mit dem Grundlegenden Sicherheitskonzept von Windows befassen. Schließliche müssen wir es handhaben können, um dem Dialog die richtigen Informationen zu geben. Für den Einstieg in die Thematik verweise ich mal auf Luckies Tutorials. Auch MSDN bietet sehr viele Informationen zum Thema. EntsprechendeLinks findet ihr am Ende dieses Teils.Weiter brauchen wir ein Windows, das diesen Dialog natürlich zur Verfügung steht. Das ist ab Windows 2000 der Fall. Windows NT 4 hat noch eine andere Variante, die wir in einem späteren Teil besprechen. Windows 95/98/Me haben diesen Dialog nicht, das sie nur als Single-User Betriebessystem ausgelegt sind.Zur Arbeitserleichterung brauchen wir jetzt nur noch die API Deklarationen für den entsprechenden Bereich. Leider sind die von Borland bisher gelieferten ungenügend für unserer Zwecke. Aber zum Glück gibts ja das JEDI-Projekt. Dort finden wir auch eine relativ aktuelle Version der API's (Win32Api). Unter [URL =http://delphi-jedi.org]http://delphi-jedi.org[/url] finden wir unter dem Punkt "Windows 32-bit API conversions library (source)" das entsprechende Packet. Da es sich dabei um keine Komponenten handelt, können wir diese einfach per Uses aufnehemnen. Aufpassen muß man nur mit Konflikten mit den Delphi eigenen Units. Also verwendet man entweder NUR die Delphi-Units oder NUR die Jedi-Units. Damit läßt sich das meiste vermeiden. Einziger Knackpunkt, den ich bisher gefunden habe, ist der Delete-Befehl. Dieser wird in einer Jedi-Unit überlagert. Also muß ein "system." davor.

3. The Beginning

Als Beispiel für diese Tutorial hab ich mir die allgemein bekannten Dateirechte ausgesucht. Mit diesen hat jeder schon mal zu tun gehabt und man braucht dafür auch kein Netzwerk. Unser Ergebnis zum Schluss soll also wie folgt aussehen:


Der Dialog selbst kann alle nur erdenklichen Systemobjekte, die für Zugriffsrechte relevant sind, behandeln (Drucker, Netzwerkfreigaben, Registry-Schlüssel und einiges mehr.). Eigentlich ist das ganze ja kein Dialog im herkömmlichen sind. Es handelt sich eigentlich vielmehr um einen Reitertab, der vom System auch in Form eines eigenen Dialoges zur Verfügung gestellt wird. Wenn ich im Folgenden also vom Dialog spreche, meine ich diesen Reiter.

Die Anzeige des Dialogs kann über zwei Wege erfolgen. Entweder man bindet ihn direkt als Sheet in eine entsprechende Komponente ein (das folgt in einen der nächsten Teile), oder man zeigt ihn als eigenen Dialog an. Dazu dienen zwei
entsprechende API-Funktionen

Für die Sheet-Variante ist das CreateSecurityPage und für die Dialog-Variante ist das EditSecurity . Beide Varianten erwarten als Parameter ein Objekt das das ISecurityInformation Interface implementiert. Zusätzlich erwartet EditSecurity noch ein Fensterhandle, das als Elternfenster agiert. CreateSecurityPage gibt als Rückgabewert ein Handle auf ein Tabsheet zurück, EditSecurity einen Wert vom Typ boolean. Damit können wir schonmal einen ersten Schritt auf den Weg machen. Wir fangen ein neues Projekt an, mit einer einfachen Form. Darauf platzieren wir einen Button und einen Fileopen-Dialog. Hinter das onClick-Ereignis des Buttons legen wir folgende
Code-Zeilen an:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender:TObject);
var
  ai : TFileSecurityInformation1;
begin
  if OpenDialog1.execute then
  begin
    ai := TFileSecurityInformation1.create(OpenDialog1.filename);
    EditSecurity(handle,ai);
  end;
end;
Wenn wir jetzt compilieren würden, würde das nicht funktionieren. Das System kenn die Klasse TFileSecurityInformation1 noch nicht. Aber das wird sich gleich ändern.

4. Des Pudels Kern

ist in unserem Fall ein Interface mit Namen ISecurityInformation . Mit Hilfe der dort definierten Methoden, steuern wir den Dialog, bzw. erhält der Dialog die Daten und Informationen, die er für die Anzeige benötigt. Und genau dieses Interface müssen wir nun in Form einer eigenen Klasse implementieren. Aber, Step by
Step. Zuerst brauchen wir in unserem Projekt eine neue Unit. In diese holen wir uns erstmal per Uses die nötigen
Units der Jedi-Api rein. Das sind die Units
  • jwaAclUI.pas Hier findet sich die Definition des Interfaces und der API-Routinen
  • jwaWindows.pas Hier werden verschiedene Typen definiert die wir brauchen.
  • jwaAclApi.pas Hier werden weiter API-Routinen die wir brauchen, definiert.
  • JwaAccCtrl.pas Hier werden einige Konstanten für API-Routenen deklariert.

Damit haben wir schonmal alles an Bord, war wir für unsere neue Klasse brauchen. Jetzt deklarieren wir erstmal unsere Klasse.
Delphi-Quellcode:
TYPE
  TFileSecurityInformation1 = Class(TInterfacedObject,ISecurityInformation)
  private
    ffilename : Widestring;
    fpagetitle : Widestring;
  protected
    function GetAccessRights(pguidObjectType: LPGUID; dwFlags: DWORD; out ppAccess: PSI_ACCESS; out pcAccesses,piDefaultAccess: ULONG): HRESULT;stdcall;
    function GetInheritTypes(out ppInheritTypes: PSI_INHERIT_TYPE;out pcInheritTypes: ULONG): HRESULT;stdcall;
    function GetObjectInformation(out pObjectInfo: SI_OBJECT_INFO): HRESULT;stdcall;
    function GetSecurity(RequestedInformation: SECURITY_INFORMATION;out ppSecurityDescriptor: PSECURITY_DESCRIPTOR; fDefault: BOOL): HRESULT;stdcall;
    function MapGeneric(pguidObjectType: LPGUID; pAceFlags: PUCHAR;pMask: PACCESS_MASK): HRESULT;stdcall;
    function PropertySheetPageCallback(hwnd: HWND; uMsg: UINT;uPage: SI_PAGE_TYPE): HRESULT;stdcall;
    function SetSecurity(SecurityInformation: SECURITY_INFORMATION;pSecurityDescriptor: PSECURITY_DESCRIPTOR): HRESULT;stdcall;
  public
    Constructor Create(Afile:widestring);
  published
    property Filename : Widestring Read fFilename write fFilename;
    property PageTitle : widestring read fpagetitle write fpagetitle;
  end;
Damit haben wir jetzt den Rumpf, den wir brauchen. Jetzt wollen wir mal in die Hände spuken und
das Teil mit Leben füllen.


5. Im Detail
Die beiden Propertys und den Konstruktor brauch ich glaube nicht groß Beschreiben, da hier nix großes passiert. Im Konstruktor setzen wir lediglich die Property Filename und ansonsten rufen wir nur die inherited Methode auf. Das wars schon. Viel interressanter sind die anderen Methoden, die wir nun im Folgenden näher untersuchen.

a)GetObjectInformation(out pObjectInfo: SI_OBJECT_INFO): HRESULT;
Diese Methode wird vom Dialog immer dann aufgerufen, wenn er Informationen braucht, wie er sich
Darstellen und Verhalten soll. Dazu erwartet er von einen Record vom Typ SI_OBJECT_INFO, den wir hier befüllen müssen. Der Record hat folgende Felder:
  • dwFlags
    Ein Set von Bit-Flags, die dem Dialog sagen was er alles Möglich machen soll
    Dazu sind einige Konstanten definiert, die wir kombinieren können. Hier ein Auszug:
    • SI_ADVANCE Schaltet den Button "Erweitert" ein.
    • SI_READONLY Sagt dem Dialog, das wir die Daten nur anzeigen wollen.
    • SI_PAGE_TITLE Sagt dem Dialog, das wir ihm im folgenden einen Titel für den Dialog (das Sheet !) angeben.
    Es gibt noch viele weitere Flags, die hier http://msdn2.microsoft.com/en-us/library/aa379605.aspx ausführlich beschrieben sind.
  • hInstance
    Ist ein Handle auf ein Modul, aus dem sich der Dialog String-Resourcen für die Anzeige holen kann. Zusätzlich bekommt der Dialog über die Methoden GetAccessRights und GetInheritTypes weitere Strings die er zur
    Anzeige braucht. Aber dazu später mehr.
  • pszServerName
    Hier können wir dem Dialog mitteilen, wo er sich die Informationen über die Benutzer und Benutzergruppen holen soll. Achtung, wie bei allen Strings in diesem Interface muß
    es ein Unicode-String sein !!!
  • pszObjectName
    Hier geben wir das Objekt der Begierde an, dessen Rechte wir anzeigen wollen (also unsere Datei). Dieser String wird für die Anzeige von Fehlermeldungen und für die Anzeige in der Titelleiste des Dialogs (!) benutzt.
  • pszPageTitle
    Die Bezeichnung des Sheets (!).
  • guidObjectType
    GUID des Objekttypes. Ist (soweit ich weiß) nur relevant, wenn wir es mit Active-Directory-Objekten zu tun haben.

Mit diesen Informationen können wir der Methoden jetzt Leben einhauchen:
Delphi-Quellcode:
function TFilesecurityInformation1.GetObjectInformation(out pObjectInfo: SI_OBJECT_INFO):HRESULT;
begin
  ZeroMemory(@pObjectInfo,SizeOf(SI_OBJECT_INFO));
  pObjectInfo.dwFlags := SI_READONLY or SI_ADVANCED or SI_PAGE_TITLE;
  pObjectInfo.hInstance := SysInit.HInstance;
  pObjectInfo.pszObjectName := pwidechar(ffilename);
  pObjectInfo.pszPageTitle := pwidechar(fpagetitle);
  Result := S_OK;
end;
b) GetAccessRights(pguidObjectType: LPGUID; dwFlags: DWORD;out ppAccess: PSI_ACCESS; out pcAccesses, piDefaultAccess: ULONG): HRESULT;
Diese Methode wird immer dann vom Dialog aufgerufen, wenn er wissen will, welche Rechte mit welchen Bezeichnungen er anzeigen soll.
  • pguidObjectType
    Genau wie unter a) eine GUID, für den Objekttyp.
  • dwFlags
    Hier gibt uns der Dialog u.U. an, in welchem Initialisierungsstatus er gerade ist. Wenn hier ein Wert gesetzt ist, kann er mit folgenden Konstanten ausgelesen werden:
    • SI_ADVANCED Der Dialog wird initalisiert.
    • SI_EDIT_AUDITS Der Dialog enthält die Möglichkeit zum editieren der AUDITS
    • SI_EDIT_PROPERTIES Der Dialog enthält die Möglichkeit ACE's zu bearbeiten.
  • ppAccess
    Ein Zeiger auf ein Array (0-basiert !) mit SI_ACCESS-Strukturen. Hierüber geben wir
    dem Dialog an, welche Rechte mit welchen Texten angezeigt werden sollen.
  • pcAccesses
    Gibt die Anzahl der Elemente in unserem Array an, damit der Dialog auch weiß wie lang das array ist.
  • piDefaultAccess
    Sagt dem Dialog, welches Recht das "Default"-Recht ist, wenn er einen neuen ACE anlegen will.
    Da die Dateirechte immer gleich sind und sich eher selten ändern, haben wir uns im Vorfeld schonmal folgendes Konstantenarray angelegt, das wir hier nur noch übergeben müssen:

    Delphi-Quellcode:
    CONST
      //Die NULL-GUID
      GUID_NULL: TGUID = '{00000000-0000-0000-0000-000000000000}';
      //erstmal die ganzen Bezeichnungen
      IDS_FILE_ADD_FILE = 'Datei zu Verzeichnis hinzufügen';
      IDS_FILE_ADD_SUBDIRECTORY = 'Unterverzeichnis zu Verzeichnis hinzufügen';
      IDS_FILE_ALL_ACCESS = 'Alle Rechte';
      IDS_FILE_APPEND_DATA = 'Daten zu Datei hinzufügen';
      IDS_FILE_DELETE_CHILD = 'Löschen eines Unterverzeichnisses mit seinen Dateien';
      IDS_FILE_EXECUTE = 'Datei ausführen';
      IDS_FILE_LIST_DIRECTORY = 'Verzeichnis anzeigen';
      IDS_FILE_READ_ATTRIBUTES = 'Attribute lesen';
      IDS_FILE_READ_DATA = 'Datei lesen';
      IDS_FILE_READ_EA = 'Erweiterte Attribute lesen';
      IDS_FILE_WRITE_ATTRIBUTES = 'Attribute speichern/ändern';
      IDS_FILE_WRITE_DATA = 'Daten schreiben';
      IDS_FILE_WRITE_EA = 'Erweiterte Attribute speichern/ändern';
      IDS_STANDARD_RIGHTS_READ = 'Standard Leserechte';
      IDS_STANDARD_RIGHTS_WRITE = 'Standard Schreibrechte';
      
      FileAccessRights:array[0..14] of SI_ACCESS=(
        (pguid: @GUID_NULL;
        mask: FILE_ADD_FILE;
        pszName:IDS_FILE_ADD_FILE;
        dwFlags: SI_ACCESS_SPECIFIC
        ),
        (pguid: @GUID_NULL;
        mask: FILE_ADD_SUBDIRECTORY;
        pszName:IDS_FILE_ADD_SUBDIRECTORY;
        dwFlags: SI_ACCESS_SPECIFIC
        ),
        (pguid: @GUID_NULL;
        mask: FILE_ALL_ACCESS;
        pszName:IDS_FILE_ALL_ACCESS;
        dwFlags: SI_ACCESS_GENERAL
        ),
        (pguid: @GUID_NULL;
        mask: FILE_APPEND_DATA;
        pszName:IDS_FILE_APPEND_DATA;
        dwFlags: SI_ACCESS_SPECIFIC
        ),
        (pguid: @GUID_NULL;
        mask: FILE_DELETE_CHILD;
        pszName:IDS_FILE_DELETE_CHILD;
        dwFlags: SI_ACCESS_SPECIFIC
        ),
        (pguid: @GUID_NULL;
        mask: FILE_EXECUTE;
        pszName:IDS_FILE_EXECUTE;
        dwFlags: SI_ACCESS_GENERAL
        ),
        (pguid: @GUID_NULL;
        mask: FILE_LIST_DIRECTORY;
        pszName:IDS_FILE_LIST_DIRECTORY;
        dwFlags: SI_ACCESS_SPECIFIC
        ),
        (pguid: @GUID_NULL;
        mask: FILE_READ_ATTRIBUTES;
        pszName:IDS_FILE_READ_ATTRIBUTES;
        dwFlags: SI_ACCESS_GENERAL
        ),
        (pguid: @GUID_NULL;
        mask: FILE_READ_DATA;
        pszName:IDS_FILE_READ_DATA;
        dwFlags: SI_ACCESS_GENERAL
        ),
        (pguid: @GUID_NULL;
        mask: FILE_READ_EA;
        pszName:IDS_FILE_READ_EA;
        dwFlags: SI_ACCESS_SPECIFIC
        ),
        (pguid: @GUID_NULL;
        mask: FILE_WRITE_ATTRIBUTES;
        pszName:IDS_FILE_WRITE_ATTRIBUTES;
        dwFlags: SI_ACCESS_GENERAL
        ),
        (pguid: @GUID_NULL;
        mask: FILE_WRITE_DATA;
        pszName:IDS_FILE_WRITE_DATA;
        dwFlags: SI_ACCESS_GENERAL
        ),
        (pguid: @GUID_NULL;
        mask: FILE_WRITE_EA;
        pszName:IDS_FILE_WRITE_EA;
        dwFlags: SI_ACCESS_SPECIFIC
        ),
        (pguid: @GUID_NULL;
        mask: STANDARD_RIGHTS_READ;
        pszName:IDS_STANDARD_RIGHTS_READ;
        dwFlags: SI_ACCESS_GENERAL
        ),
        (pguid: @GUID_NULL;
        mask: STANDARD_RIGHTS_WRITE;
        pszName:IDS_STANDARD_RIGHTS_WRITE;
        dwFlags: SI_ACCESS_GENERAL
        )
      );

Viel Text, ich hoffe das erschlägt euch nicht gleich . Schauen wir uns mal kurz die Elemente eines SI_ACCESS-Records an.
  • pguid
    Wieder die GUID, die uns in unserem Beispiel nicht wirklich interresiert, daher GUID_NULL.
  • mask
    Die Zugriffsrechte (als ACCESS_MASK), die wir mit dem folgenden Namen beschreiben.
  • pszName
    Wie der Bezeichner schon vermuten läßt, die Bezeichnung für die Zugriffsmaske
  • dwFlags
    Wiedermal ein Set von Bitflags, die das Zugriffsrecht. Hier die beiden wichtigsten:
    • SI_ACCESS_SPECIFIC Sagt aus, das das Zugriffsrecht auf der Erweiterten Seite auftaucht.
    • SI_ACCESS_GENERAL Sagt aus, das das Zugriffsrecht auf der einfachen Seite auftaucht

Damit haben wir eigentlich alles zusammen, um die Methode zum leben zu erwecken. Das sieht dann so aus:
Delphi-Quellcode:
function TFilesecurityInformation1.GetAccessRights(pguidObjectType: LPGUID; dwFlags: DWORD;
  out ppAccess: PSI_ACCESS; out pcAccesses, piDefaultAccess: ULONG): HRESULT;
begin
  ppAccess := @FileAccessRights[0];
  pcAccesses := 15;
  piDefaultAccess := 0;
  Result := S_OK;
end;
So..weiter im Text mit der nächsten Methode

c) function GetInheritTypes(out ppInheritTypes: PSI_INHERIT_TYPE;out pcInheritTypes: ULONG): HRESULT;stdcall;
Diese Methode wird vom Dialog aufgerufen, wenn er etwas über die "Vererbung" der Rechte an Untergeordnete Objekte wissen will. Da diese Thema nicht ganz einfach ist, und den Rahmen dieses Tutorials sprengen würde, verweise ich am Ende des Tuts auf einige Seiten, die euch mehr Informationen liefern. An dieser Stelle definieren wir uns wieder ein Konstanten-Array, da auch diese Teile sicher eher selten ändern.

Delphi-Quellcode:
CONST
  IDS_THISFILE_ONLY = 'Nur diese Datei/dieses Verzeichnis';
  IDS_THISANDSUB = 'Diese Datei/Verzeichnis und Unterverzeichnisse';
  IDS_ONLY_SUBS = 'Nur Unterverzeichnisse';

  FileInheritTypes: array [0..2] of SI_INHERIT_TYPE = (
    (pguid:@GUID_NULL;
    dwFlags: 0;
    pszName:IDS_THISFILE_ONLY;
    ),
    (
    pguid:@GUID_NULL;
    dwFlags:CONTAINER_INHERIT_ACE;
    pszName:IDS_THISANDSUB;
    ),
    (
    pguid:@GUID_NULL;
    dwFlags:INHERIT_ONLY_ACE or CONTAINER_INHERIT_ACE;
    pszName:IDS_ONLY_SUBS;
    )
  );
Wie ihr seht, ist der Record ganz ähnlich aufgebaut, wie SI_ACCESS. Nur die Flags haben hier eine andere Bedeutung. Sie geben die Art der Vererbung an. Die IDS_-Konstanten sind wieder Strings für die Bezeichnungen. Damit können wir dann auch die Methode implementieren, was so aussieht:

Delphi-Quellcode:
function TFilesecurityInformation1.GetInheritTypes(out ppInheritTypes: PSI_INHERIT_TYPE;out pcInheritTypes: ULONG): HRESULT;
begin
  ppInheritTypes := @FileInheritTypes;
  pcInheritTypes := 3;
  Result := S_OK;
end;
Langsam kommt Land in Sicht. Nicht mehr lange und wir können unseren Dialog in aller Pracht bewundernt

d)MapGeneric(pguidObjectType: LPGUID; pAceFlags: PUCHAR;pMask: PACCESS_MASK): HRESULT;

Es gibt unter Windows sog. generische Zugriffsrechte. Das heißt nix anderes, als das sie unabhängig vom eigentlichen Objekt sind und sozusagen global vorhanden sind. Damit Windows, und damit der Dialog, weiß, welches unserer Zugriffsrechte welchem generischen Recht entspricht, müssen wir diese Methode befüllen. Der Einfachheit halber, definieren wir uns auch hier wieder ein Konstanten-Array, das wie folgt aussieht:
Delphi-Quellcode:
CONST
  FileMaping : GENERIC_MAPPING=(
    GenericRead: FILE_READ_DATA;
    GenericWrite: FILE_WRITE_DATA;
    GenericExecute:FILE_EXECUTE;
    GenericAll: FILE_ALL_ACCESS
  );
Wie ihr seht, nix dramatisches. Und nun die entsprechende Methode dazu:

Delphi-Quellcode:
function TFilesecurityInformation1.MapGeneric(pguidObjectType: LPGUID; pAceFlags: PUCHAR;pMask: PACCESS_MASK): HRESULT;
var
  maping : GENERIC_MAPING;
begin
  maping := FileMaping;
  MapGenericMask(pMask^,maping);
  pMask^ := pMask^ and (not SYNCHRONIZE);
  Result := S_OK;
end;
MapGenericMask ist eine API Routine, die uns die Zuweisung übernimmt.

e)GetSecurity(RequestedInformation: SECURITY_INFORMATION;out ppSecurityDescriptor: PSECURITY_DESCRIPTOR; fDefault: BOOL): HRESULT;

Sodale, das ist nun die letzte, für unser Beispiel wichtige, Methode. Sie wird vom Dialog immer dann aufgerufen, wenn er die vorhanden Zugriffsrechte des jeweiligen Objektes (in unserem Beispiel der Datei) benötigt. Da Luckie schon sehr gut beschrieben hat, wie man diese Information dem System entlocken kann, kürze ich das hier ab und stelle euch gleich die fertige Methode vor:

Delphi-Quellcode:
function TFilesecurityInformation1.GetSecurity(RequestedInformation: SECURITY_INFORMATION;
  out ppSecurityDescriptor: PSECURITY_DESCRIPTOR; fDefault: BOOL): HRESULT;
var
  POWNER,POTHER : PPSID;
  PDACL,PSACL : PPACL;
begin
  RESULT := E_FAIL;
  POWNER := NIL;
  POTHER := NIL;
  PDACL := NIL;
  PSACL := NIL;
  if (GetNamedSecurityInfow(pwidechar(ffilename),
      SE_FILE_OBJECT,RequestedInformation,powner,pother,pdacl,psacl,ppSecurityDescriptor)=0) then
    RESULT := S_OK;
end;
Über den Parameter RequestedInformation sagt uns der Dialog, was er den nun wissen will. Diesen können wir direkt an die API-Routine übergeben, die uns, hoffentlich, die Infos im SecurityDescriptor zurück gibt.

f)SetSecurity(SecurityInformation: SECURITY_INFORMATION;pSecurityDescriptor: PSECURITY_DESCRIPTOR): HRESULT;

Diese Methode wird immer dann vom Dialog aufgerufen, wenn der Benutzer etwas an den Rechten geändert hat, und diese dem Objekt zugewiesen werden müssen. Da wir hier nur die Rechte Anzeigen wollen, geben wir einfach S_OK als Result zurück.

g)PropertySheetPageCallback(hwnd: HWND; uMsg: UINT;uPage: SI_PAGE_TYPE): HRESULT;

Wird immer dann aufgerufen, wenn eine Eigenschaftsseite erzeugt oder freigegeben wird. uMSG gibt dabei an, was grad der Fall ist (Erzeugen, Freigeben, Initialisieren). hwnd gibt das Handle auf die Eigenschaftsseite an (nur im Falle von Initialisieren, ansonsten ist das 0) und uPage sagt uns, um welchen Eigenschaftsseitentyp es sich handelt (Standard, Erweitert usw..). Für unser Beispiel brauchen wir auch das nicht. Also geben wir als Result einfach nur S_OK zurück (oder zu bayrisch "Bast scho").


6. The End

Ja, es ist viel Tipp-Arbeit. Aber, wie ich finde, die Arbeit lohnt sich. Zumal das ganze sich sehr flexibel einsetzen läßt. Nach dem ihr das ganze jetzt gespeichert habt, und entsprechend ins Testprojekt eingebunden habt, können wir das ganze jetzt compilieren und starten. Nach einem Klick auf den Button und der Auswahl einer Datei, sollte der Dialog auftauchen.

7. Links zum Thema

http://www.michael-puff.de
Hat zwei sehr gute Artikel (06/2006) die einige Grundlagen erklären

http://www.codeproject.com/win32/accessctrl1.asp
Eine sehr gute Artikelreihe (Englisch), die das Sicherheitskonzept von Windows recht gut erklärt. Schade das die Codeschnippsel für C++ sind.

http://msdn.microsoft.com
Tja..wer kennt sich besser aus als MS ? Neben den Beschreibungen der API-Funktionen und Interfaces findet ihr im englischsprachigen Bereich auch einige Artikel (als Suchbegriff einfach mal "Keith Brown" eingeben), die sich mit verschiedenen Aspekten des Sicherheitskonzepts befassen.

So..das war es für den 1. Teil. Ich hoffe es bringt euch ein wenig weiter und stiftet euch zu eigenen Experimenten an.

Euer
Ghostwalker (aka Uwe Rupprecht)
Angehängte Dateien
Dateityp: zip filesecurity_174.zip (1,9 KB, 47x aufgerufen)
Uwe
  Mit Zitat antworten Zitat
Alter Mann

 
Delphi 10.2 Tokyo Professional
 
#9
  Alt 18. Feb 2007, 19:18
Hallo,

warum wird auf die Fehlermeldung nicht eingegangen?

Ich finde den Artikel ganz gut, auch wenn für die Freigabe der Unicode-Strings in SI_OBJECT_INFO
andere Quellen bemüht werden müssen(sind ja nur kleine Fallstricke).

Gruss
  Mit Zitat antworten Zitat
Ghostwalker

 
Delphi 10.3 Rio
 
#10
  Alt 18. Feb 2007, 22:42
Guggst du. Ich habe an die Online-Variante eine aktualisierte Version der PAS-Datei angehängt. Da ist der Fehler behoben.
Uwe
  Mit Zitat antworten Zitat
Themen-Optionen Tutorial durchsuchen
Tutorial durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:52 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz