![]() |
Zugriffsverletzung ADSI, so was komisches hab ich noch nie..
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Leute
Langsam aber sicher verzweifle ich an folgender Problematik: - Ich arbeite an einem Benutzerfreundlichen AD Programm, Benutzer erstellen, ändern löschen usw. - Ich verwende folgene Units: ADsTLB, adshlp, AdsErr (Im Download enthalten) Zum Problem... Ich arbeite in diesem Zusammenhang an einer Unit, die den Zugriff aufs AD sehr simpel gestalten soll. Nun kommt es sehr oft zu "unerklärlichen" Zugriffsverletzungen. Schauen wir uns folgendes Beispiel an:
Delphi-Quellcode:
Ach ja, wenn die Exe nicht in der Entwicklungsumgebung gestartet wird, erscheint nicht mal eine Fehlermeldung, das Programm beentet einfach automatisch!// Endet in Zugriffsverletzung procedure TForm1.Button1Click(Sender: TObject); begin ADsMgr.ADSGroups.EnumAllGroups(CBF); Caption := 'Zugriffsverletzung'; // <-- Zugriffsverletzung immer bei der darauf folgenden Zeile, egal was hier steht. end; // Endet NICHT in Zugriffsverletung procedure TForm1.Button2Click(Sender: TObject); begin DUMMY; Caption := 'KEINE Zugriffsverletzung'; end; // Dummy function ermöglicht das Ausführen der Funktion ohne Zugriffsverletzung procedure TForm1.DUMMY; begin ADsMgr.ADSGroups.EnumAllGroups(CBF); end; Ihr könnt euch das Beispielprogramm gerne mal anschauen. Ich versteh die Welt nicht mehr :stupid: |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
ich habe mir das Projekt jetzt noch nicht runtergeladen, sondern glaube einfach mal deiner Fehlerbeschreibung. :) Ähnliche Effekte habe ich auch ein bis zwei Mal im Jahr - normalerweise hat das dann mit der Stelle selbst, an der die AV auftritt, eher wenig zu tun, sondern liegt daran, dass ich mir irgendwie den Speicher zerschossen habe. Beliebte Ursachen dafür sind Zugriffe auf Objekte, die ich schon freigegeben hatte, oder falsche Typecasts, so dass ich auf Eigenschaften eines Objekts zugreifen möchte, die es gar nicht hat. Dass sich das Programm dann mit und ohne Debugger völlig anders verhalten hat, hatte ich dann auch gerne mal - klar, dann "liegt" ja sicherlich auch so einiges anders im Speicher und dadurch taucht dann die AV nicht auf. Viel Spaß beim Suchen. :) Bis denn Bommel |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Sowas passiert auch gerne, wenn man über die Länge einens Speicherbereichs hinausschreibt.
|
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
kann mich schwach ein ein ähnliches Problem in diesem Umfeld erinnern. Soweit ich das in Erinnerung behalten habe, ließ sich das Problem "simpel" lösen. Zuweisungen nur an lokale Variabeln machen und diese dann an die globeln Variablen... zuweisen. In Deinem Beispiel könnte dann eventuell unterumständen vielleicht ... folgendes helfen:
Delphi-Quellcode:
Bin mir aber absolut nicht sicher, ob ich hier jetzt eventuell doch irgendwas durcheinander werfe. Aber einen Versuch ist es ja vielleicht doch wert ;-)
// Endet hoffentlich nicht mehr in Zugriffsverletzung
procedure TForm1.Button1Click(Sender: TObject); Var sCaption : String; begin ADsMgr.ADSGroups.EnumAllGroups(CBF); sCaption := 'jetzt keine Zugriffsverletzung mehr' Caption := sCaption; // <-- Zugriffsverletzung nicht mehr immer bei der darauf folgenden Zeile, egal was hier steht. end; Der Fehler ist jedenfalls in den Innereien dieses Befehls zu suchen:
Delphi-Quellcode:
Wo ist CBF definiert, eventuell hilft hier eine Veränderung von global nach lokal oder rein in die Klasse oder raus aus der Klasse.
ADsMgr.ADSGroups.EnumAllGroups(CBF);
|
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
TStringArray2 -> array of array of String uiui ;) Hast du deinen CBF-Code mal ausgeklammert ? er sieht aber eigentlich OK aus. Könnte es sein, dass man hier WideString / AnsiString nehmen muss Du hast ja D2009, viell. hatte der Autor eine kleinere Delphi-Version. ? Das mit dem Abstürzen bekommst du übrigens mit try/except hin.
Delphi-Quellcode:
Das läßt sich besser Debuggen.
procedure TForm1.CBF(data: TStringArray2);
var X,Y : Integer; txt : String; txt1 : String; begin for X := Low(data) to High(data) do begin txt := ''; for Y := Low(data[X]) to High(data[X]) do begin txt1:= data[X,Y]; txt := txt + ' > ' + txt1; end; ListBox1.Items.Add(txt); end; end; Ev. hilft auch ein SetLength (auf txt und txt1). Intern (TEADSObject.DirectorySearch) wird ja auch mit SetLength gearbeitet. Heiko |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
Zitat:
Die Procedure ADsMgr.ADSGroups.EnumAllGroups ist bestandteil von meiner, eben angesprochenen, Unit die den Zugriff aufs AD sehr simpel gestalten soll. (Name der Unit EExtemporanousMumblings) Ich verwende in der ganzen Unit nur eine einzige Globale Variable und das ist die Klasse selbst: ADSManager: TADSManager; damit ich die Unit einfach einbinden und loslegen kann und nicht noch Instanzieren muss! Zitat:
Zitat:
Zitat:
Zitat:
Kennt jemand die Units: ADsTLB, adshlp, AdsErr ich find keine neueren Versionen. Zitat:
|
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Hallo,
Zitat:
Hast Du sCaption mal als globale Variabel deklariert? Kann mich leider nicht mehr erinnern, was ich seinerzeit wo und wie deklariert hatte, es war aber ziemlich abstruse und ein uneleganter Workaround. |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Zitat:
Ich habe mal versucht, das Problem hier nachzuvollziehen, bin allerdings nicht in einer AD-Umgebung, insofern macht das Programm bei mir auch nur eingeschränkt Sinn. Es meldet aber immerhin, dass es kein ActiveDirectory finden konnte (das fängst du übrigens nicht ab, wodurch dann nachher eine OleException geworfen wird, weil du immer davon ausgehst, dass etwas gefunden wurde) und dann ist alles gut. Ich habe das OnClick-Event mal zu
Delphi-Quellcode:
umgebaut. Eine AV gibt es bei mir nicht mehr. Das nur noch mal als bestätigender Hinweis, dass das Problem wahrscheinlich in den genutzten Units liegt.
procedure TForm1.Button1Click(Sender: TObject);
begin try ADsMgr.ADSGroups.EnumAllGroups(CBF); finally Caption := 'Zugriffsverletzung'; end; end; |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Huuuuch... Ich glaub ich hab da eine Spur. Die ADsTLB wurde im Jahre 2007 generiert. Könnte es wohl daran liegen?
Ich hab sie mal neu wrappen lassen... Nun habe ich aber bei meiner "DirectorySearch" Funktion probleme, ich krieg sie nicht mehr zum laufen: Folgende deklarationen haben geändert: von:
Delphi-Quellcode:
auf:
function GetNextRow(hSearchResult: THandle): HResult; stdcall;
function ExecuteSearch(pszSearchFilter: PWideChar; pAttributeNames: PWideChar; dwNumberAttributes: LongWord; out phSearchResult: THandle): HResult; stdcall; function GetColumn(hSearchResult: THandle; szColumnName: PWideChar; out pSearchColumn: ads_search_column): HResult; stdcall; function CloseSearchHandle(var hSearchResult: THandle): HResult; stdcall;
Delphi-Quellcode:
Es reicht aber dann nicht ptrResult auf Pointer zu ändern. Es gibt wieder eine Zugriffsverletzung (Stelle ist markiert). Jedoch stürzt das Programm danach nicht ab,
function GetNextRow(var hSearchResult: Pointer): HResult; stdcall;
function ExecuteSearch(pszSearchFilter: PWideChar; var pAttributeNames: PWideChar; dwNumberAttributes: LongWord; out phSearchResult: Pointer): HResult; stdcall; function GetColumn(var hSearchResult: Pointer; szColumnName: PWideChar; out pSearchColumn: ads_search_column): HResult; stdcall; function CloseSearchHandle(var hSearchResult: Pointer): HResult; stdcall; ist immerhin schon etwas. Kann mir jemand helfen?
Delphi-Quellcode:
procedure TEADSObject.DirectorySearch(searchfilter: string; CallBackFunction: TCallBackResultArray; Attributes: string = 'Name;AdsPath;'; LDAPBeginingPath: string = 'ROOTDSE');
var search: IDirectorySearch; ptrResult: POINTER; opt: ads_searchpref_info; dwCount: DWORD; hr: HResult; col: ads_search_column; dwErr: DWord; szErr : array[0..255] of Char; szName : array[0..255] of Char; 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(AdsGetObject(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(StringToOleStr(searchfilter), AttrArray[0], dwCount, ptrResult); // handle the result if hr is S_OK if SUCCEEDED(hr) then begin // get first row hr := search.GetNextRow(ptrResult); // <------------ Dies löst den Fehler aus !!!! // repeat until no more rows while (hr <> S_ADS_NOMORE_ROWS) do 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(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.BackLink.ObjectName; empty := false; end; search.FreeColumn(col); end; end; hr := search.GetNextRow(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); finally search._Release; end; end; if Length(ArrResult) > 0 then CallBackFunction(ArrResult); end; |
Re: Zugriffsverletzung ADSI, so was komisches hab ich noch n
Das deklarationsproblem hatten wir schon mal
![]() Habe nun die Pointer in THandles geändert, kompilieren geht, nur der Fehler tritt am selben Ort auf. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz