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.

1029 lines
27 KiB

  1. //+------------------------------------------------------------
  2. //
  3. // Copyright (C) 1998, Microsoft Corporation
  4. //
  5. // File: icatitemattr.cpp
  6. //
  7. // Contents: Implementation of CICategorizerItemAttributesIMP
  8. //
  9. // Classes:
  10. // CLdapResultWrap
  11. // CICategorizerItemAttributesIMP
  12. //
  13. // Functions:
  14. //
  15. // History:
  16. // jstamerj 1998/07/01 13:48:15: Created.
  17. //
  18. //-------------------------------------------------------------
  19. #include "precomp.h"
  20. #include "icatitemattr.h"
  21. //+------------------------------------------------------------
  22. //
  23. // Function: CLdapResultWrap::CLdapResultWrap
  24. //
  25. // Synopsis: Refcount an LDAP Message, call ldap_msg_free when all
  26. // references have been released
  27. //
  28. // Arguments:
  29. // pCPLDAPWrap: PLDAP to refcount
  30. // pMessage: the LDAPMessage to refcount
  31. //
  32. // Returns: NOTHING
  33. //
  34. // History:
  35. // jstamerj 1998/10/05 13:12:15: Created.
  36. //
  37. //-------------------------------------------------------------
  38. CLdapResultWrap::CLdapResultWrap(
  39. ISMTPServerEx *pISMTPServerEx,
  40. CPLDAPWrap *pCPLDAPWrap,
  41. PLDAPMessage pMessage)
  42. {
  43. _ASSERT(pCPLDAPWrap);
  44. _ASSERT(pMessage);
  45. m_pCPLDAPWrap = pCPLDAPWrap;
  46. m_pCPLDAPWrap->AddRef();
  47. m_pLDAPMessage = pMessage;
  48. m_lRefCount = 0;
  49. m_pISMTPServerEx = pISMTPServerEx;
  50. if(m_pISMTPServerEx)
  51. m_pISMTPServerEx->AddRef();
  52. }
  53. //+------------------------------------------------------------
  54. //
  55. // Function: CLdapResultWrap::AddRef
  56. //
  57. // Synopsis: Increment the ref count of this object
  58. //
  59. // Arguments: NONE
  60. //
  61. // Returns: new refcount
  62. //
  63. // History:
  64. // jstamerj 1998/10/05 13:14:59: Created.
  65. //
  66. //-------------------------------------------------------------
  67. LONG CLdapResultWrap::AddRef()
  68. {
  69. return InterlockedIncrement(&m_lRefCount);
  70. }
  71. //+------------------------------------------------------------
  72. //
  73. // Function: CLdapResultWrap::Release
  74. //
  75. // Synopsis: Decrement the ref count. Free the object when the
  76. // refcount hits zero
  77. //
  78. // Arguments: NONE
  79. //
  80. // Returns: New refcount
  81. //
  82. // History:
  83. // jstamerj 1998/10/05 13:26:47: Created.
  84. //
  85. //-------------------------------------------------------------
  86. LONG CLdapResultWrap::Release()
  87. {
  88. LONG lNewRefCount;
  89. lNewRefCount = InterlockedDecrement(&m_lRefCount);
  90. if(lNewRefCount == 0) {
  91. //
  92. // Release this ldapmessage
  93. //
  94. delete this;
  95. return 0;
  96. } else {
  97. return lNewRefCount;
  98. }
  99. }
  100. //+------------------------------------------------------------
  101. //
  102. // Function: CLdapResultWrap::~CLdapResultWrap
  103. //
  104. // Synopsis: Release the ldap message result
  105. //
  106. // Arguments: NONE
  107. //
  108. // Returns: NOTHING
  109. //
  110. // History:
  111. // jstamerj 1998/10/05 13:31:39: Created.
  112. //
  113. //-------------------------------------------------------------
  114. CLdapResultWrap::~CLdapResultWrap()
  115. {
  116. m_pCPLDAPWrap->Release();
  117. ldap_msgfree(m_pLDAPMessage);
  118. if(m_pISMTPServerEx)
  119. m_pISMTPServerEx->Release();
  120. }
  121. //+------------------------------------------------------------
  122. //
  123. // Function: CICategorizerItemAttributesIMP::CICategorizerItemAttributesIMP
  124. //
  125. // Synopsis: Initializes member data
  126. //
  127. // Arguments:
  128. // pldap: PLDAP to use
  129. // pldapmessage: PLDAPMessage to serve out
  130. //
  131. // Returns: NOTHING
  132. //
  133. // History:
  134. // jstamerj 1998/07/02 12:35:15: Created.
  135. //
  136. //-------------------------------------------------------------
  137. CICategorizerItemAttributesIMP::CICategorizerItemAttributesIMP(
  138. PLDAP pldap,
  139. PLDAPMessage pldapmessage,
  140. CLdapResultWrap *pResultWrap)
  141. {
  142. m_dwSignature = CICATEGORIZERITEMATTRIBUTESIMP_SIGNATURE;
  143. _ASSERT(pldap);
  144. _ASSERT(pldapmessage);
  145. _ASSERT(pResultWrap);
  146. m_pldap = pldap;
  147. m_pldapmessage = pldapmessage;
  148. m_cRef = 0;
  149. m_pResultWrap = pResultWrap;
  150. m_pResultWrap->AddRef();
  151. }
  152. //+------------------------------------------------------------
  153. //
  154. // Function: CICategorizerItemAttributesIMP::~CICategorizerItemAttributesIMP
  155. //
  156. // Synopsis: Checks to make sure signature is valid and then resets signature
  157. //
  158. // Arguments: NONE
  159. //
  160. // Returns: NOTHING
  161. //
  162. // History:
  163. // jstamerj 1998/07/02 12:39:45: Created.
  164. //
  165. //-------------------------------------------------------------
  166. CICategorizerItemAttributesIMP::~CICategorizerItemAttributesIMP()
  167. {
  168. m_pResultWrap->Release();
  169. _ASSERT(m_dwSignature == CICATEGORIZERITEMATTRIBUTESIMP_SIGNATURE);
  170. m_dwSignature = CICATEGORIZERITEMATTRIBUTESIMP_SIGNATURE_INVALID;
  171. }
  172. //+------------------------------------------------------------
  173. //
  174. // Function: QueryInterface
  175. //
  176. // Synopsis: Returns pointer to this object for IUnknown and ICategorizerItemAttributes
  177. //
  178. // Arguments:
  179. // iid -- interface ID
  180. // ppv -- pvoid* to fill in with pointer to interface
  181. //
  182. // Returns:
  183. // S_OK: Success
  184. // E_NOINTERFACE: Don't support that interface
  185. //
  186. // History:
  187. // jstamerj 980612 14:07:57: Created.
  188. //
  189. //-------------------------------------------------------------
  190. STDMETHODIMP CICategorizerItemAttributesIMP::QueryInterface(
  191. REFIID iid,
  192. LPVOID *ppv)
  193. {
  194. *ppv = NULL;
  195. if(iid == IID_IUnknown) {
  196. *ppv = (LPVOID) this;
  197. } else if (iid == IID_ICategorizerItemAttributes) {
  198. *ppv = (LPVOID) ((ICategorizerItemAttributes *) this);
  199. } else if (iid == IID_ICategorizerItemRawAttributes) {
  200. *ppv = (LPVOID) ((ICategorizerItemRawAttributes *) this);
  201. } else if (iid == IID_ICategorizerUTF8Attributes) {
  202. *ppv = (LPVOID) ((ICategorizerUTF8Attributes *) this);
  203. } else {
  204. return E_NOINTERFACE;
  205. }
  206. AddRef();
  207. return S_OK;
  208. }
  209. //+------------------------------------------------------------
  210. //
  211. // Function: AddRef
  212. //
  213. // Synopsis: adds a reference to this object
  214. //
  215. // Arguments: NONE
  216. //
  217. // Returns: New reference count
  218. //
  219. // History:
  220. // jstamerj 980611 20:07:14: Created.
  221. //
  222. //-------------------------------------------------------------
  223. ULONG CICategorizerItemAttributesIMP::AddRef()
  224. {
  225. return InterlockedIncrement((PLONG)&m_cRef);
  226. }
  227. //+------------------------------------------------------------
  228. //
  229. // Function: Release
  230. //
  231. // Synopsis: releases a reference, deletes this object when the
  232. // refcount hits zero.
  233. //
  234. // Arguments: NONE
  235. //
  236. // Returns: New reference count
  237. //
  238. // History:
  239. // jstamerj 980611 20:07:33: Created.
  240. //
  241. //-------------------------------------------------------------
  242. ULONG CICategorizerItemAttributesIMP::Release()
  243. {
  244. LONG lNewRefCount;
  245. lNewRefCount = InterlockedDecrement((PLONG)&m_cRef);
  246. if(lNewRefCount == 0) {
  247. delete this;
  248. return 0;
  249. } else {
  250. return lNewRefCount;
  251. }
  252. }
  253. //+------------------------------------------------------------
  254. //
  255. // Function: BeginAttributeEnumeration
  256. //
  257. // Synopsis: Prepare to enumerate through attribute values for a specific attribute
  258. //
  259. // Arguments:
  260. // pszAttributeName: Name of attribute to enumerate through
  261. // penumerator: Uninitialized Enumerator structure to use
  262. //
  263. // Returns:
  264. // S_OK: Success
  265. // CAT_E_PROPNOTFOUND: No attributes values exist
  266. //
  267. // History:
  268. // jstamerj 1998/07/02 10:54:00: Created.
  269. //
  270. //-------------------------------------------------------------
  271. STDMETHODIMP CICategorizerItemAttributesIMP::BeginAttributeEnumeration(
  272. IN LPCSTR pszAttributeName,
  273. IN PATTRIBUTE_ENUMERATOR penumerator)
  274. {
  275. CatFunctEnterEx((LPARAM)this, "CICategorizerItemAttributesIMP::BeginAttributeEnumeration");
  276. _ASSERT(pszAttributeName);
  277. _ASSERT(penumerator);
  278. penumerator->pvBase =
  279. penumerator->pvCurrent = ldap_get_values(
  280. m_pldap,
  281. m_pldapmessage,
  282. (LPSTR)pszAttributeName);
  283. if(penumerator->pvBase == NULL) {
  284. ErrorTrace((LPARAM)this, "Requested attribute %s not found", pszAttributeName);
  285. CatFunctLeaveEx((LPARAM)this);
  286. return CAT_E_PROPNOTFOUND;
  287. }
  288. CatFunctLeaveEx((LPARAM)this);
  289. return S_OK;
  290. }
  291. //+------------------------------------------------------------
  292. //
  293. // Function: GetNextAttributeValue
  294. //
  295. // Synopsis: Get the next attribute in an enumeration
  296. //
  297. // Arguments:
  298. // penumerator: enumerator sturcture initialized in BeginAttributeEnumeration
  299. // ppszAttributeValue: Ptr to Ptr to recieve Ptr to string of attribute value
  300. //
  301. // Returns:
  302. // S_OK: Success
  303. // HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)
  304. //
  305. // History:
  306. // jstamerj 1998/07/02 11:14:54: Created.
  307. //
  308. //-------------------------------------------------------------
  309. STDMETHODIMP CICategorizerItemAttributesIMP::GetNextAttributeValue(
  310. IN PATTRIBUTE_ENUMERATOR penumerator,
  311. OUT LPSTR *ppszAttributeValue)
  312. {
  313. _ASSERT(penumerator);
  314. _ASSERT(ppszAttributeValue);
  315. *ppszAttributeValue = *((LPSTR *)penumerator->pvCurrent);
  316. if(*ppszAttributeValue) {
  317. //
  318. // Advance enumerator to next value
  319. //
  320. penumerator->pvCurrent = (PVOID) (((LPSTR *)penumerator->pvCurrent)+1);
  321. return S_OK;
  322. } else {
  323. //
  324. // This is the last value
  325. //
  326. return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  327. }
  328. }
  329. //+------------------------------------------------------------
  330. //
  331. // Function: RewindAttributeEnumeration
  332. //
  333. // Synopsis: Rewind enumerator to beginning of attribute value list
  334. //
  335. // Arguments:
  336. // penumerator: attribute enumerator initialized by BeginAttributeEnumeration
  337. //
  338. // Returns:
  339. // S_OK: Success
  340. //
  341. // History:
  342. // jstamerj 1998/07/06 11:22:23: Created.
  343. //
  344. //-------------------------------------------------------------
  345. STDMETHODIMP CICategorizerItemAttributesIMP::RewindAttributeEnumeration(
  346. IN PATTRIBUTE_ENUMERATOR penumerator)
  347. {
  348. penumerator->pvCurrent = penumerator->pvBase;
  349. return S_OK;
  350. }
  351. //+------------------------------------------------------------
  352. //
  353. // Function: EndAttributeEnumeration
  354. //
  355. // Synopsis: Free memory associated with an attribute enumeration
  356. //
  357. // Arguments:
  358. // penumerator: attribute enumerator initialized by BeginAttributeEnumeration
  359. //
  360. // Returns:
  361. // S_OK: Success
  362. //
  363. // History:
  364. // jstamerj 1998/07/02 12:24:44: Created.
  365. //
  366. //-------------------------------------------------------------
  367. STDMETHODIMP CICategorizerItemAttributesIMP::EndAttributeEnumeration(
  368. IN PATTRIBUTE_ENUMERATOR penumerator)
  369. {
  370. _ASSERT(penumerator);
  371. ldap_value_free((LPSTR *)penumerator->pvBase);
  372. return S_OK;
  373. }
  374. //+------------------------------------------------------------
  375. //
  376. // Function: CICategorizerItemAttributesIMP::BeginAttributeNameEnumeration
  377. //
  378. // Synopsis: Enumerate through the attributes returned from LDAP
  379. //
  380. // Arguments:
  381. // penumerator: Caller allocated enumerator structure to be
  382. // initialized by this call
  383. //
  384. // Returns:
  385. // S_OK: Success
  386. //
  387. // History:
  388. // jstamerj 1998/09/18 10:49:56: Created.
  389. //
  390. //-------------------------------------------------------------
  391. STDMETHODIMP CICategorizerItemAttributesIMP::BeginAttributeNameEnumeration(
  392. IN PATTRIBUTE_ENUMERATOR penumerator)
  393. {
  394. _ASSERT(penumerator);
  395. penumerator->pvBase =
  396. penumerator->pvCurrent = NULL;
  397. return S_OK;
  398. }
  399. //+------------------------------------------------------------
  400. //
  401. // Function: CICategorizerItemAttributesIMP::GetNextAttributeName
  402. //
  403. // Synopsis: enumerate through the attribute names returned
  404. //
  405. // Arguments:
  406. // penumerator: enumerator strucutre initialized in BeginAttributeNameEnumeration
  407. // ppszAttributeValue: out parameter for an attribute name
  408. //
  409. // Returns:
  410. // S_OK: Success
  411. // HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)
  412. //
  413. // History:
  414. // jstamerj 1998/09/18 10:53:15: Created.
  415. //
  416. //-------------------------------------------------------------
  417. STDMETHODIMP CICategorizerItemAttributesIMP::GetNextAttributeName(
  418. IN PATTRIBUTE_ENUMERATOR penumerator,
  419. OUT LPSTR *ppszAttributeName)
  420. {
  421. _ASSERT(penumerator);
  422. _ASSERT(ppszAttributeName);
  423. if(penumerator->pvCurrent == NULL) {
  424. *ppszAttributeName = ldap_first_attribute(
  425. m_pldap,
  426. m_pldapmessage,
  427. (BerElement **) &(penumerator->pvCurrent));
  428. } else {
  429. *ppszAttributeName = ldap_next_attribute(
  430. m_pldap,
  431. m_pldapmessage,
  432. (BerElement *) (penumerator->pvCurrent));
  433. }
  434. if(*ppszAttributeName == NULL) {
  435. //
  436. // Assume we've reached the end of the attribute name
  437. // enumeration
  438. //
  439. return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  440. } else {
  441. return S_OK;
  442. }
  443. }
  444. //+------------------------------------------------------------
  445. //
  446. // Function: CICategorizerItemAttributeIMP::EndAttributeNameEnumeration
  447. //
  448. // Synopsis: Free all data held for this enumeration
  449. //
  450. // Arguments:
  451. // penumerator: enumerator strucutre initialized in BeginAttributeNameEnumeration
  452. //
  453. // Returns:
  454. // S_OK: Success
  455. //
  456. // History:
  457. // jstamerj 1998/09/18 11:04:37: Created.
  458. //
  459. //-------------------------------------------------------------
  460. STDMETHODIMP CICategorizerItemAttributesIMP::EndAttributeNameEnumeration(
  461. IN PATTRIBUTE_ENUMERATOR penumerator)
  462. {
  463. //
  464. // Ldap uses only buffers in the connection block for this, so we
  465. // don't need to explicitly free anything
  466. //
  467. return S_OK;
  468. }
  469. //+------------------------------------------------------------
  470. //
  471. // Function: CICategorizerItemAttributesIMP::AggregateAttributes
  472. //
  473. // Synopsis: Normally, accept and ICategorizerItemAttributes for aggregation
  474. //
  475. // Arguments:
  476. // pICatItemAttributes: attributes to aggregate
  477. //
  478. // Returns:
  479. // E_NOTIMPL
  480. //
  481. // History:
  482. // jstamerj 1998/07/16 14:42:16: Created.
  483. //
  484. //-------------------------------------------------------------
  485. STDMETHODIMP CICategorizerItemAttributesIMP::AggregateAttributes(
  486. IN ICategorizerItemAttributes *pICatItemAttributes)
  487. {
  488. return E_NOTIMPL;
  489. }
  490. //+------------------------------------------------------------
  491. //
  492. // Function: BeginRawAttributeEnumeration
  493. //
  494. // Synopsis: Prepare to enumerate through attribute values for a specific attribute
  495. //
  496. // Arguments:
  497. // pszAttributeName: Name of attribute to enumerate through
  498. // penumerator: Uninitialized Enumerator structure to use
  499. //
  500. // Returns:
  501. // S_OK: Success
  502. // CAT_E_PROPNOTFOUND: No attributes values exist
  503. //
  504. // History:
  505. // jstamerj 1998/12/09 12:44:15: Created
  506. //
  507. //-------------------------------------------------------------
  508. STDMETHODIMP CICategorizerItemAttributesIMP::BeginRawAttributeEnumeration(
  509. IN LPCSTR pszAttributeName,
  510. IN PATTRIBUTE_ENUMERATOR penumerator)
  511. {
  512. CatFunctEnterEx((LPARAM)this, "CICategorizerItemAttributesIMP::BeginRawAttributeEnumeration");
  513. _ASSERT(pszAttributeName);
  514. _ASSERT(penumerator);
  515. penumerator->pvBase =
  516. penumerator->pvCurrent = ldap_get_values_len(
  517. m_pldap,
  518. m_pldapmessage,
  519. (LPSTR)pszAttributeName);
  520. if(penumerator->pvBase == NULL) {
  521. ErrorTrace((LPARAM)this, "Requested attribute %s not found", pszAttributeName);
  522. CatFunctLeaveEx((LPARAM)this);
  523. return CAT_E_PROPNOTFOUND;
  524. }
  525. CatFunctLeaveEx((LPARAM)this);
  526. return S_OK;
  527. }
  528. //+------------------------------------------------------------
  529. //
  530. // Function: GetNextRawAttributeValue
  531. //
  532. // Synopsis: Get the next attribute in an enumeration
  533. //
  534. // Arguments:
  535. // penumerator: enumerator sturcture initialized in BeginAttributeEnumeration
  536. // pdwcb: dword to set to the # of bytes in the pvValue buffer
  537. // pvValue: Ptr to recieve Ptr to raw attribute value
  538. //
  539. // Returns:
  540. // S_OK: Success
  541. // HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)
  542. //
  543. // History:
  544. // jstamerj 1998/12/09 12:49:27: Created
  545. //
  546. //-------------------------------------------------------------
  547. STDMETHODIMP CICategorizerItemAttributesIMP::GetNextRawAttributeValue(
  548. IN PATTRIBUTE_ENUMERATOR penumerator,
  549. OUT PDWORD pdwcb,
  550. OUT LPVOID *pvValue)
  551. {
  552. _ASSERT(penumerator);
  553. _ASSERT(pdwcb);
  554. _ASSERT(pvValue);
  555. if( (*((PLDAP_BERVAL *)penumerator->pvCurrent)) != NULL) {
  556. *pdwcb = (* ((PLDAP_BERVAL *)penumerator->pvCurrent))->bv_len;
  557. *pvValue = (* ((PLDAP_BERVAL *)penumerator->pvCurrent))->bv_val;
  558. //
  559. // Advance enumerator to next value
  560. //
  561. penumerator->pvCurrent = (PVOID)
  562. (((PLDAP_BERVAL *)penumerator->pvCurrent)+1);
  563. return S_OK;
  564. } else {
  565. //
  566. // This is the last value
  567. //
  568. *pdwcb = 0;
  569. *pvValue = NULL;
  570. return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  571. }
  572. }
  573. //+------------------------------------------------------------
  574. //
  575. // Function: RewindRawAttributeEnumeration
  576. //
  577. // Synopsis: Rewind enumerator to beginning of attribute value list
  578. //
  579. // Arguments:
  580. // penumerator: attribute enumerator initialized by BeginAttributeEnumeration
  581. //
  582. // Returns:
  583. // S_OK: Success
  584. //
  585. // History:
  586. // jstamerj 1998/12/09 12:49:23: Created
  587. //
  588. //-------------------------------------------------------------
  589. STDMETHODIMP CICategorizerItemAttributesIMP::RewindRawAttributeEnumeration(
  590. IN PATTRIBUTE_ENUMERATOR penumerator)
  591. {
  592. return RewindAttributeEnumeration(penumerator);
  593. }
  594. //+------------------------------------------------------------
  595. //
  596. // Function: EndRawAttributeEnumeration
  597. //
  598. // Synopsis: Free memory associated with an attribute enumeration
  599. //
  600. // Arguments:
  601. // penumerator: attribute enumerator initialized by BeginAttributeEnumeration
  602. //
  603. // Returns:
  604. // S_OK: Success
  605. //
  606. // History:
  607. // jstamerj 1998/12/09 12:50:02: Created
  608. //
  609. //-------------------------------------------------------------
  610. STDMETHODIMP CICategorizerItemAttributesIMP::EndRawAttributeEnumeration(
  611. IN PATTRIBUTE_ENUMERATOR penumerator)
  612. {
  613. _ASSERT(penumerator);
  614. ldap_value_free_len((struct berval **)penumerator->pvBase);
  615. return S_OK;
  616. }
  617. //+------------------------------------------------------------
  618. //
  619. // Function: CICategorizerItemAttributesIMP::GetAllAttributeValues
  620. //
  621. // Synopsis: Retrieve all values for a particular attribute at once.
  622. // This may not be optimal for attributes with a large number of
  623. // values (enumerating through the values may be better performace wise).
  624. //
  625. // Arguments:
  626. // pszAttributeName: The name of the attribute you want
  627. // penumerator: A user allocated ATTRIBUTE_ENUMERATOR structure for
  628. // use by the ICategorizerItemAttributes implementor
  629. // prgpszAttributeValues: Where to return the pointer to the
  630. // attribute string array. This will be a NULL terminated array of
  631. // pointers to strings.
  632. //
  633. // Returns:
  634. // S_OK: Success
  635. // CAT_E_PROPNOTFOUND: None of those attributes exist
  636. //
  637. // History:
  638. // jstamerj 1998/12/10 18:55:38: Created.
  639. //
  640. //-------------------------------------------------------------
  641. HRESULT CICategorizerItemAttributesIMP::GetAllAttributeValues(
  642. LPCSTR pszAttributeName,
  643. PATTRIBUTE_ENUMERATOR penumerator,
  644. LPSTR **prgpszAttributeValues)
  645. {
  646. HRESULT hr;
  647. CatFunctEnter("CICategorizerItemAttributesIMP::GetAllAttributeValues");
  648. //
  649. // piggy back on BeginAttributeEnumeration
  650. //
  651. hr = BeginAttributeEnumeration(
  652. pszAttributeName,
  653. penumerator);
  654. if(SUCCEEDED(hr)) {
  655. //
  656. // return the array
  657. //
  658. *prgpszAttributeValues = (LPSTR *) penumerator->pvBase;
  659. }
  660. DebugTrace(NULL, "returning hr %08lx", hr);
  661. CatFunctLeave();
  662. return hr;
  663. }
  664. //+------------------------------------------------------------
  665. //
  666. // Function: CICategorizerItemAttributesIMP::ReleaseAllAttributes
  667. //
  668. // Synopsis: Release the attributes allocated from GetAllAttributeValues
  669. //
  670. // Arguments:
  671. // penumerator: the enumerator passed into GetAllAttributeValues
  672. //
  673. // Returns:
  674. // S_OK: Success
  675. //
  676. // History:
  677. // jstamerj 1998/12/10 19:38:57: Created.
  678. //
  679. //-------------------------------------------------------------
  680. HRESULT CICategorizerItemAttributesIMP::ReleaseAllAttributeValues(
  681. PATTRIBUTE_ENUMERATOR penumerator)
  682. {
  683. HRESULT hr;
  684. CatFunctEnter("CICategorizerItemAttributesIMP::ReleaseAllAttributes");
  685. //
  686. // piggy back off of endattributeenumeration
  687. //
  688. hr = EndAttributeEnumeration(
  689. penumerator);
  690. DebugTrace(NULL, "returning hr %08lx", hr);
  691. CatFunctLeave();
  692. return hr;
  693. }
  694. //+------------------------------------------------------------
  695. //
  696. // Function: CICategorizerItemAttributesIMP::CountAttributeValues
  697. //
  698. // Synopsis: Return a count of the number of attribute values associated
  699. // with this enumerator
  700. //
  701. // Arguments:
  702. // penumerator: describes the attribute in question
  703. // pdwCount: Out parameter for the count
  704. //
  705. // Returns:
  706. // S_OK: Success
  707. //
  708. // History:
  709. // jstamerj 1999/03/25 14:36:58: Created.
  710. //
  711. //-------------------------------------------------------------
  712. HRESULT CICategorizerItemAttributesIMP::CountAttributeValues(
  713. IN PATTRIBUTE_ENUMERATOR penumerator,
  714. OUT DWORD *pdwCount)
  715. {
  716. CatFunctEnterEx((LPARAM)this, "CICategorizerItemAttributesIMP::CountAttributeValues");
  717. _ASSERT(pdwCount);
  718. *pdwCount = ldap_count_values((PCHAR *) penumerator->pvBase);
  719. CatFunctLeaveEx((LPARAM)this);
  720. return S_OK;
  721. } // CICategorizerItemAttributesIMP::CountAttributeValues
  722. //+------------------------------------------------------------
  723. //
  724. // Function: CICategorizerItemAttributesIMP::CountRawAttributeValues
  725. //
  726. // Synopsis: Return a count of the number of attribute values associated
  727. // with this enumerator
  728. //
  729. // Arguments:
  730. // penumerator: describes the attribute in question
  731. // pdwCount: Out parameter for the count
  732. //
  733. // Returns:
  734. // S_OK: Success
  735. //
  736. // History:
  737. // jstamerj 1999/03/25 14:39:54: Created
  738. //
  739. //-------------------------------------------------------------
  740. HRESULT CICategorizerItemAttributesIMP::CountRawAttributeValues(
  741. IN PATTRIBUTE_ENUMERATOR penumerator,
  742. OUT DWORD *pdwCount)
  743. {
  744. CatFunctEnterEx((LPARAM)this, "CICategorizerItemAttributesIMP::CountRawAttributeValues");
  745. _ASSERT(pdwCount);
  746. *pdwCount = ldap_count_values_len((struct berval **) penumerator->pvBase);
  747. CatFunctLeaveEx((LPARAM)this);
  748. return S_OK;
  749. } // CICategorizerItemAttributesIMP::CountRawAttributeValues
  750. //+------------------------------------------------------------
  751. //
  752. // Function: CICategorizerItemAttributesIMP::BeginUTF8AttributeEnumeration
  753. //
  754. // Synopsis: Begin UTF8 attribute enumeration
  755. //
  756. // Arguments:
  757. // pszAttributeName: Name of attribute to enumerate through
  758. // penumerator: Uninitialized Enumerator structure to use
  759. //
  760. // Returns:
  761. // S_OK: Success
  762. // CAT_E_PROPNOTFOUND: No attributes values exist
  763. //
  764. // Returns:
  765. // S_OK: Success
  766. //
  767. // History:
  768. // jstamerj 1999/12/10 11:14:35: Created.
  769. //
  770. //-------------------------------------------------------------
  771. HRESULT CICategorizerItemAttributesIMP::BeginUTF8AttributeEnumeration(
  772. IN LPCSTR pszAttributeName,
  773. IN PATTRIBUTE_ENUMERATOR penumerator)
  774. {
  775. HRESULT hr;
  776. CatFunctEnterEx((LPARAM)this, "CICategorizerItemAttributesIMP::BeginUTF8AttributeEnumeration");
  777. //
  778. // Piggy back raw attribute enumeration and use the pvContext
  779. // member of penumerator.
  780. //
  781. hr = BeginRawAttributeEnumeration(
  782. pszAttributeName,
  783. penumerator);
  784. penumerator->pvContext = NULL;
  785. DebugTrace((LPARAM)this, "returning hr %08lx", hr);
  786. CatFunctLeaveEx((LPARAM)this);
  787. return hr;
  788. }
  789. //+------------------------------------------------------------
  790. //
  791. // Function: GetNextAttributeValue
  792. //
  793. // Synopsis: Get the next attribute in an enumeration
  794. //
  795. // Arguments:
  796. // penumerator: enumerator sturcture initialized in BeginAttributeEnumeration
  797. // ppszAttributeValue: Ptr to Ptr to recieve Ptr to string of attribute value
  798. //
  799. // Returns:
  800. // S_OK: Success
  801. // HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)
  802. //
  803. // History:
  804. // jstamerj 1998/07/02 11:14:54: Created.
  805. //
  806. //-------------------------------------------------------------
  807. STDMETHODIMP CICategorizerItemAttributesIMP::GetNextUTF8AttributeValue(
  808. IN PATTRIBUTE_ENUMERATOR penumerator,
  809. OUT LPSTR *ppszAttributeValue)
  810. {
  811. HRESULT hr = S_OK;
  812. DWORD dwcb = 0;
  813. LPVOID pvAttributeValue = NULL;
  814. LPSTR psz = NULL;
  815. CatFunctEnterEx((LPARAM)this, "CICategorizerItemAttributesIMP::GetNextUTF8AttributeValue");
  816. if(penumerator->pvContext) {
  817. delete [] (LPSTR) penumerator->pvContext;
  818. penumerator->pvContext = NULL;
  819. }
  820. hr = GetNextRawAttributeValue(
  821. penumerator,
  822. &dwcb,
  823. &pvAttributeValue);
  824. if(FAILED(hr))
  825. return hr;
  826. //
  827. // Convert to termianted UTF8 string
  828. //
  829. psz = new CHAR[dwcb + 1];
  830. if(psz == NULL)
  831. {
  832. ERROR_LOG("new CHAR[]");
  833. return E_OUTOFMEMORY;
  834. }
  835. CopyMemory(psz, pvAttributeValue, dwcb);
  836. psz[dwcb] = '\0';
  837. *ppszAttributeValue = psz;
  838. penumerator->pvContext = psz;
  839. CatFunctLeaveEx((LPARAM)this);
  840. return hr;
  841. }
  842. //+------------------------------------------------------------
  843. //
  844. // Function: RewindAttributeEnumeration
  845. //
  846. // Synopsis: Rewind enumerator to beginning of attribute value list
  847. //
  848. // Arguments:
  849. // penumerator: attribute enumerator initialized by BeginAttributeEnumeration
  850. //
  851. // Returns:
  852. // S_OK: Success
  853. //
  854. // History:
  855. // jstamerj 1998/07/06 11:22:23: Created.
  856. //
  857. //-------------------------------------------------------------
  858. STDMETHODIMP CICategorizerItemAttributesIMP::RewindUTF8AttributeEnumeration(
  859. IN PATTRIBUTE_ENUMERATOR penumerator)
  860. {
  861. return RewindRawAttributeEnumeration(
  862. penumerator);
  863. }
  864. //+------------------------------------------------------------
  865. //
  866. // Function: EndAttributeEnumeration
  867. //
  868. // Synopsis: Free memory associated with an attribute enumeration
  869. //
  870. // Arguments:
  871. // penumerator: attribute enumerator initialized by BeginAttributeEnumeration
  872. //
  873. // Returns:
  874. // S_OK: Success
  875. //
  876. // History:
  877. // jstamerj 1998/07/02 12:24:44: Created.
  878. //
  879. //-------------------------------------------------------------
  880. STDMETHODIMP CICategorizerItemAttributesIMP::EndUTF8AttributeEnumeration(
  881. IN PATTRIBUTE_ENUMERATOR penumerator)
  882. {
  883. if(penumerator->pvContext) {
  884. delete [] (LPSTR) penumerator->pvContext;
  885. penumerator->pvContext = NULL;
  886. }
  887. return EndRawAttributeEnumeration(penumerator);
  888. }
  889. //+------------------------------------------------------------
  890. //
  891. // Function: CICategorizerItemAttributesIMP::CountUTF8AttributeValues
  892. //
  893. // Synopsis: Return a count of the number of attribute values associated
  894. // with this enumerator
  895. //
  896. // Arguments:
  897. // penumerator: describes the attribute in question
  898. // pdwCount: Out parameter for the count
  899. //
  900. // Returns:
  901. // S_OK: Success
  902. //
  903. // History:
  904. // jstamerj 1999/03/25 14:39:54: Created
  905. //
  906. //-------------------------------------------------------------
  907. HRESULT CICategorizerItemAttributesIMP::CountUTF8AttributeValues(
  908. IN PATTRIBUTE_ENUMERATOR penumerator,
  909. OUT DWORD *pdwCount)
  910. {
  911. return CountRawAttributeValues(
  912. penumerator,
  913. pdwCount);
  914. } // CICategorizerItemAttributesIMP::CountRawAttributeValues