Delphi-PRAXiS
Seite 2 von 3     12 3      

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.

cherry 24. Feb 2010 09:30

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

Zitat von Dezipaitor
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.

Ich hab nie gesagt, dass es einfach ist und es auch nie geglaubt. Aber was willst du damit eigentlich sagen?

Dezipaitor 24. Feb 2010 09:47

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Ich hab nicht direkt dich damit gemeint. Aber schön, dass du dich angesprochen fühlst.
Nur meine ich, dass man genau deshalb solche offziellen Bibliotheken, wie die JEDI API verwenden sollte. Und wenn dort ein Fehler drin ist, dann schreibt man eine Mail mit der Vermutung. Wir schauen dann nach und sehen es dann meist auch schon (jahrelange Erfahrung).
Aber wenn jemand die Konvertierung selbst macht, dann ist es meist so, dass diese/r nur seinen/ihren Quelltext postet (wenn überhaupt) und man garnicht mitbekommt, dass er/sie die Übersetzung selbst gemacht hat. Das war reiner Zufall, dass ich Remko diesen Thread gezeigt habe und er aus Interesse die Übersetzungen angeschaut hat, da er selbst an einer AD Klasse für JWSCL arbeitet.

Aber er/sie hätte sich soviel Arbeit und Zeit erspart, indem er einfach schon die (richtige) Vorlage genommen hätte.

Zitat:

Zitat von cherry
Ich hab nie gesagt, dass es einfach ist und es auch nie geglaubt.

Hast du geschrieben, dass du die Übersetzung selbst gemacht oder irgendwoher kopiert hast?

cherry 24. Feb 2010 10:09

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

Zitat von Dezipaitor
Hast du geschrieben, dass du die Übersetzung selbst gemacht oder irgendwoher kopiert hast?

Ich habe den Wrapper von Agnisoft, da ich mir Anfangs nicht bewusst war, dass eine JEDI version existierte.

Ok. Ich verwende jetzt die jedi Units und es funktioniert soweit super. Nur habe ich immer noch das Problem, dass ich mit den HRESULT nicht klar komme...

Ich nehme nochmals das Besipiel (AdsGetObject)

Mit untenstehendem Code ergibt sich folgendes:
#1: Ich verwende einen Falschen Benutzername und Passwort -> result = 16 >> S_ADS_ERRORSOCCURRED
#2: Ich will auf ein Objekt zugreiffen das nicht existiert -> result = 0 >> Keine Übereinstimmung

Delphi-Quellcode:
 
    result := '0';
    if (hr and E_ADS_BAD_PATHNAME) = 0 then
      result := '1'
    else if (hr and E_ADS_INVALID_DOMAIN_OBJECT) = 0 then
      result := '2'
    else if (hr and E_ADS_INVALID_USER_OBJECT) = 0 then
      result := '3'
    else if (hr and E_ADS_UNKNOWN_OBJECT) = 0 then
      result := '4'
    else if (hr and E_ADS_PROPERTY_NOT_SET) = 0 then
      result := '5'
    else if (hr and E_ADS_PROPERTY_NOT_SUPPORTED) = 0 then
      result := '6'
    else if (hr and E_ADS_PROPERTY_INVALID) = 0 then
      result := '7'
    else if (hr and E_ADS_OBJECT_UNBOUND) = 0 then
      result := '8'
    else if (hr and E_ADS_PROPERTY_NOT_MODIFIED) = 0 then
      result := '9'
    else if (hr and E_ADS_PROPERTY_MODIFIED) = 0 then
      result := '10'
    else if (hr and E_ADS_CANT_CONVERT_DATATYPE) = 0 then
      result := '11'
    else if (hr and E_ADS_PROPERTY_NOT_FOUND) = 0 then
      result := '12'
    else if (hr and E_ADS_OBJECT_EXISTS) = 0 then
      result := '13'
    else if (hr and E_ADS_SCHEMA_VIOLATION) = 0 then
      result := '14'
    else if (hr and E_ADS_COLUMN_NOT_SET) = 0 then
      result := '15'
    else if (hr and S_ADS_ERRORSOCCURRED) = 0 then
      result := '16'
    else if (hr and S_ADS_NOMORE_ROWS) = 0 then
      result := '17'
    else if (hr and S_ADS_NOMORE_COLUMNS) = 0 then
      result := '18'
    else if (hr and E_ADS_INVALID_FILTER) = 0 then
      result := '19';
