Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1578 lines
34 KiB

  1. #pragma once
  2. #include <map>
  3. #include <string>
  4. #include <vector>
  5. #include <TChar.h>
  6. #include <ComDef.h>
  7. #include <ActiveDS.h>
  8. #ifndef tstring
  9. typedef std::basic_string<_TCHAR> tstring;
  10. #endif
  11. #ifndef IADsPtr
  12. _COM_SMARTPTR_TYPEDEF(IADs, IID_IADs);
  13. #endif
  14. #ifndef IADsContainerPtr
  15. _COM_SMARTPTR_TYPEDEF(IADsContainer, IID_IADsContainer);
  16. #endif
  17. #ifndef IADsUserPtr
  18. _COM_SMARTPTR_TYPEDEF(IADsUser, IID_IADsUser);
  19. #endif
  20. #ifndef IADsADSystemInfoPtr
  21. _COM_SMARTPTR_TYPEDEF(IADsADSystemInfo, IID_IADsADSystemInfo);
  22. #endif
  23. #ifndef IADsPathnamePtr
  24. _COM_SMARTPTR_TYPEDEF(IADsPathname, IID_IADsPathname);
  25. #endif
  26. #ifndef IDirectoryObjectPtr
  27. _COM_SMARTPTR_TYPEDEF(IDirectoryObject, IID_IDirectoryObject);
  28. #endif
  29. #ifndef IADsDeleteOpsPtr
  30. _COM_SMARTPTR_TYPEDEF(IADsDeleteOps, IID_IADsDeleteOps);
  31. #endif
  32. #ifndef IDirectorySearchPtr
  33. _COM_SMARTPTR_TYPEDEF(IDirectorySearch, IID_IDirectorySearch);
  34. #endif
  35. //---------------------------------------------------------------------------
  36. // CADs Class
  37. //---------------------------------------------------------------------------
  38. class CADs
  39. {
  40. public:
  41. CADs(IADsPtr spADs) :
  42. m_spADs(spADs)
  43. {
  44. }
  45. CADs(LPCTSTR pszADsPath = NULL)
  46. {
  47. if (pszADsPath)
  48. {
  49. CheckResult(ADsGetObject(pszADsPath, IID_IADs, (VOID**)&m_spADs));
  50. }
  51. }
  52. CADs(const CADs& r) :
  53. m_spADs(r.m_spADs)
  54. {
  55. }
  56. operator bool() const
  57. {
  58. return m_spADs;
  59. }
  60. operator IADs*() const
  61. {
  62. return m_spADs;
  63. }
  64. CADs& operator =(IADsPtr spADs)
  65. {
  66. m_spADs = spADs;
  67. return *this;
  68. }
  69. CADs& operator =(const CADs& r)
  70. {
  71. m_spADs = r.m_spADs;
  72. return *this;
  73. }
  74. _bstr_t GetName()
  75. {
  76. BSTR bstr;
  77. CheckResult(m_spADs->get_Name(&bstr));
  78. return _bstr_t(bstr, false);
  79. }
  80. _bstr_t GetClass()
  81. {
  82. BSTR bstr;
  83. CheckResult(m_spADs->get_Class(&bstr));
  84. return _bstr_t(bstr, false);
  85. }
  86. _bstr_t GetGUID()
  87. {
  88. BSTR bstr;
  89. CheckResult(m_spADs->get_GUID(&bstr));
  90. return _bstr_t(bstr, false);
  91. }
  92. _bstr_t GetADsPath()
  93. {
  94. BSTR bstr;
  95. CheckResult(m_spADs->get_ADsPath(&bstr));
  96. return _bstr_t(bstr, false);
  97. }
  98. _bstr_t GetParent()
  99. {
  100. BSTR bstr;
  101. CheckResult(m_spADs->get_Parent(&bstr));
  102. return _bstr_t(bstr, false);
  103. }
  104. _bstr_t GetSchema()
  105. {
  106. BSTR bstr;
  107. CheckResult(m_spADs->get_Schema(&bstr));
  108. return _bstr_t(bstr, false);
  109. }
  110. void GetInfo()
  111. {
  112. CheckResult(m_spADs->GetInfo());
  113. }
  114. void SetInfo()
  115. {
  116. CheckResult(m_spADs->SetInfo());
  117. }
  118. _variant_t Get(_bstr_t strName)
  119. {
  120. VARIANT vnt;
  121. VariantInit(&vnt);
  122. CheckResult(m_spADs->Get(strName, &vnt));
  123. return _variant_t(vnt, false);
  124. }
  125. void Put(_bstr_t strName, const _variant_t& vntValue)
  126. {
  127. CheckResult(m_spADs->Put(strName, vntValue));
  128. }
  129. _variant_t GetEx(_bstr_t strName)
  130. {
  131. VARIANT vnt;
  132. VariantInit(&vnt);
  133. CheckResult(m_spADs->GetEx(strName, &vnt));
  134. return _variant_t(vnt, false);
  135. }
  136. void PutEx(long lControlCode, _bstr_t strName, const _variant_t& vntValue)
  137. {
  138. CheckResult(m_spADs->PutEx(lControlCode, strName, vntValue));
  139. }
  140. void GetInfoEx(const _variant_t& vntProperties, long lReserved)
  141. {
  142. CheckResult(m_spADs->GetInfoEx(vntProperties, lReserved));
  143. }
  144. protected:
  145. void CheckResult(HRESULT hr)
  146. {
  147. if (FAILED(hr))
  148. {
  149. _com_issue_errorex(hr, IUnknownPtr(m_spADs), IID_IADs);
  150. }
  151. }
  152. protected:
  153. IADsPtr m_spADs;
  154. };
  155. //---------------------------------------------------------------------------
  156. // CADsContainer Class
  157. //---------------------------------------------------------------------------
  158. class CADsContainer : public CADs
  159. {
  160. protected:
  161. void CheckResult(HRESULT hr)
  162. {
  163. if (FAILED(hr))
  164. {
  165. _com_issue_errorex(hr, IUnknownPtr(m_spADsContainer), IID_IADsContainer);
  166. }
  167. }
  168. public:
  169. CADsContainer(IADsContainerPtr spADsContainer) :
  170. CADs(spADsContainer),
  171. m_spADsContainer(spADsContainer)
  172. {
  173. }
  174. CADsContainer(LPCTSTR pszADsPath = NULL) :
  175. CADs(pszADsPath)
  176. {
  177. m_spADsContainer = m_spADs;
  178. }
  179. CADsContainer(const CADsContainer& r) :
  180. CADs(r),
  181. m_spADsContainer(r.m_spADsContainer)
  182. {
  183. }
  184. operator bool() const
  185. {
  186. return m_spADsContainer;
  187. }
  188. operator IADsContainer*() const
  189. {
  190. return m_spADsContainer;
  191. }
  192. CADsContainer& operator =(IADsContainerPtr spADsContainer)
  193. {
  194. m_spADs = spADsContainer;
  195. m_spADsContainer = spADsContainer;
  196. return *this;
  197. }
  198. CADsContainer& operator =(const CADsContainer& r)
  199. {
  200. m_spADs = r.m_spADs;
  201. m_spADsContainer = r.m_spADsContainer;
  202. return *this;
  203. }
  204. long GetCount()
  205. {
  206. long l;
  207. CheckResult(m_spADsContainer->get_Count(&l));
  208. return l;
  209. }
  210. IEnumVARIANTPtr GetEnumerator()
  211. {
  212. IUnknown* punk;
  213. CheckResult(m_spADsContainer->get__NewEnum(&punk));
  214. return IEnumVARIANTPtr(IUnknownPtr(punk, false));
  215. }
  216. _variant_t GetFilter()
  217. {
  218. VARIANT vnt;
  219. VariantInit(&vnt);
  220. CheckResult(m_spADsContainer->get_Filter(&vnt));
  221. return _variant_t(vnt, false);
  222. }
  223. void SetFilter(const _variant_t& vnt)
  224. {
  225. CheckResult(m_spADsContainer->put_Filter(vnt));
  226. }
  227. _variant_t GetHints()
  228. {
  229. VARIANT vnt;
  230. VariantInit(&vnt);
  231. CheckResult(m_spADsContainer->get_Hints(&vnt));
  232. return _variant_t(vnt, false);
  233. }
  234. void SetHints(const _variant_t& vnt)
  235. {
  236. CheckResult(m_spADsContainer->put_Hints(vnt));
  237. }
  238. IDispatchPtr GetObject(_bstr_t strClassName, _bstr_t strRelativeName)
  239. {
  240. IDispatch* pdisp;
  241. CheckResult(m_spADsContainer->GetObject(strClassName, strRelativeName, &pdisp));
  242. return IDispatchPtr(pdisp, false);
  243. }
  244. IDispatchPtr Create(_bstr_t strClassName, _bstr_t strRelativeName)
  245. {
  246. IDispatch* pdisp;
  247. CheckResult(m_spADsContainer->Create(strClassName, strRelativeName, &pdisp));
  248. return IDispatchPtr(pdisp, false);
  249. }
  250. void Delete(_bstr_t strClassName, _bstr_t strRelativeName)
  251. {
  252. CheckResult(m_spADsContainer->Delete(strClassName, strRelativeName));
  253. }
  254. IDispatchPtr CopyHere(_bstr_t strSourceName, _bstr_t strNewName)
  255. {
  256. IDispatch* pdisp;
  257. CheckResult(m_spADsContainer->CopyHere(strSourceName, strNewName, &pdisp));
  258. return IDispatchPtr(pdisp, false);
  259. }
  260. IDispatchPtr MoveHere(_bstr_t strSourceName, _bstr_t strNewName)
  261. {
  262. IDispatch* pdisp;
  263. CheckResult(m_spADsContainer->MoveHere(strSourceName, strNewName, &pdisp));
  264. return IDispatchPtr(pdisp, false);
  265. }
  266. protected:
  267. IADsContainerPtr m_spADsContainer;
  268. };
  269. //---------------------------------------------------------------------------
  270. // CADsUser Class
  271. //---------------------------------------------------------------------------
  272. class CADsUser : public CADs
  273. {
  274. public:
  275. CADsUser(IADsUserPtr spADsUser) :
  276. CADs(spADsUser),
  277. m_spADsUser(spADsUser)
  278. {
  279. }
  280. CADsUser(LPCTSTR pszADsPath = NULL) :
  281. CADs(pszADsPath)
  282. {
  283. m_spADsUser = m_spADs;
  284. }
  285. CADsUser(const CADsUser& r) :
  286. CADs(r),
  287. m_spADsUser(r.m_spADsUser)
  288. {
  289. }
  290. operator bool() const
  291. {
  292. return m_spADsUser;
  293. }
  294. operator IADsUser*() const
  295. {
  296. return m_spADsUser;
  297. }
  298. CADsUser& operator =(IADsUserPtr spADsUser)
  299. {
  300. m_spADs = spADsUser;
  301. m_spADsUser = spADsUser;
  302. return *this;
  303. }
  304. CADsUser& operator =(const CADsUser& r)
  305. {
  306. m_spADs = r.m_spADs;
  307. m_spADsUser = r.m_spADsUser;
  308. return *this;
  309. }
  310. _bstr_t GetBadLoginAddress()
  311. {
  312. BSTR bstr;
  313. CheckResult(m_spADsUser->get_BadLoginAddress(&bstr));
  314. return _bstr_t(bstr, false);
  315. }
  316. DATE GetLastLogin()
  317. {
  318. DATE d;
  319. CheckResult(m_spADsUser->get_LastLogin(&d));
  320. return d;
  321. }
  322. DATE GetLastLogoff()
  323. {
  324. DATE d;
  325. CheckResult(m_spADsUser->get_LastLogoff(&d));
  326. return d;
  327. }
  328. DATE GetLastFailedLogin()
  329. {
  330. DATE d;
  331. CheckResult(m_spADsUser->get_LastFailedLogin(&d));
  332. return d;
  333. }
  334. DATE GetPasswordLastChanged()
  335. {
  336. DATE d;
  337. CheckResult(m_spADsUser->get_PasswordLastChanged(&d));
  338. return d;
  339. }
  340. _bstr_t GetDescription()
  341. {
  342. BSTR bstr;
  343. CheckResult(m_spADsUser->get_Description(&bstr));
  344. return _bstr_t(bstr, false);
  345. }
  346. void SetDescription(_bstr_t strDescription)
  347. {
  348. CheckResult(m_spADsUser->put_Description(strDescription));
  349. }
  350. _bstr_t GetDivision()
  351. {
  352. BSTR bstr;
  353. CheckResult(m_spADsUser->get_Division(&bstr));
  354. return _bstr_t(bstr, false);
  355. }
  356. void SetDivision(_bstr_t strDivision)
  357. {
  358. CheckResult(m_spADsUser->put_Division(strDivision));
  359. }
  360. _bstr_t GetDepartment()
  361. {
  362. BSTR bstr;
  363. CheckResult(m_spADsUser->get_Department(&bstr));
  364. return _bstr_t(bstr, false);
  365. }
  366. void SetDepartment(_bstr_t strDepartment)
  367. {
  368. CheckResult(m_spADsUser->put_Department(strDepartment));
  369. }
  370. _bstr_t GetEmployeeId()
  371. {
  372. BSTR bstr;
  373. CheckResult(m_spADsUser->get_EmployeeID(&bstr));
  374. return _bstr_t(bstr, false);
  375. }
  376. void SetEmployeeId(_bstr_t strEmployeeId)
  377. {
  378. CheckResult(m_spADsUser->put_EmployeeID(strEmployeeId));
  379. }
  380. _bstr_t GetFullName()
  381. {
  382. BSTR bstr;
  383. CheckResult(m_spADsUser->get_FullName(&bstr));
  384. return _bstr_t(bstr, false);
  385. }
  386. void SetFullName(_bstr_t strFullName)
  387. {
  388. CheckResult(m_spADsUser->put_FullName(strFullName));
  389. }
  390. _bstr_t GetFirstName()
  391. {
  392. BSTR bstr;
  393. CheckResult(m_spADsUser->get_FirstName(&bstr));
  394. return _bstr_t(bstr, false);
  395. }
  396. void SetFirstName(_bstr_t strFirstName)
  397. {
  398. CheckResult(m_spADsUser->put_FirstName(strFirstName));
  399. }
  400. _bstr_t GetLastName()
  401. {
  402. BSTR bstr;
  403. CheckResult(m_spADsUser->get_LastName(&bstr));
  404. return _bstr_t(bstr, false);
  405. }
  406. void SetLastName(_bstr_t strLastName)
  407. {
  408. CheckResult(m_spADsUser->put_LastName(strLastName));
  409. }
  410. _bstr_t GetOtherName()
  411. {
  412. BSTR bstr;
  413. CheckResult(m_spADsUser->get_OtherName(&bstr));
  414. return _bstr_t(bstr, false);
  415. }
  416. void SetOtherName(_bstr_t strOtherName)
  417. {
  418. CheckResult(m_spADsUser->put_OtherName(strOtherName));
  419. }
  420. _bstr_t GetNamePrefix()
  421. {
  422. BSTR bstr;
  423. CheckResult(m_spADsUser->get_NamePrefix(&bstr));
  424. return _bstr_t(bstr, false);
  425. }
  426. void SetNamePrefix(_bstr_t strNamePrefix)
  427. {
  428. CheckResult(m_spADsUser->put_NamePrefix(strNamePrefix));
  429. }
  430. _bstr_t GetNameSuffix()
  431. {
  432. BSTR bstr;
  433. CheckResult(m_spADsUser->get_NameSuffix(&bstr));
  434. return _bstr_t(bstr, false);
  435. }
  436. void SetNameSuffix(_bstr_t strNameSuffix)
  437. {
  438. CheckResult(m_spADsUser->put_NameSuffix(strNameSuffix));
  439. }
  440. _bstr_t GetTitle()
  441. {
  442. BSTR bstr;
  443. CheckResult(m_spADsUser->get_Title(&bstr));
  444. return _bstr_t(bstr, false);
  445. }
  446. void SetTitle(_bstr_t strTitle)
  447. {
  448. CheckResult(m_spADsUser->put_Title(strTitle));
  449. }
  450. _bstr_t GetManager()
  451. {
  452. BSTR bstr;
  453. CheckResult(m_spADsUser->get_Manager(&bstr));
  454. return _bstr_t(bstr, false);
  455. }
  456. void SetManager(_bstr_t strManager)
  457. {
  458. CheckResult(m_spADsUser->put_Manager(strManager));
  459. }
  460. /*
  461. virtual HRESULT STDMETHODCALLTYPE get_TelephoneHome(
  462. VARIANT __RPC_FAR *retval) = 0;
  463. virtual HRESULT STDMETHODCALLTYPE put_TelephoneHome(
  464. VARIANT vTelephoneHome) = 0;
  465. virtual HRESULT STDMETHODCALLTYPE get_TelephoneMobile(
  466. VARIANT __RPC_FAR *retval) = 0;
  467. virtual HRESULT STDMETHODCALLTYPE put_TelephoneMobile(
  468. VARIANT vTelephoneMobile) = 0;
  469. virtual HRESULT STDMETHODCALLTYPE get_TelephoneNumber(
  470. VARIANT __RPC_FAR *retval) = 0;
  471. virtual HRESULT STDMETHODCALLTYPE put_TelephoneNumber(
  472. VARIANT vTelephoneNumber) = 0;
  473. virtual HRESULT STDMETHODCALLTYPE get_TelephonePager(
  474. VARIANT __RPC_FAR *retval) = 0;
  475. virtual HRESULT STDMETHODCALLTYPE put_TelephonePager(
  476. VARIANT vTelephonePager) = 0;
  477. virtual HRESULT STDMETHODCALLTYPE get_FaxNumber(
  478. VARIANT __RPC_FAR *retval) = 0;
  479. virtual HRESULT STDMETHODCALLTYPE put_FaxNumber(
  480. VARIANT vFaxNumber) = 0;
  481. virtual HRESULT STDMETHODCALLTYPE get_OfficeLocations(
  482. VARIANT __RPC_FAR *retval) = 0;
  483. virtual HRESULT STDMETHODCALLTYPE put_OfficeLocations(
  484. VARIANT vOfficeLocations) = 0;
  485. virtual HRESULT STDMETHODCALLTYPE get_PostalAddresses(
  486. VARIANT __RPC_FAR *retval) = 0;
  487. virtual HRESULT STDMETHODCALLTYPE put_PostalAddresses(
  488. VARIANT vPostalAddresses) = 0;
  489. virtual HRESULT STDMETHODCALLTYPE get_PostalCodes(
  490. VARIANT __RPC_FAR *retval) = 0;
  491. virtual HRESULT STDMETHODCALLTYPE put_PostalCodes(
  492. VARIANT vPostalCodes) = 0;
  493. virtual HRESULT STDMETHODCALLTYPE get_SeeAlso(
  494. VARIANT __RPC_FAR *retval) = 0;
  495. virtual HRESULT STDMETHODCALLTYPE put_SeeAlso(
  496. VARIANT vSeeAlso) = 0;
  497. */
  498. bool GetAccountDisabled()
  499. {
  500. VARIANT_BOOL b;
  501. CheckResult(m_spADsUser->get_AccountDisabled(&b));
  502. return b ? true : false;
  503. }
  504. void SetAccountDisabled(bool bAccountDisabled)
  505. {
  506. CheckResult(m_spADsUser->put_AccountDisabled(bAccountDisabled ? VARIANT_TRUE : VARIANT_FALSE));
  507. }
  508. /*
  509. virtual HRESULT STDMETHODCALLTYPE get_AccountExpirationDate(
  510. DATE __RPC_FAR *retval) = 0;
  511. virtual HRESULT STDMETHODCALLTYPE put_AccountExpirationDate(
  512. DATE daAccountExpirationDate) = 0;
  513. virtual HRESULT STDMETHODCALLTYPE get_GraceLoginsAllowed(
  514. long __RPC_FAR *retval) = 0;
  515. virtual HRESULT STDMETHODCALLTYPE put_GraceLoginsAllowed(
  516. long lnGraceLoginsAllowed) = 0;
  517. virtual HRESULT STDMETHODCALLTYPE get_GraceLoginsRemaining(
  518. long __RPC_FAR *retval) = 0;
  519. virtual HRESULT STDMETHODCALLTYPE put_GraceLoginsRemaining(
  520. long lnGraceLoginsRemaining) = 0;
  521. virtual HRESULT STDMETHODCALLTYPE get_IsAccountLocked(
  522. VARIANT_BOOL __RPC_FAR *retval) = 0;
  523. virtual HRESULT STDMETHODCALLTYPE put_IsAccountLocked(
  524. VARIANT_BOOL fIsAccountLocked) = 0;
  525. virtual HRESULT STDMETHODCALLTYPE get_LoginHours(
  526. VARIANT __RPC_FAR *retval) = 0;
  527. virtual HRESULT STDMETHODCALLTYPE put_LoginHours(
  528. VARIANT vLoginHours) = 0;
  529. virtual HRESULT STDMETHODCALLTYPE get_LoginWorkstations(
  530. VARIANT __RPC_FAR *retval) = 0;
  531. virtual HRESULT STDMETHODCALLTYPE put_LoginWorkstations(
  532. VARIANT vLoginWorkstations) = 0;
  533. virtual HRESULT STDMETHODCALLTYPE get_MaxLogins(
  534. long __RPC_FAR *retval) = 0;
  535. virtual HRESULT STDMETHODCALLTYPE put_MaxLogins(
  536. long lnMaxLogins) = 0;
  537. virtual HRESULT STDMETHODCALLTYPE get_MaxStorage(
  538. long __RPC_FAR *retval) = 0;
  539. virtual HRESULT STDMETHODCALLTYPE put_MaxStorage(
  540. long lnMaxStorage) = 0;
  541. virtual HRESULT STDMETHODCALLTYPE get_PasswordExpirationDate(
  542. DATE __RPC_FAR *retval) = 0;
  543. virtual HRESULT STDMETHODCALLTYPE put_PasswordExpirationDate(
  544. DATE daPasswordExpirationDate) = 0;
  545. virtual HRESULT STDMETHODCALLTYPE get_PasswordMinimumLength(
  546. long __RPC_FAR *retval) = 0;
  547. virtual HRESULT STDMETHODCALLTYPE put_PasswordMinimumLength(
  548. long lnPasswordMinimumLength) = 0;
  549. virtual HRESULT STDMETHODCALLTYPE get_PasswordRequired(
  550. VARIANT_BOOL __RPC_FAR *retval) = 0;
  551. virtual HRESULT STDMETHODCALLTYPE put_PasswordRequired(
  552. VARIANT_BOOL fPasswordRequired) = 0;
  553. virtual HRESULT STDMETHODCALLTYPE get_RequireUniquePassword(
  554. VARIANT_BOOL __RPC_FAR *retval) = 0;
  555. virtual HRESULT STDMETHODCALLTYPE put_RequireUniquePassword(
  556. VARIANT_BOOL fRequireUniquePassword) = 0;
  557. virtual HRESULT STDMETHODCALLTYPE get_EmailAddress(
  558. BSTR __RPC_FAR *retval) = 0;
  559. virtual HRESULT STDMETHODCALLTYPE put_EmailAddress(
  560. BSTR bstrEmailAddress) = 0;
  561. virtual HRESULT STDMETHODCALLTYPE get_HomeDirectory(
  562. BSTR __RPC_FAR *retval) = 0;
  563. virtual HRESULT STDMETHODCALLTYPE put_HomeDirectory(
  564. BSTR bstrHomeDirectory) = 0;
  565. virtual HRESULT STDMETHODCALLTYPE get_Languages(
  566. VARIANT __RPC_FAR *retval) = 0;
  567. virtual HRESULT STDMETHODCALLTYPE put_Languages(
  568. VARIANT vLanguages) = 0;
  569. virtual HRESULT STDMETHODCALLTYPE get_Profile(
  570. BSTR __RPC_FAR *retval) = 0;
  571. virtual HRESULT STDMETHODCALLTYPE put_Profile(
  572. BSTR bstrProfile) = 0;
  573. virtual HRESULT STDMETHODCALLTYPE get_LoginScript(
  574. BSTR __RPC_FAR *retval) = 0;
  575. virtual HRESULT STDMETHODCALLTYPE put_LoginScript(
  576. BSTR bstrLoginScript) = 0;
  577. virtual HRESULT STDMETHODCALLTYPE get_Picture(
  578. VARIANT __RPC_FAR *retval) = 0;
  579. virtual HRESULT STDMETHODCALLTYPE put_Picture(
  580. VARIANT vPicture) = 0;
  581. virtual HRESULT STDMETHODCALLTYPE get_HomePage(
  582. BSTR __RPC_FAR *retval) = 0;
  583. virtual HRESULT STDMETHODCALLTYPE put_HomePage(
  584. BSTR bstrHomePage) = 0;
  585. virtual HRESULT STDMETHODCALLTYPE Groups(
  586. IADsMembers __RPC_FAR *__RPC_FAR *ppGroups) = 0;
  587. */
  588. void SetPassword(_bstr_t strNewPassword)
  589. {
  590. CheckResult(m_spADsUser->SetPassword(strNewPassword));
  591. }
  592. void ChangePassword(_bstr_t strOldPassword, _bstr_t strNewPassword)
  593. {
  594. CheckResult(m_spADsUser->ChangePassword(strOldPassword, strNewPassword));
  595. }
  596. protected:
  597. void CheckResult(HRESULT hr)
  598. {
  599. if (FAILED(hr))
  600. {
  601. _com_issue_errorex(hr, IUnknownPtr(m_spADsUser), IID_IADsUser);
  602. }
  603. }
  604. protected:
  605. IADsUserPtr m_spADsUser;
  606. };
  607. //---------------------------------------------------------------------------
  608. // CADsADSystemInfo Class
  609. //---------------------------------------------------------------------------
  610. class CADsADSystemInfo
  611. {
  612. public:
  613. CADsADSystemInfo() :
  614. m_sp(CLSID_ADSystemInfo)
  615. {
  616. }
  617. CADsADSystemInfo(IADsADSystemInfo* pADsADSystemInfo) :
  618. m_sp(pADsADSystemInfo)
  619. {
  620. }
  621. CADsADSystemInfo(const CADsADSystemInfo& r) :
  622. m_sp(r.m_sp)
  623. {
  624. }
  625. operator IADsADSystemInfo*() const
  626. {
  627. return m_sp;
  628. }
  629. _bstr_t GetUserName()
  630. {
  631. BSTR bstr;
  632. CheckResult(m_sp->get_UserName(&bstr));
  633. return _bstr_t(bstr, false);
  634. }
  635. _bstr_t GetComputerName()
  636. {
  637. BSTR bstr;
  638. CheckResult(m_sp->get_ComputerName(&bstr));
  639. return _bstr_t(bstr, false);
  640. }
  641. _bstr_t GetSiteName()
  642. {
  643. BSTR bstr;
  644. CheckResult(m_sp->get_SiteName(&bstr));
  645. return _bstr_t(bstr, false);
  646. }
  647. _bstr_t GetDomainShortName()
  648. {
  649. BSTR bstr;
  650. CheckResult(m_sp->get_DomainShortName(&bstr));
  651. return _bstr_t(bstr, false);
  652. }
  653. _bstr_t GetDomainDNSName()
  654. {
  655. BSTR bstr;
  656. CheckResult(m_sp->get_DomainDNSName(&bstr));
  657. return _bstr_t(bstr, false);
  658. }
  659. _bstr_t GetForestDNSName()
  660. {
  661. BSTR bstr;
  662. CheckResult(m_sp->get_ForestDNSName(&bstr));
  663. return _bstr_t(bstr, false);
  664. }
  665. _bstr_t GetPDCRoleOwner()
  666. {
  667. BSTR bstr;
  668. CheckResult(m_sp->get_PDCRoleOwner(&bstr));
  669. return _bstr_t(bstr, false);
  670. }
  671. _bstr_t GetSchemaRoleOwner()
  672. {
  673. BSTR bstr;
  674. CheckResult(m_sp->get_SchemaRoleOwner(&bstr));
  675. return _bstr_t(bstr, false);
  676. }
  677. bool GetIsNativeMode()
  678. {
  679. VARIANT_BOOL b;
  680. CheckResult(m_sp->get_IsNativeMode(&b));
  681. return b ? true : false;
  682. }
  683. _bstr_t GetAnyDCName()
  684. {
  685. BSTR bstr;
  686. CheckResult(m_sp->GetAnyDCName(&bstr));
  687. return _bstr_t(bstr, false);
  688. }
  689. _bstr_t GetDCSiteName(_bstr_t strServer)
  690. {
  691. BSTR bstr;
  692. CheckResult(m_sp->GetDCSiteName(strServer, &bstr));
  693. return _bstr_t(bstr, false);
  694. }
  695. void RefreshSchemaCache()
  696. {
  697. CheckResult(m_sp->RefreshSchemaCache());
  698. }
  699. _variant_t GetTrees()
  700. {
  701. VARIANT vnt;
  702. CheckResult(m_sp->GetTrees(&vnt));
  703. return _variant_t(vnt, false);
  704. }
  705. protected:
  706. void CheckResult(HRESULT hr)
  707. {
  708. if (FAILED(hr))
  709. {
  710. _com_issue_errorex(hr, IUnknownPtr(m_sp), IID_IADsADSystemInfo);
  711. }
  712. }
  713. protected:
  714. IADsADSystemInfoPtr m_sp;
  715. };
  716. //---------------------------------------------------------------------------
  717. // CADsPathName Class
  718. //---------------------------------------------------------------------------
  719. class CADsPathName
  720. {
  721. // ADS_DISPLAY_ENUM
  722. // ADS_DISPLAY_FULL = 1
  723. // ADS_DISPLAY_VALUE_ONLY = 2
  724. // ADS_FORMAT_ENUM
  725. // ADS_FORMAT_WINDOWS = 1
  726. // ADS_FORMAT_WINDOWS_NO_SERVER = 2
  727. // ADS_FORMAT_WINDOWS_DN = 3
  728. // ADS_FORMAT_WINDOWS_PARENT = 4
  729. // ADS_FORMAT_X500 = 5
  730. // ADS_FORMAT_X500_NO_SERVER = 6
  731. // ADS_FORMAT_X500_DN = 7
  732. // ADS_FORMAT_X500_PARENT = 8
  733. // ADS_FORMAT_SERVER = 9
  734. // ADS_FORMAT_PROVIDER = 10
  735. // ADS_FORMAT_LEAF = 11
  736. // ADS_SETTYPE_ENUM
  737. // ADS_SETTYPE_FULL = 1
  738. // ADS_SETTYPE_PROVIDER = 2
  739. // ADS_SETTYPE_SERVER = 3
  740. // ADS_SETTYPE_DN = 4
  741. public:
  742. CADsPathName(_bstr_t strPath = _bstr_t(), long lSetType = ADS_SETTYPE_FULL) :
  743. m_sp(CLSID_Pathname)
  744. {
  745. if (strPath.length() > 0)
  746. {
  747. CheckResult(m_sp->Set(strPath, lSetType));
  748. }
  749. }
  750. void Set(_bstr_t strADsPath, long lSetType)
  751. {
  752. CheckResult(m_sp->Set(strADsPath, lSetType));
  753. }
  754. void SetDisplayType(long lDisplayType)
  755. {
  756. CheckResult(m_sp->SetDisplayType(lDisplayType));
  757. }
  758. _bstr_t Retrieve(long lFormatType)
  759. {
  760. BSTR bstr;
  761. CheckResult(m_sp->Retrieve(lFormatType, &bstr));
  762. return _bstr_t(bstr, false);
  763. }
  764. long GetNumElements()
  765. {
  766. long l;
  767. CheckResult(m_sp->GetNumElements(&l));
  768. return l;
  769. }
  770. _bstr_t GetElement(long lElementIndex)
  771. {
  772. BSTR bstr;
  773. CheckResult(m_sp->GetElement(lElementIndex, &bstr));
  774. return _bstr_t(bstr, false);
  775. }
  776. void AddLeafElement(_bstr_t strLeafElement)
  777. {
  778. CheckResult(m_sp->AddLeafElement(strLeafElement));
  779. }
  780. void RemoveLeafElement()
  781. {
  782. CheckResult(m_sp->RemoveLeafElement());
  783. }
  784. CADsPathName CopyPath()
  785. {
  786. IDispatch* pdisp;
  787. CheckResult(m_sp->CopyPath(&pdisp));
  788. return CADsPathName(IADsPathnamePtr(IDispatchPtr(pdisp, false)));
  789. }
  790. _bstr_t GetEscapedElement(long lReserved, _bstr_t strInStr)
  791. {
  792. BSTR bstr;
  793. CheckResult(m_sp->GetEscapedElement(lReserved, strInStr, &bstr));
  794. return _bstr_t(bstr, false);
  795. }
  796. long GetEscapedMode()
  797. {
  798. long l;
  799. CheckResult(m_sp->get_EscapedMode(&l));
  800. return l;
  801. }
  802. void PutEscapedMode(long l)
  803. {
  804. CheckResult(m_sp->put_EscapedMode(l));
  805. }
  806. protected:
  807. CADsPathName(const CADsPathName& r) :
  808. m_sp(r.m_sp)
  809. {
  810. }
  811. CADsPathName(IADsPathnamePtr& r) :
  812. m_sp(r)
  813. {
  814. }
  815. void CheckResult(HRESULT hr)
  816. {
  817. if (FAILED(hr))
  818. {
  819. _com_issue_errorex(hr, IUnknownPtr(m_sp), IID_IADsPathname);
  820. }
  821. }
  822. protected:
  823. IADsPathnamePtr m_sp;
  824. };
  825. //---------------------------------------------------------------------------
  826. // Directory Attributes Class
  827. //---------------------------------------------------------------------------
  828. class CDirectoryAttributes :
  829. public std::map<tstring, _variant_t>
  830. {
  831. public:
  832. CDirectoryAttributes()
  833. {
  834. }
  835. //
  836. void AddAttribute(LPCTSTR pszName)
  837. {
  838. insert(value_type(tstring(pszName), _variant_t()));
  839. }
  840. void ClearValues()
  841. {
  842. for (iterator it = begin(); it != end(); it++)
  843. {
  844. it->second.Clear();
  845. }
  846. }
  847. const _variant_t& GetValue(LPCTSTR pszName) const
  848. {
  849. static _variant_t s_vntEmptyValue;
  850. const_iterator it = find(tstring(pszName));
  851. if (it != end())
  852. {
  853. return it->second;
  854. }
  855. else
  856. {
  857. return s_vntEmptyValue;
  858. }
  859. }
  860. void SetADsValue(LPCTSTR pszName, ADSTYPE atType, PADSVALUE pavValue, DWORD dwCount)
  861. {
  862. iterator it = find(tstring(pszName));
  863. if (it != end())
  864. {
  865. GetADsValue(atType, pavValue, dwCount, it->second);
  866. }
  867. }
  868. protected:
  869. void GetADsValue(ADSTYPE atType, PADSVALUE pavValue, DWORD dwCount, _variant_t& vntValue)
  870. {
  871. switch (atType)
  872. {
  873. case ADSTYPE_DN_STRING:
  874. {
  875. vntValue = pavValue->DNString;
  876. break;
  877. }
  878. case ADSTYPE_CASE_EXACT_STRING:
  879. {
  880. if (dwCount == 1)
  881. {
  882. vntValue = pavValue->CaseExactString;
  883. }
  884. else
  885. {
  886. vntValue.vt = VT_ARRAY|VT_BSTR;
  887. vntValue.parray = SafeArrayCreateVector(VT_BSTR, 0, dwCount);
  888. PADSVALUE pav = pavValue;
  889. BSTR* pbstr = (BSTR*)vntValue.parray->pvData;
  890. for (DWORD dwIndex = 0; dwIndex < dwCount; dwIndex++, pav++)
  891. {
  892. *pbstr++ = SysAllocString(pav->CaseExactString);
  893. }
  894. }
  895. break;
  896. }
  897. case ADSTYPE_CASE_IGNORE_STRING:
  898. {
  899. if (dwCount == 1)
  900. {
  901. vntValue = pavValue->CaseIgnoreString;
  902. }
  903. else
  904. {
  905. vntValue.vt = VT_ARRAY|VT_BSTR;
  906. vntValue.parray = SafeArrayCreateVector(VT_BSTR, 0, dwCount);
  907. PADSVALUE pav = pavValue;
  908. BSTR* pbstr = (BSTR*)vntValue.parray->pvData;
  909. for (DWORD dwIndex = 0; dwIndex < dwCount; dwIndex++, pav++)
  910. {
  911. *pbstr++ = SysAllocString(pav->CaseIgnoreString);
  912. }
  913. }
  914. break;
  915. }
  916. case ADSTYPE_PRINTABLE_STRING:
  917. {
  918. vntValue = pavValue->PrintableString;
  919. break;
  920. }
  921. case ADSTYPE_NUMERIC_STRING:
  922. {
  923. vntValue = pavValue->NumericString;
  924. break;
  925. }
  926. case ADSTYPE_BOOLEAN:
  927. {
  928. vntValue = pavValue->Boolean ? true : false;
  929. break;
  930. }
  931. case ADSTYPE_INTEGER:
  932. {
  933. vntValue = static_cast<long>(pavValue->Integer);
  934. break;
  935. }
  936. case ADSTYPE_OCTET_STRING:
  937. {
  938. vntValue.vt = VT_ARRAY|VT_UI1;
  939. vntValue.parray = SafeArrayCreateVector(VT_UI1, 0, pavValue->OctetString.dwLength);
  940. memcpy(vntValue.parray->pvData, pavValue->OctetString.lpValue, pavValue->OctetString.dwLength);
  941. break;
  942. }
  943. case ADSTYPE_UTC_TIME:
  944. {
  945. DATE dt;
  946. SystemTimeToVariantTime(&pavValue->UTCTime, &dt);
  947. vntValue = dt;
  948. vntValue.ChangeType(VT_DATE);
  949. break;
  950. }
  951. // case ADSTYPE_LARGE_INTEGER:
  952. case ADSTYPE_OBJECT_CLASS:
  953. {
  954. if (dwCount == 1)
  955. {
  956. vntValue = pavValue->ClassName;
  957. }
  958. else
  959. {
  960. vntValue.vt = VT_ARRAY|VT_BSTR;
  961. vntValue.parray = SafeArrayCreateVector(VT_BSTR, 0, dwCount);
  962. PADSVALUE pav = pavValue;
  963. BSTR* pbstr = (BSTR*)vntValue.parray->pvData;
  964. for (DWORD dwIndex = 0; dwIndex < dwCount; dwIndex++, pav++)
  965. {
  966. *pbstr++ = SysAllocString(pav->ClassName);
  967. }
  968. }
  969. break;
  970. }
  971. // case ADSTYPE_PROV_SPECIFIC:
  972. // case ADSTYPE_CASEIGNORE_LIST:
  973. // case ADSTYPE_OCTET_LIST:
  974. // case ADSTYPE_PATH:
  975. // case ADSTYPE_POSTALADDRESS:
  976. // case ADSTYPE_TIMESTAMP:
  977. // case ADSTYPE_BACKLINK:
  978. // case ADSTYPE_TYPEDNAME:
  979. // case ADSTYPE_HOLD:
  980. // case ADSTYPE_NETADDRESS:
  981. // case ADSTYPE_REPLICAPOINTER:
  982. // case ADSTYPE_FAXNUMBER:
  983. // case ADSTYPE_EMAIL:
  984. case ADSTYPE_NT_SECURITY_DESCRIPTOR:
  985. {
  986. ADS_NT_SECURITY_DESCRIPTOR& sd = pavValue->SecurityDescriptor;
  987. vntValue.vt = VT_ARRAY|VT_UI1;
  988. vntValue.parray = SafeArrayCreateVector(VT_UI1, 0, sd.dwLength);
  989. memcpy(vntValue.parray->pvData, sd.lpValue, sd.dwLength);
  990. break;
  991. }
  992. // case ADSTYPE_DN_WITH_BINARY:
  993. // case ADSTYPE_DN_WITH_STRING:
  994. default:
  995. {
  996. vntValue.Clear();
  997. break;
  998. }
  999. }
  1000. }
  1001. };
  1002. //---------------------------------------------------------------------------
  1003. // Directory Attributes Name Array Class
  1004. //---------------------------------------------------------------------------
  1005. class CDirectoryAttributesNameArray
  1006. {
  1007. public:
  1008. CDirectoryAttributesNameArray(const CDirectoryAttributes& daAttributes) :
  1009. m_ppszNames(NULL)
  1010. {
  1011. m_ppszNames = new LPTSTR[daAttributes.size()];
  1012. if (m_ppszNames)
  1013. {
  1014. LPTSTR* ppsz = m_ppszNames;
  1015. for (CDirectoryAttributes::const_iterator it = daAttributes.begin(); it != daAttributes.end(); it++)
  1016. {
  1017. *ppsz++ = const_cast<LPTSTR>(it->first.c_str());
  1018. }
  1019. }
  1020. else
  1021. {
  1022. _com_issue_error(E_OUTOFMEMORY);
  1023. }
  1024. }
  1025. ~CDirectoryAttributesNameArray()
  1026. {
  1027. if (m_ppszNames)
  1028. {
  1029. delete [] m_ppszNames;
  1030. }
  1031. }
  1032. operator LPTSTR*()
  1033. {
  1034. return m_ppszNames;
  1035. }
  1036. protected:
  1037. LPTSTR* m_ppszNames;
  1038. };
  1039. #define ATTRIBUTE_ADS_PATH _T("ADsPath")
  1040. #define ATTRIBUTE_CANONICAL_NAME _T("canonicalName")
  1041. #define ATTRIBUTE_DISTINGUISHED_NAME _T("distinguishedName")
  1042. #define ATTRIBUTE_NAME _T("name")
  1043. #define ATTRIBUTE_OBJECT_CATEGORY _T("objectCategory")
  1044. #define ATTRIBUTE_OBJECT_CLASS _T("objectClass")
  1045. #define ATTRIBUTE_OBJECT_SID _T("objectSid")
  1046. #define ATTRIBUTE_SAM_ACCOUNT_NAME _T("sAMAccountName")
  1047. #define ATTRIBUTE_USER_ACCOUNT_CONTROL _T("userAccountControl")
  1048. #define ATTRIBUTE_USER_PRINCIPAL_NAME _T("userPrincipalName")
  1049. //---------------------------------------------------------------------------
  1050. // Directory Object Class
  1051. //---------------------------------------------------------------------------
  1052. class CDirectoryObject
  1053. {
  1054. public:
  1055. CDirectoryObject(LPCTSTR pszPath = NULL)
  1056. {
  1057. if (pszPath)
  1058. {
  1059. _com_util::CheckError(ADsGetObject(pszPath, IID_IDirectoryObject, (VOID**)&m_spObject));
  1060. }
  1061. }
  1062. CDirectoryObject(IDispatchPtr spDispatch) :
  1063. m_spObject(spDispatch)
  1064. {
  1065. }
  1066. ~CDirectoryObject()
  1067. {
  1068. if (m_spObject)
  1069. {
  1070. m_spObject.Release();
  1071. }
  1072. }
  1073. CDirectoryObject& operator =(LPCTSTR pszPath)
  1074. {
  1075. _com_util::CheckError(ADsGetObject(pszPath, IID_IDirectoryObject, (VOID**)&m_spObject));
  1076. return *this;
  1077. }
  1078. void AddAttribute(LPCTSTR pszName)
  1079. {
  1080. m_daAttributes.AddAttribute(pszName);
  1081. }
  1082. void GetAttributes()
  1083. {
  1084. PADS_ATTR_INFO pAttrInfo = NULL;
  1085. try
  1086. {
  1087. // clear any existing attribute values
  1088. m_daAttributes.ClearValues();
  1089. // get attribute values
  1090. DWORD cAttr;
  1091. _com_util::CheckError(
  1092. m_spObject->GetObjectAttributes(
  1093. CDirectoryAttributesNameArray(m_daAttributes), m_daAttributes.size(), &pAttrInfo, &cAttr
  1094. )
  1095. );
  1096. // assign attribute values to directory attributes
  1097. PADS_ATTR_INFO pai = pAttrInfo;
  1098. for (DWORD iAttr = 0; iAttr < cAttr; iAttr++, pai++)
  1099. {
  1100. m_daAttributes.SetADsValue(pai->pszAttrName, pai->dwADsType, pai->pADsValues, pai->dwNumValues);
  1101. }
  1102. // clean up
  1103. if (pAttrInfo)
  1104. {
  1105. FreeADsMem(pAttrInfo);
  1106. }
  1107. }
  1108. catch (...)
  1109. {
  1110. if (pAttrInfo)
  1111. {
  1112. FreeADsMem(pAttrInfo);
  1113. }
  1114. throw;
  1115. }
  1116. }
  1117. const _variant_t& GetAttributeValue(LPCTSTR pszName)
  1118. {
  1119. return m_daAttributes.GetValue(pszName);
  1120. }
  1121. protected:
  1122. IDirectoryObjectPtr m_spObject;
  1123. CDirectoryAttributes m_daAttributes;
  1124. };
  1125. //---------------------------------------------------------------------------
  1126. // DirectorySearch Class
  1127. //---------------------------------------------------------------------------
  1128. class CDirectorySearch
  1129. {
  1130. public:
  1131. //
  1132. CDirectorySearch() :
  1133. m_hSearch(NULL)
  1134. {
  1135. }
  1136. CDirectorySearch(IDispatchPtr spDispatch) :
  1137. m_spSearch(spDispatch),
  1138. m_hSearch(NULL)
  1139. {
  1140. }
  1141. ~CDirectorySearch()
  1142. {
  1143. CloseSearchHandle();
  1144. }
  1145. void operator =(const IDispatchPtr& spDispatch)
  1146. {
  1147. m_spSearch = spDispatch;
  1148. }
  1149. //
  1150. void SetFilter(LPCTSTR pszFilter)
  1151. {
  1152. m_strFilter = pszFilter;
  1153. }
  1154. void SetPreferences(ADS_INTEGER nScope = ADS_SCOPE_SUBTREE)
  1155. {
  1156. ADS_SEARCHPREF_INFO siPreferences[4];
  1157. siPreferences[0].dwSearchPref = ADS_SEARCHPREF_ASYNCHRONOUS;
  1158. siPreferences[0].vValue.dwType = ADSTYPE_BOOLEAN;
  1159. siPreferences[0].vValue.Integer = TRUE;
  1160. siPreferences[1].dwSearchPref = ADS_SEARCHPREF_CACHE_RESULTS;
  1161. siPreferences[1].vValue.dwType = ADSTYPE_BOOLEAN;
  1162. siPreferences[1].vValue.Integer = FALSE;
  1163. siPreferences[2].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  1164. siPreferences[2].vValue.dwType = ADSTYPE_INTEGER;
  1165. siPreferences[2].vValue.Integer = 100;
  1166. siPreferences[3].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  1167. siPreferences[3].vValue.dwType = ADSTYPE_INTEGER;
  1168. siPreferences[3].vValue.Integer = nScope;
  1169. m_spSearch->SetSearchPreference(siPreferences, sizeof(siPreferences) / sizeof(siPreferences[0]));
  1170. }
  1171. void AddAttribute(LPCTSTR pszName)
  1172. {
  1173. m_daAttributes.AddAttribute(pszName);
  1174. }
  1175. void Search()
  1176. {
  1177. CloseSearchHandle();
  1178. _com_util::CheckError(m_spSearch->ExecuteSearch(
  1179. const_cast<LPTSTR>(m_strFilter.c_str()),
  1180. CDirectoryAttributesNameArray(m_daAttributes),
  1181. m_daAttributes.size(),
  1182. &m_hSearch
  1183. ));
  1184. }
  1185. bool GetFirstRow()
  1186. {
  1187. bool bGet = false;
  1188. HRESULT hr = m_spSearch->GetFirstRow(m_hSearch);
  1189. if (FAILED(hr))
  1190. {
  1191. _com_issue_error(hr);
  1192. }
  1193. if (hr == S_OK)
  1194. {
  1195. GetColumns();
  1196. bGet = true;
  1197. }
  1198. return bGet;
  1199. }
  1200. bool GetNextRow()
  1201. {
  1202. bool bGet = false;
  1203. HRESULT hr = m_spSearch->GetNextRow(m_hSearch);
  1204. if (FAILED(hr))
  1205. {
  1206. _com_issue_error(hr);
  1207. }
  1208. if (hr == S_OK)
  1209. {
  1210. GetColumns();
  1211. bGet = true;
  1212. }
  1213. return bGet;
  1214. }
  1215. const _variant_t& GetAttributeValue(LPCTSTR pszName)
  1216. {
  1217. return m_daAttributes.GetValue(pszName);
  1218. }
  1219. protected:
  1220. void GetColumns()
  1221. {
  1222. for (CDirectoryAttributes::iterator it = m_daAttributes.begin(); it != m_daAttributes.end(); it++)
  1223. {
  1224. const tstring& strName = it->first;
  1225. ADS_SEARCH_COLUMN scColumn;
  1226. if (m_spSearch->GetColumn(m_hSearch, const_cast<LPTSTR>(strName.c_str()), &scColumn) == S_OK)
  1227. {
  1228. m_daAttributes.SetADsValue(strName.c_str(), scColumn.dwADsType, scColumn.pADsValues, scColumn.dwNumValues);
  1229. m_spSearch->FreeColumn(&scColumn);
  1230. }
  1231. else
  1232. {
  1233. it->second.Clear();
  1234. }
  1235. }
  1236. }
  1237. void CloseSearchHandle()
  1238. {
  1239. if (m_hSearch)
  1240. {
  1241. m_spSearch->CloseSearchHandle(m_hSearch);
  1242. m_hSearch = NULL;
  1243. }
  1244. }
  1245. protected:
  1246. IDirectorySearchPtr m_spSearch;
  1247. tstring m_strFilter;
  1248. CDirectoryAttributes m_daAttributes;
  1249. ADS_SEARCH_HANDLE m_hSearch;
  1250. };
  1251. //
  1252. // Object SID helpers
  1253. //
  1254. #define MIN_NON_RESERVED_RID 1000
  1255. bool __stdcall IsUserRid(const _variant_t& vntSid);
  1256. //
  1257. // Other helpers.
  1258. //
  1259. tstring __stdcall GetEscapedFilterValue(PCTSTR pszValue);