The following method is used to read the user list and organizational structure in AD:Bool readadtree (lpwstr strldapurl) <br/>{< br/> bool Bret = false; <br/> hresult hr; <br/> iadscontainer * pcontainer = NULL; <br/> ienumvariant * penum = NULL; <br/> int Pos =-1; <br/> variant varchild; <br/> Iads * pads1 = NULL; <br/> lpwstr strname, strdisplayname, strnewurl; <br/> BSTR bstrvalue; <br/> ccombstr bstrguid; <br/> variant varloginname; // login name <br/> lpwstr strloginname; // login name </P> <p> lpwstr strprefi X = l "LDAP: //"; // prefix <br/> int Nt = wcslen (strprefix); <br/> lpwstr strobjurl = strldapurl + nt; // address </P> <p> int nchildcount = 0; </P> <p> // <br/> // open the object <br/> // <br/> hR = adsgetobject (strldapurl, iid_iadscontainer, (void **) & pcontainer); </P> <p> If (s_ OK! = HR) <br/>{< br/> goto label_exit; <br/>}</P> <p> // <br/> // obtain the object enumerator <br/> // </P> <p> hR = adsbuildenumerator (pcontainer, & penum); <br/> If (s_ OK! = HR) <br/>{< br/> goto label_exit; <br/>}</P> <p> // <br/> // subitem of the enumerated object <br/> // </P> <p> while (1) <br/>{< br/> hR = adsenumeratenext (penum, 1, & varchild, null); <br/> If (s_false = HR) // If the subitem is null, exit <br/>{< br/> Bret = true; <br/> goto label_exit; <br/>}</P> <p> nchildcount ++; <br/> hR = varchild. pdispval-> QueryInterface (iid_iads, (void **) & pads1); <br/> If (s_ OK! = HR) // The API does not support <br/>{< br/> continue; <br/>}</P> <p> // <br/> // Object Name (Format: xx = ???, XX indicates the type ,??? <Br/> // </P> <p> hR = pads1-> get_name (& bstrvalue); <br/> strname = bstrvalue; <br/> // wchar C [512]; <br/> // swprintf (wchar *) C, L "/t hell name -------- LDAP: // % s/n ", strname); <br/> // outputdebugstringw (C ); <br/> // obtain the logon name <br/> // <br/> variantinit (& varloginname ); </P> <p> hR = pads1-> get (L "userprincipalname", & varloginname); <br/> switch (varloginname. vt) <br/>{< br/> case vt_bstr: // string <br/>{< br/> Str Loginname = varloginname. bstrval; <br/>}< br/> break; <br/> default: <br/> strloginname = l "; <br/> break; <br/>}</P> <p> // <br/> // remove the = character <br/> // <br/> lpwstr lpsz = wcschr (strname, (_ tuchar) '='); <br/> Pos = (lpsz = NULL )? -1: (INT) (lpsz-strname); </P> <p> If (Pos> 0) <br/>{< br/> strdisplayname = strname + POS + 1; <br/>}< br/> else <br/>{< br/> strdisplayname = strname; <br/>}// end </P> <p> lpsz = wcsstr (strname, l "ou"); <br/> Pos = (lpsz = NULL )? -1: (INT) (lpsz-strname); </P> <p> If (! Pos) <br/>{< br/> // todo <br/>}< br/> else <br/>{</P> <p >}</P> <p> // <br/> // construct the URL of the current object, recursive search <br/> // <br/> wchar CC [512]; <br/> swprintf (wchar *) CC, l "LDAP: // % s, % s ", strname, strobjurl); <br/> wchar CCC [512]; <br/> swprintf (wchar *) CCC, l"/t hell ladp -------- LDAP: // % s, % s/n ", strname, strobjurl); <br/> outputdebugstringw (CCC); <br/> readadtree (CC ); </P> <p> ///////////////////////////////// //// // <br/>}</P> <p> label_exit: </P> <p> If (pads1) <br/>{< br/> pads1-> release (); <br/>}</P> <p> // If (penum) // because smart point is used, you do not need to manually release <br/> // {<br/> // penum-> release (); <br/> //} </P> <p> If (pcontainer) <br/>{< br/> pcontainer-> release (); <br/>}</P> <p> return Bret; <br/>}</P> <p> int wmain (INT argc, char * argv []) <br/>{< br/> coinitialize (null); </P> <p> readadtree (L "LDAP: // ou = user, Dc = bydhq, dc = com, Dc = cn "); <br/> couninitialize (); <br/> return 0; <br/>}