Nun mache ich das Selbe, verwende aber die Vergleichsweise die mir Corpsman unterbreitet hat:
#1: Ich verwende einen Falschen Benutzername und Passwort -> result = 0 >> Keine Übereinstimmung
#2: Ich will auf ein Objekt zugreiffen das nicht existiert -> result = 0 >> Keine Übereinstimmung

Delphi-Quellcode:
 
    result := '0';  
    if ((hr and E_ADS_BAD_PATHNAME) = E_ADS_BAD_PATHNAME) then
      result := '1'
    else if ((hr and E_ADS_INVALID_DOMAIN_OBJECT) = E_ADS_INVALID_DOMAIN_OBJECT) then
      result := '2'
    else if ((hr and E_ADS_INVALID_USER_OBJECT) = E_ADS_INVALID_USER_OBJECT) then
      result := '3'
    else if ((hr and E_ADS_UNKNOWN_OBJECT) = E_ADS_UNKNOWN_OBJECT) then
      result := '4'
    else if ((hr and E_ADS_PROPERTY_NOT_SET) = E_ADS_PROPERTY_NOT_SET) then
      result := '5'
    else if ((hr and E_ADS_PROPERTY_NOT_SUPPORTED) = E_ADS_PROPERTY_NOT_SUPPORTED) then
      result := '6'
    else if ((hr and E_ADS_PROPERTY_INVALID) = E_ADS_PROPERTY_INVALID) then
      result := '7'
    else if ((hr and E_ADS_OBJECT_UNBOUND) = E_ADS_OBJECT_UNBOUND) then
      result := '8'
    else if ((hr and E_ADS_PROPERTY_NOT_MODIFIED) = E_ADS_PROPERTY_NOT_MODIFIED) then
      result := '9'
    else if ((hr and E_ADS_PROPERTY_MODIFIED) = E_ADS_PROPERTY_MODIFIED) then
      result := '10'
    else if ((hr and E_ADS_CANT_CONVERT_DATATYPE) = E_ADS_CANT_CONVERT_DATATYPE) then
      result := '11'
    else if ((hr and E_ADS_PROPERTY_NOT_FOUND) = E_ADS_PROPERTY_NOT_FOUND) then
      result := '12'
    else if ((hr and E_ADS_OBJECT_EXISTS) = E_ADS_OBJECT_EXISTS) then
      result := '13'
    else if ((hr and E_ADS_SCHEMA_VIOLATION) = E_ADS_SCHEMA_VIOLATION) then
      result := '14'
    else if ((hr and E_ADS_COLUMN_NOT_SET) = E_ADS_COLUMN_NOT_SET) then
      result := '15'
    else if ((hr and S_ADS_ERRORSOCCURRED) = S_ADS_ERRORSOCCURRED) then
      result := '16'
    else if ((hr and S_ADS_NOMORE_ROWS) = S_ADS_NOMORE_ROWS) then
      result := '17'
    else if ((hr and S_ADS_NOMORE_COLUMNS) = S_ADS_NOMORE_COLUMNS) then
      result := '18'
    else if ((hr and E_ADS_INVALID_FILTER) = E_ADS_INVALID_FILTER) then
      result := '19';
Ich habe das Ganze Spielchen auch noch mit Case hr of E_ADS_BAD_PATHNAME: usw ... gemacht,
auch hier ergab sich:

#1: Ich verwende einen Falschen Benutzername und Passwort -> result = 0 >> Keine Übereinstimmung
#2: Ich will auf ein Objekt zugreiffen das nicht existiert -> result = 0 >> Keine Übereinstimmung

Ich scheine ja wohl grundsätzlich was falsch zu machen, aber was?

Dezipaitor 24. Feb 2010 10:27

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
D.h. einfach, dass entweder hr = 0 oder ein Wert ist, den du nicht abfängst.
Nimm OleCheck(ADBla()); ,um eine FehlerException zu bekommen.

cherry 24. Feb 2010 10:42

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

Zitat von Dezipaitor
D.h. einfach, dass entweder hr = 0 oder ein Wert ist, den du nicht abfängst.
Nimm OleCheck(ADBla()); ,um eine FehlerException zu bekommen.

Danke.
Und noch das letzte mal das ich eure Nerven in diesem Thread strapaziere bevor ich ihn dann schliesse...

Da die Deklaration von ADsGetObject nun einen Pointer erwartet als out Parameter, habe ichs folgendermassen gelöst:

Delphi-Quellcode:

function TForm1.AccessObject(const PathName: string; const riid:TGUID; out ppObject: Pointer): HRESULT;
var
  e: EOleSysError;
begin
  if (EdUsername.Text <> '') and (EdPassword.Text <> '') then
    result := ADsOpenObject(LPCWSTR(PathName), LPCWSTR(EdUsername.Text), LPCWSTR(EdPassword.Text), ADS_USE_ENCRYPTION, riid, ppObject)
  else
    result := ADsGetObject(LPCWSTR(PathName), riid, ppObject);

  if not Succeeded(result) then
  begin
    e := EOleSysError.Create('', result, 0);
    MessageDlg(e.Message, mtError, [mbOK], 0);
  end;
end;

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

  if SUCCEEDED(AccessObject(EdLDAP.Text, IADsUser, usr)) then
    EnumGroupsOfUser(IADsUser(usr), ListBox1.Items);
end;
Ist das grundsätzlich richtig? oder würde man das anders machen?

Remko 24. Feb 2010 12:12

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Just cast the interface to pointer when passing it to AdsGetObject

Remko 24. Feb 2010 12:14

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
btw: here is a link to the Win32 error codes for Adsi: http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx

Dezipaitor 24. Feb 2010 13:21

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Delphi-Quellcode:
if not Succeeded(result) then
  begin
    e := EOleSysError.Create('', result, 0);
    MessageDlg(e.Message, mtError, [mbOK], 0);
  end;
???????? Was ist das?

cherry 24. Feb 2010 13:39

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

Zitat von Dezipaitor
Delphi-Quellcode:
if not Succeeded(result) then
  begin
    e := EOleSysError.Create('', result, 0);
    MessageDlg(e.Message, mtError, [mbOK], 0);
  end;
???????? Was ist das?

Das war nur ein Test. OleCheck gibt gleich eine Fehlermeldung raus, ich möchte aber später die Fehlermeldung in meinen AdsManager speichern und diese dann nur bei bedarf durch AdsManager.getLastError aufrufen. Also würde dann

Delphi-Quellcode:
if not Succeeded(result) then
  begin
    e := EOleSysError.Create('', result, 0);
    SetLastError(e.Message);
  end;
daraus, oder so in der Art.


Ok, jetzt drängt sich aber doch noch was auf:
und zwar ExecuteSearch, hast du da vielleicht ein Beispiel dazu... Meine Variante funktioniert natürlich so nicht mehr. Und ich weiss noch wie lange ich damals hatte um die Funktion hinzubekommen. Konkret gibts ne Zugriffsverletzung beim Aufruf von: "hr := search.GetNextRow(Pointer(ptrResult));"

Letztes mal, weiss ich noch, wars so, das ich das ganze IDirectorySearch geändert habe. Sprich alle Pointer auf THandle geändert, dann hats geklappt. Nun verwende ich ja aber JwaAdsTLB und da sind die Pointer wieder und ich denke die JEDIS haben das schon richtig gemacht?!

Meine Suchfunktion ist etwas "speziell", ich Poste sie trotzdem mal... Wäre jedoch um ein einfaches Beispiel (das mit den JEDI Units funktioniert) sehr dankbar.

Delphi-Quellcode:
{******************************************************************************}
// OBJECT: THIS FUNCTION EXECUTES A SEARCH.
// EXPECTED PARAMETERS: searchfilter eg. = (&(|(objectClass=user)(objectClass=group)(objectClass=organizationalUnit))(|(Name=*'+EdSearch.Text+'*)(sAMAccountName=*'+EdSearch.Text+'*)))
//                      CallBackFunction interface: TCallBackResultArray = procedure(data: TResultArray) of object; -> TResultArray is an 2dimensional array of string
// OPTIONAL PARAMETERS: Attributes: eg: 'Name;AdsPath;Class;' -> A delimited String to pass which defines the attributes you want to get. default: Name;AdsPath;
//                      LDAPBeginingPath: eg: OU=example,OU=this,DC=domain1,DC=lan -> means the search will be executed on this path. default: search whole AD
{******************************************************************************}
procedure TEADSObject.DirectorySearch(searchfilter: string; CallBackFunction: TCallBackResultArray; Attributes: string = 'Name;AdsPath;'; LDAPBeginingPath: string = 'ROOTDSE');
var
  search: IDirectorySearch;
  ptrResult: THandle;
  opt: ads_searchpref_info;
  dwCount: DWORD;
  hr: HResult;
  col: ads_search_column;

  dwErr: DWord;
  szErr    : array[0..255] of WideChar;
  szName   : array[0..255] of WideChar;
  I: Integer;

  ArrResult: TStringArray2;
  ArrResCnt: Integer;
  AttrArray: array of PWideChar;
  Attribute: string;
  empty: Boolean;
