AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Prism File Owner mittels GetNamedSecurityInfo - Hilfe!
Thema durchsuchen
Ansicht
Themen-Optionen

File Owner mittels GetNamedSecurityInfo - Hilfe!

Ein Thema von FragKing · begonnen am 22. Mai 2005 · letzter Beitrag vom 30. Mai 2005
Antwort Antwort
Seite 1 von 2  1 2      
FragKing

Registriert seit: 21. Mai 2005
Ort: Zurich, Switzerland
5 Beiträge
 
Delphi 2005 Architect
 
#1

File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 22. Mai 2005, 16:14
Hi Leute!

Ich bin ziemlich "frisch" mit Delphi am herumtüfteln und werkeln. Es funktioniert soweit ganz gut, ist wirklich einfach das zeugs...
Nur habe ich jetzt etwas was weder mit Delphi selber noch mit dem .net Framework implementiert ist (Im .net v2.0 wirds dann drin sein hab ich gelesen

Und zwar geht es darum den Owner eines files herauszufinden, und zwar benötige ich eigentlich nur die SID, Domain&Account wären dann noch zusatz-gimmicks.
Das ganze mache ich laut Platform SDK mittels des Win32 API calls "GetNamedSecurityInfo" (MSDN).

Ich habe bereits zahlreiche newsgroups / foren durchkämmt, habe aber entweder nur Delphi für Win32 solutions gefunden (mit GetMem FreeMem calls etc -> nicht .net kompatibel) oder dann nur für andere Sprachen (z.b. hier). Ich habe das ganze mal soweit zusammengestiefelt dass ich (zumindest dachte) es sollte funktionieren, tut es aber nicht

Für ein funktionierendes Beispiel wäre ich sehr dankbar, und mit einigen erläuterungen verstehe ich das nachher hoffentlich auch noch

Danke schonmal im voraus!

Hier der Code:

Delphi-Quellcode:
unit Unit1;

{$UNSAFECODE ON}
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, System.Text;

  type
  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
  );

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

function GetNamedSecurityInfo(var pObjectName: String; const ObjectType: SE_OBJECT_TYPE; const SecurityInfo: SECURITY_INFORMATION; ppsidOwner: PSID; ppsidGroup: IntPtr; ppDacl: IntPtr; ppSacl: IntPtr; ppSecurityDescriptor: PSecurity_Descriptor): Integer; cdecl; unsafe;

var
  Form1: TForm1;

implementation

const advapi32 = 'advapi32.dll';

function GetNamedSecurityInfo(var pObjectName: String; const ObjectType: SE_OBJECT_TYPE; const SecurityInfo: SECURITY_INFORMATION; ppsidOwner: PSID; ppsidGroup: IntPtr; ppDacl: IntPtr; ppSacl: IntPtr; ppSecurityDescriptor: PSecurity_Descriptor): Integer; cdecl; unsafe;
external advapi32 name 'GetNamedSecurityInfo';

{$R *.nfm}

procedure TForm1.FormCreate(Sender: TObject); unsafe;
var ssid: PSID;
    user, domainname: string;
    acctype: IntPtr;
    blah: DWORD;
    dir: String;
    dirchar: Char;
    stringsid: String;
    error: Integer;

    sspointer: PSecurity_Descriptor;
begin
dir := ('c:\Test.txt');
error := GetNamedSecurityInfo(dir, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, ssid, nil, nil, nil, sspointer);

if error <> 0 then
ShowMessage(SysErrorMessage(error));
ShowMessage(SysErrorMessage(System.Runtime.InteropServices.Marshal.GetLastWin32Error));

ShowMessage(ssid.ToString);

end;

end.
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#2

Re: File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 23. Mai 2005, 05:40
Autsch, woher hast du denn den obigen Prototypen?
Code:
function GetNamedSecurityInfoA( [color=red]pObjectName: PWideChar[/color]; ObjectType: SE_OBJECT_TYPE; SecurityInfo: SECURITY_INFORMATION; [color=red]var[/color] ppsidOwner: PSID; [color=red]var[/color] ppsidGroup: PSID; [color=red]var[/color] ppDacl: PACL; [color=red]var[/color] ppSacl: PACL; [color=red]var[/color] ppSecurityDescriptor: PSecurity_Descriptor): DWORD; [color=red]stdcall;[/color] external 'Advapi32.dll';

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';
Wenn PACL bei dir nicht definiert ist, benutzt du einfach Pointer oder einen untypisierten Pointertypen - keine Ahnung was das bei Delphi.NET ist.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

