procedure TEADSObject.EnumObjectsOfContainer(CallbackFunction: TCallbackResultArray; Attributes:
string = '
Name;AdsPath;'; AdsPath:
string = '
ROOTDSE');
var
search: IDirectorySearch;
ptrResult: ADS_SEARCH_HANDLE;
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 AdsPath = '
ROOTDSE'
then
AdsPath := AdsMgr.ADSController.LDAPPATH;
// get the search object
if SUCCEEDED(AccessObject(AdsPath, 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_ONELEVEL;
// <<---------------------------- irgendwie wird das nicht richtig gesetzt!?
// 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('
(objectCategory=*)', @AttrArray[0], dwCount, ptrResult);
// handle the result if hr is S_OK
if SUCCEEDED(hr)
then
begin
hr := search.GetNextRow(ptrResult);
while hr <> S_ADS_NOMORE_ROWS
do
begin
// dim 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
if I = 0
then
begin
if ExtractContainerPath(col.pADsValues^.__MIDL_0010.BackLink.ObjectName) <> AdsPath
then
begin
search.FreeColumn(col);
break;
end;
end;
// dim 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
begin
// A CALLBACK AFTER EVERY SUCCEEDED ROW
CallBackFunction(ArrResult);
Inc(ArrResCnt);
end;
end;
end;
//search.CloseSearchHandle(ptrResult);
except
//search._Release;
on e: EOleException
do
AdsMgr.SetLastError(e.
Message);
end;
end;
end;