begin

  // create an attributes array from the attributes passed by a delimitted string
  for I := 1 to Length(Attributes) do
  begin
    if Attributes[I] = ';' then
    begin
      SetLength(AttrArray, Length(AttrArray)+1);
      getmem(AttrArray[Length(AttrArray)-1], 256);
      StringToWideChar(Attribute, AttrArray[Length(AttrArray)-1], 256);
      Attribute := '';
    end
    else
      Attribute := Attribute + Attributes[I]
  end;

  // for faster search set a LDAPBeginingPath to execute the search within this container
  if LDAPBeginingPath = 'ROOTDSE' then
    LDAPBeginingPath := AdsMgr.ADSController.LDAPPATH;

  // get the search object
  if SUCCEEDED(AccessObject(LDAPBeginingPath, IDirectorySearch, search)) then
  begin
    try
      // set parameters
      opt.dwSearchPref := ADS_SEARCHPREF_SEARCH_SCOPE OR ADS_SEARCHPREF_SORT_ON;
      opt.vValue.dwType := ADSTYPE_INTEGER;
      opt.vValue.__MIDL_0010.Integer := ADS_SCOPE_SUBTREE;
      // setting search preferences
      if not SUCCEEDED(search.SetSearchPreference(opt, 1)) then
      begin
        ADsGetLastError(dwErr, @szErr[0], 254, @szName[0], 254);
        ShowMessage(WideCharToString(szErr));
        Exit;
      end;
      // prepare
      dwCount := Length(AttrArray);
      ArrResCnt := 1;
      // execute the search
      hr := search.ExecuteSearch(LPCWSTR(searchfilter), @AttrArray[0], dwCount, Pointer(ptrResult));
      // handle the result if hr is S_OK
      if SUCCEEDED(hr) then
      begin
        // get first row
        hr := search.GetNextRow(Pointer(ptrResult)); // <<<<<<<<<< ACCESS VIOLATION
        // repeat until no more rows
        while (hr = S_OK) do // (S_NOMORE_ROWS) < JEDI scheints nicht zu kennen
        begin

          // redim result array
          SetLength(ArrResult, ArrResCnt);
          empty := true;

          // for each attribute you want to get (defined in AttrArray)
          for I := 0 to dwCount -1 do
          begin
            // get column
            if Succeeded(search.GetColumn(Pointer(ptrResult), @AttrArray[I], col)) then
            begin
              if col.pADsValues <> nil then
              begin
                // redim result array (2 dimensional string array)
                SetLength(ArrResult[ArrResCnt-1], I+1);
                // fill values into the result array
                ArrResult[ArrResCnt-1,I] := col.pADsValues^.__MIDL_0010.DNString;
                //ArrResult[ArrResCnt-1,I] := col.pADsValues^.__MIDL_0010.BackLink.ObjectName; [AHAAA]
                empty := false;
              end;
              search.FreeColumn(col);
            end;
          end;
          hr := search.GetNextRow(Pointer(ptrResult));

          // only redim the result array next time, if there was a value found
          // we dont want empty fields in the result array.
          if not empty then
            Inc(ArrResCnt);

        end;
      end;
      //search.CloseSearchHandle(ptrResult);
    except
      //search._Release;
      on e: EOleException do
        AdsMgr.SetLastError(e.Message);
    end;
  end;
  if Length(ArrResult) > 0 then
    CallBackFunction(ArrResult);
end;

Dezipaitor 24. Feb 2010 14:10

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

Das war nur ein Test. OleCheck gibt gleich eine Fehlermeldung raus, ich möchte aber später die Fehlermeldung in meinen AdsManager speichern und diese dann nur bei bedarf durch AdsManager.getLastError aufrufen. Also würde dann
Du wirst es mir vllt. nicht glauben, aber jemand anderes würde den Quelltext ohne zu zucken einfach kopieren und verwenden. Kenne so manchen falschen Quellcode, der im Internet damit verbreitet wurde ("Checking if a user is an administrator").

Remko 24. Feb 2010 14:11

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
You are doing something VERY wrong!
First you declare ptrResult as THandle:
Delphi-Quellcode:
  ptrResult: THandle;
Later on you cast it to a pointer:
Delphi-Quellcode:
hr := search.ExecuteSearch(LPCWSTR(searchfilter), @AttrArray[0], dwCount, Pointer(ptrResult));
You are actually lucky that it works because a pointer is actually a dword therefore it works but the correct way would IMO be:
ptrHandle: PHandle;