Re: File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 23. Mai 2005, 06:05
Du hast den Beitrag mit .NET gekennzeichnet, bist du sicher dass das richtig war? Das was du da gepsotet hast, sieht mir mehr nach einem herkömlichen Win32 Delphi Programm aus.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#4

Re: File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 23. Mai 2005, 06:07
Zitat von Luckie:
Du hast den Beitrag mit .NET gekennzeichnet, bist du sicher dass das richtig war? Das was du da gepsotet hast, sieht mir mehr nach einem herkömlichen Win32 Delphi Programm aus.
Ich denke das war schon korrekt. Er will mit Delphi.NET auf Win32-APIs zugreifen:

Delphi-Quellcode:
ShowMessage(SysErrorMessage(error));
ShowMessage(SysErrorMessage(System.Runtime.InteropServices.Marshal.GetLastWin32Error));
Und dann die vielen Stellen mit "unsafe". Also das kenne ich vom traditionellen Delphi her nicht.
  Mit Zitat antworten Zitat
FragKing

Registriert seit: 21. Mai 2005
Ort: Zurich, Switzerland
5 Beiträge
 
Delphi 2005 Architect
 
#5

Re: File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 23. Mai 2005, 08:33
Nein, es ist schon korrekt dass es Delphi.NET ist.
Ich möchte wie Olli sagt von Delphi.NET her auf Win32-API's zugreiffen.

Der Prototyp ist von mir. Habe viel hin und her geübt mit dem ding
Ich probiere deinen Vorschlag so schnell wie möglich, danke! Werd mich melden ob's geklappt hat.

Grüsse
Michel
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#6

Re: File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 23. Mai 2005, 08:44
Zitat von FragKing:
Der Prototyp ist von mir. Habe viel hin und her geübt mit dem ding
Ich probiere deinen Vorschlag so schnell wie möglich, danke! Werd mich melden ob's geklappt hat.
Na dann noch ein paar Hinweise. Guck mal hier.

Wenn man einen Pointer auf eine Struktur hat (PStruktur = ^TStruktur) kann man C
Code:
void bla(PStruktur x);
nach Delphi
Code:
procedure bla(var x:TStruktur);
oder
Code:
procedure bla(x:PStruktur);
übersetzen. Entsprechend ergibt sich für den Pointer auf den Pointer auf eine Struktur (Dopplung beachten) von C
Code:
void bla(PStruktur *x);
in Delphi
Code:
procedure bla(var x:PStruktur);
oder, wenn PPStruktur = ^PStruktur, dann
Code:
procedure bla(x:PPStruktur);
.

Hoffe du siehst dabei durch. Obige Vorkommen von var können auch durch const oder out ersetzt werden, wenn dies Sinn macht. Es ist nur wichtig zu verstehen, daß bei var, const und out unter Delphi die Übergabe "by reference" (also als Pointer auf übergebenen Typ) geschieht. Hingegen in den Win32-C/C++-Headern ist OUT nur ein "leeres" Makro, welches als Anhaltspunkt für den Programmierer dient.

Ach ja: alle WINAPIs sind in stdcall. Alle klingt etwas übertrieben (ist es auch), aber bis auf wenige dokumentierte Ausnahmen (meist C-Lib oder ähnliche Funktionen), sind alle stdcall, nicht cdecl!
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#7

Re: File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 23. Mai 2005, 13:02
Kennst du den Reflector? Sau geiles Teil.
Du nimmst deinen C#/Delphi.Net/Chrome/Eifel/whatsoever - Samplecode und kompostierst ihn auch in dem Compiler.
Die entstandene Assembly jagst du durch den Reflector und wählst deine Sprache ala Darstellung aus.
*Fump* Schon findest du den Cod ein deiner Sprache...

Der Beispielcode bei P/Invoke ist übrigens falsch, da ihre Version von xxx mit einem anderen Typen für den pSid-Parameter arbeitet. Dieses hier geht.

