public class RecursiveLinkPair
{
DirectoryEntry entry;
ArrayList members;
Hashtable processed;
string attrib;
bool includeAll;
public RecursiveLinkPair(DirectoryEntry entry, string attrib, bool includeIntermediate)
{
if (entry == null)
throw new ArgumentNullException("entry");
if (String.IsNullOrEmpty(attrib))
throw new ArgumentException("attrib");
this.includeAll = includeIntermediate;
this.attrib = attrib;
this.entry = entry;
this.processed = new Hashtable();
this.processed.Add(
this.entry.Properties[
"distinguishedName"][0].ToString(),
null
);
this.members = Expand(this.entry);
}
public ArrayList Members
{
get { return this.members; }
}
private ArrayList Expand(DirectoryEntry group)
{
ArrayList al = new ArrayList(5000);
DirectorySearcher ds = new DirectorySearcher(
entry,
"(objectClass=*)",
new string[] {
this.attrib,
"distinguishedName",
"objectClass" },
SearchScope.Base
);
ds.AttributeScopeQuery = this.attrib;
ds.PageSize = 1000;
using (SearchResultCollection src = ds.FindAll())
{
string dn = null;
foreach (SearchResult sr in src)
{
dn = (string)
sr.Properties["distinguishedName"][0];
if (!this.processed.ContainsKey(dn))
{
this.processed.Add(dn, null);
if (sr.Properties.Contains(this.attrib))
{
if (this.includeAll)
al.Add(dn);
SetNewPath(this.entry, dn);
al.AddRange(Expand(this.entry));
}
else
al.Add(dn);
}
}
}
return al;
}
//we will use IADsPathName utility function instead
//of parsing string values. This particular function
//allows us to replace only the DN portion of a path
//and leave the server and port information intact
private void SetNewPath(DirectoryEntry entry, string dn)
{
IAdsPathname pathCracker = (IAdsPathname)new Pathname();
pathCracker.Set(entry.Path, 1);
pathCracker.Set(dn, 4);
entry.Path = pathCracker.Retrieve(5);
}
}