Delphi-Quellcode:
hr := search.ExecuteSearch(LPCWSTR(searchfilter), @AttrArray[0], dwCount, ptrResult);
If you need to pass it as handle later on use
Delphi-Quellcode:
ptrHandle^
to derefence the pointer.

/Edit just a remark: I know this is just test code but if you change a variable type ALWAYS change it's name as well as you WILL confuse yourself later on ( or DelphiPraxis members reading your code ;-) )
Also when you post example code, please take the effort of cleaning it up as much as possible.

cherry 24. Feb 2010 14:27

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Danke nochmals für dein Engagement. Leider ändert sich auch dann nichts. Auch wenn ich "ptrResult: Pointer;" habe.
Komisch ist, dass "hr := search.ExecuteSearch(LPCWSTR(searchfilter), @AttrArray[0], dwCount, ptrResult);" = S_OK ist, aber die Zeile weiter unten:
"hr := search.GetNextRow(Pointer(ptrResult)); " in einer Zugriffsverletzung endet.

Hast du viellecht ein funktionierendes Beispiel, das wäre wohl das einfachste. Ansonsten probiere ich mir hier einen ab. ;-)
Danke schon mal.

Remko 24. Feb 2010 14:30

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
First you use ptrResult in ExecuteSearch and then you use Pointer(ptrResult) in search.GetNextRow ??
I suggest you do a good cleanup of your code and post that, stating what is and what is not working.

Dezipaitor 24. Feb 2010 14:36

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Vllt. braucht man GetFirstResult zuerst?

cherry 24. Feb 2010 14:57

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Versuche zunächst mal ganz klein anzufangen:

Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
const
  ColCount = 3;
  ColNames : array[0..ColCount-1] of PWideChar = ('Name','Description','ADsPath');
var
  search: IDirectorySearch;
  ptrResult: Pointer;
  hr : HRESULT;
begin
  if SUCCEEDED(ADsGetObject(PWideChar('LDAP://DC=thun,DC=lan'), IDirectorySearch, Pointer(search))) then
  begin
    if SUCCEEDED(search.ExecuteSearch('(objectClass=organizationalUnit)',@ColNames,ColCount,ptrResult)) then
    begin
      hr := search.GetNextRow(ptrResult); // Zugriffsverletzung
    end;
  end;
end;
Und auch ...

Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
const
  ColCount = 3;
  ColNames : array[0..ColCount-1] of PWideChar = ('Name','Description','ADsPath');
var
  search: IDirectorySearch;
  ptrResult: Pointer;
  hr : HRESULT;
begin
  if SUCCEEDED(ADsGetObject(PWideChar('LDAP://DC=thun,DC=lan'), IDirectorySearch, Pointer(search))) then
  begin
    if SUCCEEDED(search.ExecuteSearch('(objectClass=organizationalUnit)',@ColNames,ColCount,ptrResult)) then
    begin
      hr := search.GetFirstRow(ptrResult); // Zugriffsverletzung
    end;
  end;
end;
Was mach ich denn falsch?

Alter Mann 24. Feb 2010 15:00

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

In diesem Beitrag habe ich damals schon auf ein paar Unstimmigkeiten hingewiesen.

Das mit der nicht geschriebenen Mail tut mir leid.

cherry 24. Feb 2010 15:17

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

Zitat von Alter Mann
Hallo

In diesem Beitrag habe ich damals schon auf ein paar Unstimmigkeiten hingewiesen.

Das mit der nicht geschriebenen Mail tut mir leid.

Du meinst das mit Pointer und THandle nehm ich an?! Nun, da ich ja jetzt die JEDI units verwende verwende ich auch jwaADsTLB, und ich weiss nicht ob ich da einfach das IDirectoryInterface ändern soll?!
Zudem habe ich das Testhalber kurz gemacht und es klappte trotzdem nicht... > Zugriffsverletzung an derselben Stelle!

Remko 24. Feb 2010 15:36

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
I have seen the problem: delphi creates garbage when importing the TypeLib for Active Directory. I reimported the typelib from c:\windows\system32\activeds.tlb with Delphi 2010 and it's still the same mess. The declaration of IDirectorySearch is totally wrong (and the one in AdsHlp.pas is wrong as well).

This works fine for me:

Delphi-Quellcode:
type
  ADS_SEARCH_HANDLE = THandle;
  PADS_SEARCH_HANDLE = ^ADS_SEARCH_HANDLE;
