AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

ADSI, Stackproblem

Ein Thema von Alex O. · begonnen am 11. Sep 2009 · letzter Beitrag vom 12. Sep 2009
Antwort Antwort
Alex O.

Registriert seit: 30. Apr 2007
8 Beiträge
 
Delphi 2010 Enterprise
 
#1

ADSI, Stackproblem

  Alt 11. Sep 2009, 15:25
Hallo!

Ich arbeite an einem Replikationsdienst, der peropdisch Mitarbeiterstammdaten (Telefonnr, usw) aus meiner Mitarbeiterdatenbank ins ActiveDirectory schreiben soll.
In einer Testumgebung habe ich das mittels der ADSI-Bibliotheken die ich mir von agnisoft geholt habe schon mal hinbekommen.

Jetzt baue ich das ganze in meinen Dienst ein, und habe jetzt plötzlich ein Problem mit dem Stack, wenn ich die Funktion ADsOpenObject (eine in der Windows-DDL activeds.dll definierte Funktion, die über die Unit adshlp.pas definiert wird).
Soweit ich das sehe wird der Stack nach dem Funktionsaufruf nicht richtig zurückgesetzt (?)

so schaut mein Funktionsaufruf aus:
Delphi-Quellcode:
var
  i: Integer;
  DHR: TDHI_HRAnagraphic;
begin
  ...
  ...
  DHR:=ExpGod.HRAnagraphics.GetItem(qWork.FieldByName('HRID').asInteger);
  ...
  ...
  if DHR.ADUser.asBoolean then
  begin
    i:=$123;
    Res:=HRtoAD(DHR);
    Showmessage(IntToStr(i));
  end;
  ...
  ...
end;
folgendes wird dabei aufgerufen:
Delphi-Quellcode:
function THRReplSrv.HRtoAD(AHR: TDHI_HRAnagraphic): Boolean;
var
  DNameTranslator: TNameTranslator;
  DStr: String;
  DADUser: IADsUser;
  HRes: HREsult;
begin
  Result:=False;

  CoInitialize(nil);
  DNameTranslator:=TNameTranslator.Create;
  try
    DStr:=DNameTranslator.Translate_NT_2_DN(AHr.ADLink.asString);

    if DStr = 'then begin
      exit;
    end
    else begin
      if DADUser <> nil then
        DADUser._Release;

      ADsOpenObject('LDAP://' + DStr, FConfig.AD_Username, FConfig.AD_UserPassword, 0, IADsUser, DADUser);

      if Failed(HRes) then begin
        //LogErrorMessage(...);
        exit;
      end;

      if not(Assigned(DADUser)) then begin
        //LogErrorMessage(...);
        exit;
      end;

      //*** get all the ADSI-Fields...
      DADUser.GetInfo;
      ...
      //*** hier werden die Mitarbeiterstammdaten in die entsprechenden Attribute des AD geschrieben
      ...
      DADUser.SetInfo;
      ...
    Result:=True;
  finally
    if DADUser <> nil then
      DADUser._Release;

    DNameTranslator.Free;
    CoUninitialize;
  end;
end;
(das Unwichtige hab ich mal weggelassen, damit die Übersicht nicht leidet; das Objekt DHR speichert mir meine Mitarbeiterstammdaten)

Ich habe bereits versucht:
- alles unwichtige auszukommentieren (Fehler trat trotzdem auf)
- alles bis auf den Aufruf von ADSOpenObject auszukommentieren (Fehler trat trotzdem auf)
- alles auszuführen, nur der Aufruf von ADSOpenObject wird auskommentiert (Fehler trat NICHT auf)
- den Aufruf von ADSOpenObject mit einem leeren LDAP-String auszuführen (Fehler trat NICHT auf)

das Ergebnis war immer: Wenn der Aufruf von ADSOpenObject erfolgreich gemacht wurde, war der Stack in der oben deklarierten Funktion "zerschossen".
Sprich:
- der Stackpointer im Register ESP war vor dem Aufruf der Funktion HRtoAD = 0012FD94
- nach der Rückkehr aus der Funktion HRtoAD war der plötzlich = 0012F894
sollte der nicht identisch sein?? (Siehe auch die angehängten Screenshots des CPU-Fensters)

ich habe deshalb auch mal extra die (lokal deklarierte) Variable i eingebaut, der ja extra vor dem Aufruf der Funktion ein Wert zugewiesen wird, unmittelbar danach wird aber nicht der erwartete Wert, sondern ein komplett anderer Wert in der Messagebox angezeigt (was ja auch nicht weiter verwunderlich ist, wenn der Stackpointer komplett daneben liegt...)

Hat jemand eine Idee, was da die Ursache sein könnte?
Ich habe zwar betreffend ADSI / Delphi einiges im Gooooogle gefunden, aber nie wurde irgend ein ähnliches Problem berichtet.
das einzige was annähernd mein Problem beschreibt habe ich hier gefunden
Miniaturansicht angehängter Grafiken
nach_aufruf_680.jpg   vor_aufruf_190.jpg  
  Mit Zitat antworten Zitat
Alex O.

Registriert seit: 30. Apr 2007
8 Beiträge
 
Delphi 2010 Enterprise
 
#2

Re: ADSI, Stackproblem

  Alt 12. Sep 2009, 12:24
mit etwas Glück konnte ich def Fehler selbst finden :-)

für die Nachwelt, hier meine Lösung:

das DADUser._Release darf nicht (!) aufgerufen werden - statt dessen direkt NIL zuweisen, und schon geht's besser (Zumindest kommt der Stack nicht mehr durcheinander)

Delphi-Quellcode:
finally
  //if DADUser <> nil then
  // DADUser._Release;
  DADUser:=nil;
  ...
end;
Ausserdem musste meine Function so aufrufen
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.

vielleicht kann das ja mal jemandem helfen!
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema 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 20:20 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