Ich habe es einfach in eine neue C#-ClassLib kopiert, ein wenig rum-ReSharpert (damit man es auch lesen kann ) und kompiliert.
Code:
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace FileOwnerDings
{
    public class SecurityDescriptor
    {
        [DllImport("advapi32.dll", SetLastError=true)]
        static extern int GetNamedSecurityInfo(string pObjectName,
                                               SeObjectType ObjectType,
                                               SecurityInformation SecurityInfo,
                                               out IntPtr ppsidOwner,
                                               out IntPtr ppsidGroup,
                                               out IntPtr ppDacl,
                                               out IntPtr ppSacl,
                                               out IntPtr ppSecurityDescriptor);

        [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        static extern int LookupAccountSid(string systemName,
                                           IntPtr psid,
                                           StringBuilder accountName,
                                           ref int cbAccount,
                                           [Out] StringBuilder domainName,
                                           ref int cbDomainName,
                                           out int use);

        public static string GetFileObjectOwner(string objectName)
        {
            IntPtr pZero = IntPtr.Zero;
            IntPtr pSid = pZero;
            IntPtr psd = pZero; // Not used here
            int errorReturn = GetNamedSecurityInfo(objectName,
                                                   SeObjectType.FileObject,
                                                   SecurityInformation.Owner,
                                                   out pSid,
                                                   out pZero,
                                                   out pZero,
                                                   out pZero,
                                                   out psd);
            if (errorReturn != 0)
            {
                throw new Exception(string.Format("GetNamedSecurityInfo has exited with code {0}. (last error is {0})",
                                                  errorReturn,
                                                  Marshal.GetLastWin32Error()));
            }
            int bufferSize = 64;
            StringBuilder buffer = new StringBuilder();
            int accounLength = bufferSize;
            int domainLength = bufferSize;
            int sidNameUse = 0;
            StringBuilder account = new StringBuilder(bufferSize);
            StringBuilder domain = new StringBuilder(bufferSize);
            errorReturn = LookupAccountSid(null,
                                           pSid,
                                           account,
                                           ref accounLength,
                                           domain,
                                           ref domainLength,
                                           out sidNameUse);
            if (errorReturn == 0)
            {
                throw new Exception(string.Format("LookupAccountSid has exited with code 0. (last error is {0})",
                                                  Marshal.GetLastWin32Error()));
            }
            buffer.Append(domain);
            buffer.Append(@"\");
            buffer.Append(account);
            return buffer.ToString();
        }
    }
}
Die Enums:
Code:
    [Flags]
    public enum SecurityInformation
    {
        Owner = 1,
        Group = 2,
        DACL = 4,
        SACL = 8
    }
Code:
   public enum SeObjectType
    {
        UnknownObjectType = 0,
        FileObject,
        Service,
        Printer,
        RegistryKey,
        LMShare,
        KernelObject,
        WindowObject,
        DsObject,
        DsObjectAll,
        ProviderDefinedObject,
        WMIGUIDObject,
        RegistryWOW64Key
    }
Mangels eines Delphi.Net Komposters nahm ich das Chrome PlugIn für den Reflector und ieß mir Chrome Code erzeugen. (Ist ja sehr ähnlich zu Delphi.Net)
Nachdem ich die lokalen Variablen umbenannt habe (DIe werden von der IL nicht wirklich benannt ) und auch hier einen Formatter drüberrennen ließ, sah es so aus:

Delphi-Quellcode:
namespace FileOwnerDings;

interface
uses
   System,
   System.Runtime.InteropServices,
   System.Text;

type
  SecurityDescriptor = public class
  private
    [DllImport('advapi32.dll', SetLastError := True)]
    class method GetNamedSecurityInfo(pObjectName: string;
                                      ObjectType: SeObjectType;
                                      SecurityInfo: SecurityInformation;
                                      out ppsidOwner,
                                          ppsidGroup,
                                          ppDacl,
                                          ppSacl,
                                          ppSecurityDescriptor: IntPtr): Integer; external;
    [DllImport('advapi32.dll', CharSet := CharSet.Auto, SetLastError := True)]
    class method LookupAccountSid(systemName: string;
                                   psid: IntPtr;
                                   accountName: StringBuilder;
                                   var cbAccount: Integer;
                                   [&Out] domainName: StringBuilder;
                                   var cbDomainName: Integer;
                                   out use: Integer): Integer; external;
  public
    class method GetFileObjectOwner(objectName: string): string;
  end;


implementation

class method SecurityDescriptor.GetFileObjectOwner(objectName: string): string;
var
  pZero, pSid, psd : IntPtr;
  errorReturn : Integer;
  bufferSize : Integer;
  accountLength : Integer;
  domainLength : Integer;
  sidNameUse : Integer;
  buffer : StringBuilder;
  account : StringBuilder;
  domain : StringBuilder;
begin
  pZero := IntPtr.Zero;
  pSid := IntPtr.Zero;
  psd := pZero;
  errorReturn := SecurityDescriptor.GetNamedSecurityInfo(objectName,
                                                         SeObjectType.FileObject,
                                                         SecurityInformation.Owner,
                                                         pSid,
                                                         pZero,
                                                         pZero,
                                                         pZero,
                                                         psd);
  if (errorReturn <> 0) then
    raise new Exception(string.Format('GetNamedSecurityInfo excited with code {0}. (last error is {0})',
                                      errorReturn,
                                      Marshal.GetLastWin32Error));

  bufferSize := 64;
  accountLength := bufferSize;
  domainLength := bufferSize;
  sidNameUse := 0;
  
  buffer := new StringBuilder;
  account := new StringBuilder(bufferSize);
  domain := new StringBuilder(bufferSize);
  
  errorReturn := SecurityDescriptor.LookupAccountSid(nil,
                                                     pSid,
                                                     account,
                                                     accountLength,
                                                     domain,
                                                     domainLength,
                                                     sidNameUse);
  if (errorReturn = 0) then
    raise new Exception(string.Format('LookupAccountSid excited with code 0. (last error is {0})',
                                      Marshal.GetLastWin32Error));

  buffer.Append(domain);
  buffer.Append('\');
  buffer.Append(account);
  Result := buffer.ToString;
end;

end.
Ab hier sollte eine Konvertierung zu D.Net easy sein.

Der zeitaufwendigste Part an allem war das Schreiben dieses Beitrages. Also -> Schau dir den Reflector mal an.
Es macht auch Spass die Microsoft Assemblies damit auseinanderzunehmen.
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#8

Re: File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 23. Mai 2005, 13:22
Zitat von Robert_G:
Delphi-Quellcode:
    [DllImport('advapi32.dll', SetLastError := True)]
    class method GetNamedSecurityInfo(pObjectName: string;
                                      ObjectType: SeObjectType;
                                      SecurityInfo: SecurityInformation;
                                      out ppsidOwner,
                                          ppsidGroup,
                                          ppDacl,
                                          ppSacl,
                                          ppSecurityDescriptor: IntPtr): Integer; external;
Ich verspüre den Drang zu ulfen

Sorry, @FragKing, ich konnte nicht wissen, daß auch eine solche Verballhornung von ObjectPascal existiert. Aber zumindest das out (siehe var, const, out) hat sich erhalten. Nur string für den ersten Parameter befremdet mich leicht. Aber wird schon richtig sein, ist schließlich die .NETte Version.
  Mit Zitat antworten Zitat
FragKing

Registriert seit: 21. Mai 2005
Ort: Zurich, Switzerland
5 Beiträge
 
Delphi 2005 Architect
 
#9

Re: File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 23. Mai 2005, 13:27
Das String, so habe ich gelesen, wird vom compiller selber in ein brauchbares format umgewandelt

Ich probiere das ganze mal, danke vielmals! Und das mit diesem Reflector klingt wirklich hervorragend!
Danke euch allen für die Hilfe! So sollts doch sicher klappen =)

Melde mich wieder!

Gruss
Michel
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#10

Re: File Owner mittels GetNamedSecurityInfo - Hilfe!

  Alt 23. Mai 2005, 14:04
Zitat von Olli:
Sorry, @FragKing, ich konnte nicht wissen, daß auch eine solche Verballhornung von ObjectPascal existiert. Aber zumindest das out (siehe var, const, out) hat sich erhalten. Nur string für den ersten Parameter befremdet mich leicht.
Hmpf?
Was ist an der Zeile anders als in Delphi.Net? (Mal abgesehen davon, dass es in Chrome method statt function/procedure heißt)...
Zitat von Olli:
Aber wird schon richtig sein, ist schließlich die .NETte Version.
Das wird vom Marshaler übersetzt.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 13:59 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