// *********************************************************************//
// Interface: IDirectorySearch
// Flags:    (0)
// GUID:     {109BA8EC-92F0-11D0-A790-00C04FD8D5A8}
// *********************************************************************//
  IDirectorySearch = interface(IUnknown)
    ['{109BA8EC-92F0-11D0-A790-00C04FD8D5A8}']
    function SetSearchPreference(var pSearchPrefs: ads_searchpref_info; dwNumPrefs: LongWord): HResult; stdcall;
    function ExecuteSearch(pszSearchFilter: PWideChar; pAttributeNames: PWideChar;
                            dwNumberAttributes: LongWord; var phSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function AbandonSearch(phSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function GetFirstRow(hSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function GetNextRow(hSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function GetPreviousRow(hSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function GetNextColumnName(hSearchHandle: ADS_SEARCH_HANDLE; out ppszColumnName: PWideChar): HResult; stdcall;
    function GetColumn(hSearchResult: ADS_SEARCH_HANDLE; szColumnName: PWideChar;
                        out pSearchColumn: ads_search_column): HResult; stdcall;
    function FreeColumn(var pSearchColumn: ads_search_column): HResult; stdcall;
    function CloseSearchHandle(hSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
  end;

procedure TMainForm.Button1Click(Sender: TObject);
var
  ColCount: DWORD;
  ColNames: array of PWideChar;
  DirSearch: IDirectorySearch;
  SearchHandle: ADS_SEARCH_HANDLE;
  hr : HRESULT;
begin
  ColCount := 1;
  SetLength(ColNames, 3);
  ColNames[0] := 'name';
  ColNames[1] := 'description';
  ColNames[2] := 'adspath';

  hr := ADsGetObject(PWideChar('LDAP://DC=rmi,DC=local'), IID_IDirectorySearch, Pointer(DirSearch));

  if failed(hr) then
    Exit;

  SearchHandle := 0;
  hr := DirSearch.ExecuteSearch('(objectClass=organizationalUnit)', @ColNames[0], Length(ColNames), SearchHandle);
  if failed(hr) then
    Exit;

  while DirSearch.GetNextRow(SearchHandle) <> S_ADS_NOMORE_ROWS do
  begin
    // Do something with result
  end;
  DirSearch.CloseSearchHandle(SearchHandle);
  DirSearch := nil;
end;

Remko 24. Feb 2010 15:56

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Some more observations: the attribute names in pAttributeNames MUST BE lowerCASE or you will get empty results.
I made some more corrections to the declaration:
Delphi-Quellcode:
type
  ADS_SEARCH_HANDLE = THandle;
  PADS_SEARCH_HANDLE = ^ADS_SEARCH_HANDLE;
  PADS_SEARCH_COLUMN = ^ads_search_column;
// *********************************************************************//
// Interface: IDirectorySearch
// Flags:    (0)
// GUID:     {109BA8EC-92F0-11D0-A790-00C04FD8D5A8}
// *********************************************************************//
  IDirectorySearch = interface(IUnknown)
    ['{109BA8EC-92F0-11D0-A790-00C04FD8D5A8}']
    function SetSearchPreference(var pSearchPrefs: ads_searchpref_info; dwNumPrefs: LongWord): HResult; stdcall;
    function ExecuteSearch(pszSearchFilter: PWideChar; pAttributeNames: PWideChar;
                            dwNumberAttributes: LongWord; var phSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function AbandonSearch(phSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function GetFirstRow(hSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function GetNextRow(hSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function GetPreviousRow(hSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
    function GetNextColumnName(hSearchHandle: ADS_SEARCH_HANDLE; out ppszColumnName: PWideChar): HResult; stdcall;
    function GetColumn(hSearchResult: ADS_SEARCH_HANDLE; szColumnName: PWideChar;
                        var pSearchColumn: ads_search_column): HResult; stdcall;
    function FreeColumn(var pSearchColumn: ads_search_column): HResult; stdcall;
    function CloseSearchHandle(hSearchResult: ADS_SEARCH_HANDLE): HResult; stdcall;
  end;
Accessing the search results will currently not work because the declaration of ADS_SEARCH_COLUMN is totally wrong in the typelib, so while this code should be correct the results cannot be displayed because of the wrong declaration:
Delphi-Quellcode:
  while DirSearch.GetNextRow(SearchHandle) <> S_ADS_NOMORE_ROWS do
  begin
    for i := 0 to Length(ColNames) - 1 do
    begin
      hr := DirSearch.GetColumn(SearchHandle, ColNames[i], col);
      if succeeded(hr) then
      begin
        // note that the typelib doesn't know the proper typed pointer and the anonymous union in it
        OutputDebugString(col.pADsValues^.__MIDL_0010.CaseIgnoreString);
        DirSearch.FreeColumn(col);
      end;
    end;
    // Do something with result
  end;

Alter Mann 24. Feb 2010 16:20

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi

hier mein Änderungen:
Delphi-Quellcode:
// *********************************************************************//
// Schnittstelle: IDirectorySearch
// Flags:    (0)
// GUID:     {109BA8EC-92F0-11D0-A790-00C04FD8D5A8}
// *********************************************************************//
  IDirectorySearch = interface(IUnknown)
    ['{109BA8EC-92F0-11D0-A790-00C04FD8D5A8}']
    function SetSearchPreference(var pSearchPrefs: ads_searchpref_info; dwNumPrefs: LongWord): HResult; stdcall;
    function ExecuteSearch(pszSearchFilter: PWideChar; pAttributeNames: PWideChar;
                           dwNumberAttributes: LongWord; out phSearchResult: THandle): HResult; stdcall;
    function AbandonSearch(var phSearchResult: THandle): HResult; stdcall;
    function GetFirstRow(var hSearchResult: THandle): HResult; stdcall;
    function GetNextRow(hSearchResult: THandle): HResult; stdcall;
    function GetPreviousRow(var hSearchResult: THandle): HResult; stdcall;
    function GetNextColumnName(var hSearchHandle: THandle; out ppszColumnName: PWideChar): HResult; stdcall;
    function GetColumn(hSearchResult: THandle; szColumnName: PWideChar;
                       out pSearchColumn: ads_search_column): HResult; stdcall;
    function FreeColumn(var pSearchColumn: ads_search_column): HResult; stdcall;
    function CloseSearchHandle(var hSearchResult: THandle): HResult; stdcall;
  end;
Im Anhang der Directorysearcher.

Alter Mann

cherry 24. Feb 2010 16:24

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hey! Vielen Dank euch allen :!:

:dancer2: :witch: :bouncing4: :bounce1: :firejump: :bounce2: :hi: :hello:

Remko 24. Feb 2010 16:27

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
http://www.remkoweijnen.nl/temp/jediblog.png

:wink: :wink: :wink:

Dezipaitor 24. Feb 2010 16:31

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Dann geb ich auch meinen Senf ab:
Die JEDI API&WSCL hat einen geschätzten Wert bei Neuerstellung von 5 Millionen USD.

@Alter Mann:
Remko erstellt gerade eine AD Klasse für JWSCL. Allerdings hat er gerade mehr Arbeit bekommen und daher wird das länger dauern. Hast du nicht etwas Zeit übrig, um mitzumachen?

Alter Mann 24. Feb 2010 16:48

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Hm..m,

erst nach meinen Urlaub, so ab den 15. März.

Viele Grüße

PN bis morgen Abend möglich.

Remko 25. Feb 2010 15:21

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
I have created a new version of JwaAdsTlb by hand because the typelib import from Delphi is unable to produce a good file.
I was hoping that Cherry and/or Alter Mann can test the new unit as the conversion was a lot of (boring) work and it's not unimaginable that I made errors. Please let me know...


The problem with the AdsValue record is alignment: I found it in the file IADS.h from the SDK which has the following options:
Delphi-Quellcode:
/* Compiler settings for ads.odl:
    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555
It means that record will be aligned at 8 byte boundaries and Delphi doesn't have an option for that. I was able to solve it by declaring it with a nested case statement:
Delphi-Quellcode:
  ADSVALUE = packed record
  case Byte of // Padding
    0: (
      dwType: ADSTYPE;
      case _DoNotUse: ADSTYPE of // Padding
        ADSTYPE_DN_STRING: (DNString: ADS_DN_STRING);
        ADSTYPE_CASE_EXACT_STRING: (CaseExactString: ADS_CASE_EXACT_STRING);
        ADSTYPE_CASE_IGNORE_STRING: (CaseIgnoreString: ADS_CASE_IGNORE_STRING);
        ADSTYPE_PRINTABLE_STRING: (PrintableString: ADS_PRINTABLE_STRING);
        ADSTYPE_NUMERIC_STRING: (NumericString: ADS_NUMERIC_STRING);
        ADSTYPE_BOOLEAN: (Boolean: ADS_BOOLEAN);
        ADSTYPE_INTEGER: (Integer: ADS_INTEGER);
        ADSTYPE_OCTET_STRING: (OctetString: ADS_OCTET_STRING);
        ADSTYPE_UTC_TIME: (UTCTime: ADS_UTC_TIME);
        ADSTYPE_LARGE_INTEGER: (LargeInteger: ADS_LARGE_INTEGER);
        ADSTYPE_OBJECT_CLASS: (ClassName: ADS_PROV_SPECIFIC);
        ADSTYPE_PROV_SPECIFIC: (ProviderSpecific: ADS_PROV_SPECIFIC);
        ADSTYPE_CASEIGNORE_LIST: (pCaseIgnoreList: PADS_CASEIGNORE_LIST);
        ADSTYPE_OCTET_LIST: (pOctetList: PADS_OCTET_LIST);
        ADSTYPE_PATH: (pPath: PADS_PATH);
        ADSTYPE_POSTALADDRESS: (pPostalAddress: PADS_POSTALADDRESS);
        ADSTYPE_TIMESTAMP: (Timestamp: ADS_TIMESTAMP);
        ADSTYPE_BACKLINK: (BackLink: ADS_BACKLINK);
        ADSTYPE_TYPEDNAME: (pTypedName: PADS_TYPEDNAME);
        ADSTYPE_HOLD: (Hold: ADS_HOLD);
        ADSTYPE_NETADDRESS: (pNetAddress: PADS_NETADDRESS);
        ADSTYPE_REPLICAPOINTER: (pReplicaPointer: PADS_REPLICAPOINTER);
        ADSTYPE_FAXNUMBER: (pFaxNumber: PADS_FAXNUMBER);
        ADSTYPE_EMAIL: (Email: ADS_EMAIL);
        ADSTYPE_NT_SECURITY_DESCRIPTOR: (SecurityDescriptor: ADS_NT_SECURITY_DESCRIPTOR);
        ADSTYPE_DN_WITH_BINARY: (pDNWithBinary: PADS_DN_WITH_BINARY);
        ADSTYPE_DN_WITH_STRING: (pDNWithString: PADS_DN_WITH_STRING)
      );
  end;
  _adsvalue = ADSVALUE;
  PADSVALUE = ^ADSVALUE;
  LPADSVALUE = PADSVALUE;

Remko 8. Mär 2010 20:20

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
So nobody wants to test?

Dezipaitor 22. Mär 2010 12:12

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Wer könnte die ADS Header Testen? Wir brauchen wirklich Freiwillige hier. Das Problem ist auch, dass sich nicht jeder so gut mit AD auskennt, geschweige denn eines hat.

Und besonders, da wir dieses große Problem gelöst haben, kann man etwas zurück erwarten. Nicht zuletzt ist das hier alles nur für euch:
http://blog.delphi-jedi.net/2010/02/15/reminder-to-you/

cherry 23. Mär 2010 13:11

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
@Dezipaitor und @Remko

Sorry das ich mich so lange nicht gemeldet habe. Ich werde das sehr gerne testen und dann auch Feedback abliefern. Nur muss ich bis morgen ein Betarelease des Programms bereit haben und bin daher sehr unter druck. Ich konnte die neue JwaAdsTlb leider noch nicht implementieren, da ich zuwenig Zeit hatte.

Ich verspreche aber, dass ich das gleich nächste Woche implementiere! Ich werde dann die Erfahrungen die ich machen werden in diesem Thread posten.. ok?!
Danke nochmals für eure Hilfe!

cherry 6. Apr 2010 15:34

Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
 
Lieber spät als nie...

Wo kriege ich deine aktuelle JwaAdsHlp und JwaAdsTLB? Ich hab jetzt endlich Zeit dies auszutesten. Oder hast du "nur" die Änderungen gemacht die du hier auch gepostet hast? Dann kann ichs ja auch selber anpassen. Danke.

LG

cherry 7. Apr 2010 14:42

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

Zitat von Remko
I have created a new version of JwaAdsTlb by hand because the typelib import from Delphi is unable to produce a good file.
I was hoping that Cherry and/or Alter Mann can test the new unit as the conversion was a lot of (boring) work and it's not unimaginable that I made errors. Please let me know...

Sind die Änderungen in Beitrag #75 die einzigen die du in JwaAdsTlb gemacht hast. Und die Änderungen #69 die einzigen für JwaAdsHlp ? oder schickst du mir deine Dateien?


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:27 Uhr.
Seite 2 von 3     12 3      

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