Delphi-PRAXiS
Seite 5 von 9   « Erste     345 67     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Zugriffsverletzung ADSI, so was komisches hab ich noch nie.. (https://www.delphipraxis.net/146499-zugriffsverletzung-adsi-so-komisches-hab-ich-noch-nie.html)

Alex O. 20. Feb 2010 13:43

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hallo Cherry!

schau dir mal die Threads an Hier im Forum suchenADSI Stackproblem.
vielleicht liegt es bei dir auch an einem Stack-Problem(?)

Damit würden sich zumindest einige der Probleme erklären...

cherry 22. Feb 2010 09:27

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von Alex O.
Hallo Cherry!

schau dir mal die Threads an Hier im Forum suchenADSI Stackproblem.
vielleicht liegt es bei dir auch an einem Stack-Problem(?)

Damit würden sich zumindest einige der Probleme erklären...

[Zitat aus anderem Thread]

Delphi-Quellcode:
asm
  push ESI;
  push EDI;
end;
  Res:=HRtoAD(DHR);
asm
  pop EDI;
  pop ESI;
end;
die Register ESI und EDI werden anscheinend durch den Aufruf von ADsOpenObject umgebogen und nicht korrekt wiederhergestellt.
Folge war, dass der erste Aufruf der Funktion zwar geklappt hatte, daraufhin aber einige Variablen, nicht mehr erreichbar waren.

Funktioniert wunderbar. Kannst du mir die asm auskommentieren`?

Remko 22. Feb 2010 10:09

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Dezipaitor pointed me to this topic, although I didn't test your code I am sure the problem is the declaration in AdsHlp:
Delphi-Quellcode:
function ADsOpenObject(lpszPathName:WideString;
                       lpszUserName:WideString;
                       lpszPassword:WideString;
                       dwReserved:DWORD;
                       const riid:TGUID;
                       out ppObject):HRESULT; safecall;
which should be using PWideChar instead of WideString. The declaration in the Jedi Apilib (JwaActiveDs) is correct btw:
Delphi-Quellcode:
 function ADsOpenObject(lpszPathName, lpszUserName, lpszPassword: LPCWSTR;
  dwReserved: DWORD; const riid: REFIID; out ppObject: Pointer): HRESULT; stdcall;

cherry 24. Feb 2010 08:49

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von Remko
Dezipaitor pointed me to this topic, although I didn't test your code I am sure the problem is the declaration in AdsHlp:
Delphi-Quellcode:
function ADsOpenObject(lpszPathName:WideString;
                       lpszUserName:WideString;
                       lpszPassword:WideString;
                       dwReserved:DWORD;
                       const riid:TGUID;
                       out ppObject):HRESULT; safecall;
which should be using PWideChar instead of WideString. The declaration in the Jedi Apilib (JwaActiveDs) is correct btw:
Delphi-Quellcode:
 function ADsOpenObject(lpszPathName, lpszUserName, lpszPassword: LPCWSTR;
  dwReserved: DWORD; const riid: REFIID; out ppObject: Pointer): HRESULT; stdcall;

HURRA!! Genau das scheint die Lösung zu sein. Die einzige die bei mir keine Gänsehaut hervorruft. :-) Danke.

Nun habe ich ein kleines Folgeproblem...
Bis jetzt hat bei mir die Funktion ADsGetObject/ADsOpenObject immer eine EOleException ausgelöst, wenn was nicht i.O. war. Diese konnte ich dann super verwenden. Wenn jetzt z.B eine Authentifizierung mit ADsOpenObject() fehlschlägt, kann ich zwar checken ob SUCCEEDED(HRESULT) oder nicht, jedoch löst es (nachdem die Funktionen korrekt deklariert sind, nochmals Danke Remko) keine eOleExceptions mehr aus... habe jetzt angefangen mir dazu eine Hilfsfunktion zu bauen, nur leider scheints endlos zu sein, jedenfalls der ADsOpenObject Fehlercode wenn ich z.B ein falsches Passwort angebe, habe ich noch nicht rausgekriegt.

Oder ist der Ansatzt schon mal falsch?

Delphi-Quellcode:
function ShowEx(hr: HRESULT): String;
resourcestring
  rsERROR_FILE_NOT_FOUND = 'Objekt nicht gefunden.';
  rsERROR_ACCESS_DENIED = 'Zugriff verweigert.';
  rsERROR_NOT_ENOUGH_MEMORY = 'System hat zuwenig speicher.';
  rsERROR_GEN_FAILURE = 'Unbekannter Fehler.';
  rsERROR_DEV_NOT_EXIST = 'Server ist nicht verfügbar.';
  rsERROR_BAD_NET_RESP = 'Kommunikation mit dem LDAP-Server kann nicht aufgebaut werden.';
  rsERROR_UNEXP_NET_ERR = 'Ver- / Entschlüsselungsfehler ist aufgetreten.';
  rsERROR_TOO_MANY_NAMES = 'Limite der verbundenen Administratoren ist erreicht.';
  rsERROR_INVALID_PASSWORD = 'Authentifizierung fehlgeschlagen.';
  rsERROR_INVALID_PARAMETER = 'Syntax oder Parameter ist nicht korrekt';
  rsERROR_OPEN_FAILED = 'Operationsfehler ist aufgetreten.';
  rsERROR_INSUFFICIENT_BUFFER = 'Resultat ist zu gross.';
  rsERROR_INVALID_NAME = 'Syntaxfehler.';
  rsERROR_INVALID_LEVEL = 'Protokollfehler.';
  rsERROR_ALREADY_EXISTS = 'Objekt ist bereits vorhanden.';
  rsERROR_MORE_DATA = 'Es wurden nicht alle benötigten Informationen erhalten.';
  rsERROR_BUSY = 'Server ist beschäftigt.';
  rsERROR_CAN_NOT_COMPLETE = 'Server kann die Operation nicht durchführen.';
  rsERROR_SERVICE_REQUEST_TIMEOUT = 'Timeout abgelaufen.';
  rsERROR_EXTENDED_ERROR = 'Erweiterter Fehler.';
  rsERROR_CANCELLED = 'Aktion wurde durch den Benutzer abgebrochen.';
  rsERROR_NOT_ENOUGH_QUOTA = 'Zeit- oder Grössenlimit erreicht.';
  rsERROR_LOGON_FAILURE = 'Die angegebene Anmeldeinformationen sind ungültig.';
  rsERROR_OBJECT_ALREADY_EXISTS = 'Das Objekt ist bereits vorhanden.';
begin
  if (hr and ERROR_FILE_NOT_FOUND = 0) then
    result := rsERROR_FILE_NOT_FOUND
  else if (hr and ERROR_ACCESS_DENIED = 0) then
    result := rsERROR_ACCESS_DENIED
  else if (hr and ERROR_NOT_ENOUGH_MEMORY = 0) then
    result := rsERROR_NOT_ENOUGH_MEMORY
  else if (hr and ERROR_GEN_FAILURE = 0) then
    result := rsERROR_GEN_FAILURE
  else if (hr and ERROR_DEV_NOT_EXIST = 0) then
    result := rsERROR_DEV_NOT_EXIST
  else if (hr and ERROR_BAD_NET_RESP = 0) then
    result := rsERROR_BAD_NET_RESP
  else if (hr and ERROR_UNEXP_NET_ERR = 0) then
    result := rsERROR_UNEXP_NET_ERR
  else if (hr and ERROR_TOO_MANY_NAMES = 0) then
    result := rsERROR_TOO_MANY_NAMES
  else if (hr and ERROR_INVALID_PASSWORD = 0) then
    result := rsERROR_INVALID_PASSWORD
  else if (hr and ERROR_INVALID_PARAMETER = 0) then
    result := rsERROR_INVALID_PARAMETER
  else if (hr and ERROR_OPEN_FAILED = 0) then
    result := rsERROR_OPEN_FAILED
  else if (hr and ERROR_INSUFFICIENT_BUFFER = 0) then
    result := rsERROR_INSUFFICIENT_BUFFER
  else if (hr and ERROR_INVALID_NAME = 0) then
    result := rsERROR_INVALID_NAME
  else if (hr and ERROR_INVALID_LEVEL = 0) then
    result := rsERROR_INVALID_LEVEL
  else if (hr and ERROR_ALREADY_EXISTS = 0) then
    result := rsERROR_ALREADY_EXISTS
  else if (hr and ERROR_MORE_DATA = 0) then
    result := rsERROR_MORE_DATA
  else if (hr and ERROR_BUSY = 0) then
    result := rsERROR_BUSY
  else if (hr and ERROR_CAN_NOT_COMPLETE = 0) then
    result := rsERROR_CAN_NOT_COMPLETE
  else if (hr and ERROR_SERVICE_REQUEST_TIMEOUT = 0) then
    result := rsERROR_SERVICE_REQUEST_TIMEOUT
  else if (hr and ERROR_EXTENDED_ERROR = 0) then
    result := rsERROR_EXTENDED_ERROR
  else if (hr and ERROR_CANCELLED = 0) then
    result := rsERROR_CANCELLED
  else if (hr and ERROR_NOT_ENOUGH_QUOTA = 0) then
    result := rsERROR_NOT_ENOUGH_QUOTA
  else if (hr and ERROR_LOGON_FAILURE = 0) then
    result := rsERROR_LOGON_FAILURE
end;

Remko 24. Feb 2010 08:56

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
AdsOpenObject always returns a HRESULT which you can check against known values (case hr of). When you declare a function as safecall in Delphi a wrapper (sometimes called an exception firewall) is added that will raise exceptions for you. If you want you can declare the function as safecall (just replace stdcall with safecall) and use a try..except handler.

PS: the other functions in AdsHlp such as AdsGetObject have the same declaration using WideString so you should change those as well...

Alex O. 24. Feb 2010 09:11

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von cherry
HURRA!! Genau das scheint die Lösung zu sein. Die einzige die bei mir keine Gänsehaut hervorruft. :-) Danke.

Das geht mir genau so! Das mit dem Push/Pop funktioniert zwar, ist aber sicher äusserst grenzwertig :-D

Danke an Remko für den Tipp! :thumb:

cherry 24. Feb 2010 09:13

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Zitat:

Zitat von Remko
AdsOpenObject always returns a HRESULT which you can check against known values (case hr of). When you declare a function as safecall in Delphi a wrapper (sometimes called an exception firewall) is added that will raise exceptions for you. If you want you can declare the function as safecall (just replace stdcall with safecall) and use a try..except handler.

PS: the other functions in AdsHlp such as AdsGetObject have the same declaration using WideString so you should change those as well...

Hmm... und schon wieder schleicht sich ein Problem ein:

Wenn ich die Funktionen AdsGetObject/AdsOpenObject mit safecall deklariere, werden zwar die exceptions wieder ausgelöst nur verhaltet sich das Ganze wieder ähnlich unstabil wie vorher...
Diese Funktion zeigt mir einen Benutzer an und die dazugehörigen Gruppen... Dies funktioniert wenn ich die Funktionen im Wrapper mit stdcall deklariere, nicht aber mit safecall! >> wenn ich das Auflisten der Gruppen auskommentiere gehts... ist doch komisch oder?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  usr: IADsUser;
begin
  ClearFields;
  ShowUser(EdLDAP.Text, CBShowUser);
  sEditedFields.Clear;
  sOldObjectPath := EdLDAP.Text;

  if SUCCEEDED(AccessObject(EdLDAP.Text, IADsUser, usr)) then
    EnumGroupsOfUser(usr, ListBox1.Items); //<-- Access Violation here >> Die Haltepunkte in der Funktion kommen nicht zum Zug!!!
end;

Remko 24. Feb 2010 09:17

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
I don't understand what you are trying to do with showex and the hr values, you should use the error values as declared in JwaAdsErr.pas such as E_ADS_BAD_PATHNAME and E_ADS_INVALID_DOMAIN_OBJECT.

Corpsman 24. Feb 2010 09:24

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
ist euch eigentlich aufgefallen dass die If Bedingungen von cherry falsch sind ?


Zitat:

Delphi-Quellcode:
if (hr and ERROR_FILE_NOT_FOUND = 0) then
    result := rsERROR_FILE_NOT_FOUND

ist natürlich absoluter Blödsin

richtig wäre :
Delphi-Quellcode:
if ((hr and ERROR_FILE_NOT_FOUND)= ERROR_FILE_NOT_FOUND) then
     result := rsERROR_FILE_NOT_FOUND

Dezipaitor 24. Feb 2010 09:28

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Ich kann mich nur schon wieder aufregen, dass jeder glaubt so einfach von C nach Delphi WinAPI Header Dateien konvertieren zu können. Der Thread hier ist ein großes Beispiel, dass es oftmals nicht funktioniert.
Ich vermute noch viel mehr Fehler in diesen Units.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:48 Uhr.
Seite 5 von 9   « Erste     345 67     Letzte »    

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