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.

798 lines
22 KiB

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright(C) Microsoft Corporation all rights reserved.
  4. //
  5. // Module: sdocollection.h
  6. //
  7. // Description: IAS Server Data Object Collection Implementation
  8. //
  9. // Author: TLP 1/23/98
  10. //
  11. ///////////////////////////////////////////////////////////////////////////
  12. #include "stdafx.h"
  13. #include "sdo.h"
  14. #include "sdocollection.h"
  15. #include "sdofactory.h"
  16. #include "sdohelperfuncs.h"
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CSdoCollection Class Implementation
  19. /////////////////////////////////////////////////////////////////////////////
  20. /////////////////////////////////////////////////////////////////////////////
  21. CSdoCollection::CSdoCollection()
  22. : m_fSdoInitialized(false),
  23. m_pDSContainer(NULL),
  24. m_pSdoMachine(NULL),
  25. m_fCreateOnAdd(false),
  26. m_MaxSize(INFINITE)
  27. {
  28. InternalAddRef();
  29. }
  30. /////////////////////////////////////////////////////////////////////////////
  31. CSdoCollection::~CSdoCollection()
  32. {
  33. InternalShutdown();
  34. }
  35. /////////////////////////////////////////////////////////////////////////////
  36. // ISdoCollection Interface Implmentation
  37. /////////////////////////////////////////////////////////////////////////////
  38. /////////////////////////////////////////////////////////////////////////////
  39. STDMETHODIMP CSdoCollection::get_Count(long* pCount)
  40. {
  41. CSdoLock theLock(*this);
  42. // Check precondtions
  43. //
  44. _ASSERT ( m_fSdoInitialized );
  45. if ( ! m_fSdoInitialized )
  46. return E_FAIL;
  47. _ASSERT( NULL != pCount );
  48. if ( NULL == pCount )
  49. return E_POINTER;
  50. *pCount = m_Objects.size();
  51. return S_OK;
  52. }
  53. /////////////////////////////////////////////////////////////////////////////
  54. STDMETHODIMP CSdoCollection::Add(
  55. /*[in]*/ BSTR bstrName,
  56. /*[in/out]*/ IDispatch** ppItem
  57. )
  58. {
  59. CSdoLock theLock(*this);
  60. // Check preconditions
  61. //
  62. _ASSERT ( m_fSdoInitialized );
  63. if ( ! m_fSdoInitialized )
  64. return E_FAIL;
  65. _ASSERT ( NULL != ppItem );
  66. if ( NULL == ppItem )
  67. return E_POINTER;
  68. // Get the Sdo name from the specified object if bstrName is not given
  69. //
  70. HRESULT hr = E_FAIL;
  71. _variant_t vtSdoName;
  72. if ( NULL == bstrName )
  73. {
  74. CComPtr<ISdo> pSdo;
  75. hr = (*ppItem)->QueryInterface(IID_ISdo, (void**)&pSdo);
  76. if ( FAILED(hr) )
  77. {
  78. IASTracePrintf("Error in SDO Collection - Add() - QueryInterface(ISdo) failed!...");
  79. return hr;
  80. }
  81. hr = pSdo->GetProperty(PROPERTY_SDO_NAME, &vtSdoName);
  82. if ( FAILED(hr) )
  83. {
  84. IASTracePrintf("Error in SDO Collection - Add - GetProperty(Name) failed");
  85. return hr;
  86. }
  87. bstrName = V_BSTR(&vtSdoName);
  88. }
  89. // Ensure that the SDO name is unique
  90. //
  91. VARIANT_BOOL boolVal;
  92. hr = InternalIsNameUnique(bstrName, &boolVal);
  93. if ( SUCCEEDED(hr) )
  94. {
  95. if (boolVal)
  96. {
  97. if (m_Objects.size() >= m_MaxSize)
  98. {
  99. hr = IAS_E_LICENSE_VIOLATION;
  100. }
  101. else
  102. {
  103. hr = InternalAdd(bstrName, ppItem);
  104. }
  105. }
  106. else
  107. {
  108. // Name is not unqiue
  109. //
  110. hr = E_INVALIDARG;
  111. }
  112. }
  113. return hr;
  114. }
  115. /////////////////////////////////////////////////////////////////////////////
  116. STDMETHODIMP CSdoCollection::Remove(IDispatch* pItem)
  117. {
  118. CSdoLock theLock(*this);
  119. HRESULT hr = DISP_E_MEMBERNOTFOUND;
  120. try
  121. {
  122. SDO_TRACE_VERBOSE_2("Removing item at $%p from SDO collection at $%p...", pItem, this);
  123. // Check preconditions
  124. //
  125. _ASSERT ( m_fSdoInitialized );
  126. if ( ! m_fSdoInitialized )
  127. throw _com_error(E_UNEXPECTED);
  128. _ASSERT ( NULL != pItem );
  129. if ( NULL == pItem )
  130. throw _com_error(E_POINTER);
  131. CComPtr<ISdo> pSdo;
  132. hr = pItem->QueryInterface(IID_ISdo, (void**)&pSdo);
  133. if ( FAILED(hr) )
  134. throw _com_error(hr);
  135. VariantArrayIterator p = m_Objects.begin();
  136. while ( p != m_Objects.end() )
  137. {
  138. if ( (*p).pdispVal == pItem )
  139. {
  140. // Remove the object from the underlying datastore (if neccessary)
  141. //
  142. if ( m_pDSContainer )
  143. {
  144. _variant_t vtItemName;
  145. hr = pSdo->GetProperty(PROPERTY_SDO_DATASTORE_NAME, &vtItemName);
  146. if ( FAILED(hr) )
  147. throw _com_error(hr);
  148. hr = m_pDSContainer->Remove(NULL, V_BSTR(&vtItemName));
  149. if ( FAILED(hr) )
  150. throw _com_error(hr);
  151. }
  152. // Remove the object from the collection
  153. //
  154. m_Objects.erase(p);
  155. break;
  156. }
  157. p++;
  158. }
  159. }
  160. catch (_com_error theError)
  161. {
  162. hr = theError.Error();
  163. IASTracePrintf("Error in SDO Collection - Remove() - Caught _com_error exception: %lx...", hr);
  164. }
  165. catch (...)
  166. {
  167. hr = E_UNEXPECTED;
  168. IASTracePrintf("Error in SDO Collection - Remove() - Caught unhandled exception...");
  169. }
  170. return hr;
  171. }
  172. /////////////////////////////////////////////////////////////////////////////
  173. STDMETHODIMP CSdoCollection::RemoveAll(void)
  174. {
  175. CSdoLock theLock(*this);
  176. HRESULT hr = S_OK;
  177. try
  178. {
  179. SDO_TRACE_VERBOSE_1("Clearing the items from the SDO collection at $%p...",this);
  180. _ASSERT ( m_fSdoInitialized );
  181. if ( ! m_fSdoInitialized )
  182. throw _com_error(E_UNEXPECTED);
  183. if ( ! m_Objects.empty() )
  184. {
  185. VariantArrayIterator p = m_Objects.begin();
  186. while( p != m_Objects.end() )
  187. {
  188. if ( m_pDSContainer )
  189. {
  190. CComPtr<ISdo> pSdo;
  191. hr = ((*p).pdispVal)->QueryInterface(IID_ISdo, (void**)&pSdo);
  192. if ( FAILED(hr) )
  193. throw _com_error(E_UNEXPECTED);
  194. _variant_t vtItemName;
  195. hr = pSdo->GetProperty(PROPERTY_SDO_DATASTORE_NAME, &vtItemName);
  196. if ( FAILED(hr) )
  197. throw _com_error(E_UNEXPECTED);
  198. hr = m_pDSContainer->Remove(NULL, V_BSTR(&vtItemName));
  199. if ( FAILED(hr) )
  200. throw _com_error(hr); // Datastore Error
  201. }
  202. p = m_Objects.erase(p);
  203. }
  204. }
  205. }
  206. catch(_com_error theError)
  207. {
  208. hr = theError.Error();
  209. IASTracePrintf("Error in SDO Collection - RemoveAll() - Caught _com_error exception: %lx...", hr);
  210. }
  211. catch(...)
  212. {
  213. hr = E_UNEXPECTED;
  214. IASTracePrintf("Error in SDO Collection - RemoveAll() - Caught unhandled exception...");
  215. }
  216. return hr;
  217. }
  218. //////////////////////////////////////////////////////////////////////////////
  219. STDMETHODIMP CSdoCollection::Reload(void)
  220. {
  221. CSdoLock theLock(*this);
  222. HRESULT hr = S_OK;
  223. try
  224. {
  225. _ASSERT ( m_fSdoInitialized );
  226. if ( ! m_fSdoInitialized )
  227. throw _com_error(E_UNEXPECTED);
  228. if ( m_pDSContainer )
  229. {
  230. ReleaseItems();
  231. hr = Load();
  232. }
  233. }
  234. catch(_com_error theError)
  235. {
  236. hr = theError.Error();
  237. IASTracePrintf("Error in SDO Collection - Reload() - Caught _com_error exception: %lx...", hr);
  238. }
  239. catch(...)
  240. {
  241. hr = E_UNEXPECTED;
  242. IASTracePrintf("Error in SDO Collection - Reload() - Caught unhandled exception...");
  243. }
  244. return hr;
  245. }
  246. //////////////////////////////////////////////////////////////////////////////
  247. STDMETHODIMP CSdoCollection::IsNameUnique(
  248. /*[in]*/ BSTR bstrName,
  249. /*[out]*/ VARIANT_BOOL* pBool
  250. )
  251. {
  252. CSdoLock theLock(*this);
  253. // Check preconditions
  254. //
  255. _ASSERT ( m_fSdoInitialized );
  256. if ( ! m_fSdoInitialized )
  257. return E_FAIL;
  258. _ASSERT ( NULL != bstrName && NULL != pBool );
  259. if ( NULL == bstrName || NULL == pBool )
  260. return E_POINTER;
  261. VARIANT_BOOL boolVal;
  262. HRESULT hr = InternalIsNameUnique(bstrName, &boolVal);
  263. if ( SUCCEEDED(hr) )
  264. *pBool = boolVal;
  265. return hr;
  266. }
  267. /////////////////////////////////////////////////////////////////////////////
  268. STDMETHODIMP CSdoCollection::Item(
  269. /*[in]*/ VARIANT* pName,
  270. /*[out]*/ IDispatch** ppItem
  271. )
  272. {
  273. CSdoLock theLock(*this);
  274. // Check preconditions
  275. //
  276. _ASSERT ( m_fSdoInitialized );
  277. if ( ! m_fSdoInitialized )
  278. return E_FAIL;
  279. _ASSERT ( NULL != pName && NULL != ppItem );
  280. if ( pName == NULL || ppItem == NULL )
  281. return E_POINTER;
  282. if ( VT_BSTR != V_VT(pName) )
  283. return E_INVALIDARG;
  284. SDO_TRACE_VERBOSE_2("Locating item '%ls' in SDO collection at $%p...", V_BSTR(pName), this);
  285. if ( m_Objects.empty() )
  286. {
  287. IASTracePrintf("Error in SDO Collection - Item() - Could not locate the specified item...");
  288. return DISP_E_MEMBERNOTFOUND;
  289. }
  290. HRESULT hr = DISP_E_MEMBERNOTFOUND;
  291. try
  292. {
  293. ISdo* pSdo;
  294. IDispatch* pDispatch;
  295. _variant_t varName;
  296. VariantArrayIterator p = m_Objects.begin();
  297. while ( p != m_Objects.end() )
  298. {
  299. pDispatch = (*p).pdispVal;
  300. hr = pDispatch->QueryInterface(IID_ISdo,(void **)&pSdo);
  301. if ( FAILED(hr) )
  302. break;
  303. hr = pSdo->GetProperty(PROPERTY_SDO_NAME, &varName);
  304. pSdo->Release();
  305. if ( FAILED(hr) )
  306. break;
  307. _ASSERT( V_VT(&varName) == VT_BSTR );
  308. if ( 0 == lstrcmpiW(V_BSTR(pName), V_BSTR(&varName)) )
  309. {
  310. (*ppItem = pDispatch)->AddRef();
  311. hr = S_OK;
  312. break;
  313. }
  314. varName.Clear();
  315. p++;
  316. hr = DISP_E_MEMBERNOTFOUND;
  317. }
  318. if ( FAILED(hr) )
  319. IASTracePrintf("Error in SDO Collection - Item() - Could not locate the specified item...");
  320. }
  321. catch(_com_error theCOMError)
  322. {
  323. hr = theCOMError.Error();
  324. IASTracePrintf("Error in SDO Collection - Item() - Caught COM exception...");
  325. }
  326. catch(...)
  327. {
  328. hr = DISP_E_MEMBERNOTFOUND;
  329. IASTracePrintf("Error in SDO Collection - Item() - Caught unknown exception...");
  330. }
  331. return hr;
  332. }
  333. /////////////////////////////////////////////////////////////////////////////
  334. STDMETHODIMP CSdoCollection::get__NewEnum(IUnknown** ppEnumSdo)
  335. {
  336. CSdoLock theLock(*this);
  337. // Check function preconditions
  338. //
  339. _ASSERT ( m_fSdoInitialized );
  340. if ( ! m_fSdoInitialized )
  341. return E_FAIL;
  342. _ASSERT ( NULL != ppEnumSdo );
  343. if (ppEnumSdo == NULL)
  344. return E_POINTER;
  345. HRESULT hr = E_FAIL;
  346. EnumVARIANT* newEnum = NULL;
  347. try
  348. {
  349. newEnum = new (std::nothrow) CComObject<EnumVARIANT>;
  350. if ( newEnum == NULL )
  351. {
  352. IASTracePrintf("Error in SDO Collection - get__NewEnum() - Out of memory...");
  353. return E_OUTOFMEMORY;
  354. }
  355. hr = newEnum->Init(
  356. m_Objects.begin(),
  357. m_Objects.end(),
  358. GetControllingUnknown(),
  359. AtlFlagCopy
  360. );
  361. if ( SUCCEEDED(hr) )
  362. {
  363. (*ppEnumSdo = newEnum)->AddRef();
  364. return S_OK;
  365. }
  366. }
  367. catch(...)
  368. {
  369. IASTracePrintf("Error in SDO Collection - get__NewEnum() - Caught unknown exception...");
  370. hr = E_FAIL;
  371. }
  372. if ( NULL != newEnum )
  373. delete newEnum;
  374. return hr;
  375. }
  376. STDMETHODIMP CSdoCollection::get_Limits(IAS_PRODUCT_LIMITS* pVal)
  377. {
  378. return SDOGetProductLimits(m_pSdoMachine, pVal);
  379. }
  380. /////////////////////////////////////////////////////////////////////////////
  381. // Collection Initialization / Shutdown Methods
  382. /////////////////////////////////////////////////////////////////////////////
  383. //////////////////////////////////////////////////////////////////////////////
  384. HRESULT CSdoCollection::InternalInitialize(
  385. LPCWSTR lpszCreateClassId,
  386. ISdoMachine* pSdoMachine,
  387. IDataStoreContainer* pDSContainer,
  388. size_t maxSize
  389. )
  390. {
  391. CSdoLock theLock(*this);
  392. // Check preconditions...
  393. //
  394. _ASSERT( ! m_fSdoInitialized );
  395. if ( m_fSdoInitialized )
  396. return S_OK;
  397. m_MaxSize = maxSize;
  398. HRESULT hr = S_OK;
  399. SDO_TRACE_VERBOSE_1("SDO Collection at $%p is initializing its internal state...",this);
  400. _ASSERT( NULL != pSdoMachine );
  401. m_pSdoMachine = pSdoMachine;
  402. m_pSdoMachine->AddRef();
  403. if ( lpszCreateClassId )
  404. {
  405. m_fCreateOnAdd = true;
  406. m_CreateClassId = lpszCreateClassId;
  407. if ( NULL != pDSContainer )
  408. {
  409. m_DatastoreClass = ::GetDataStoreClass(lpszCreateClassId);
  410. m_pDSContainer = pDSContainer;
  411. m_pDSContainer->AddRef();
  412. hr = Load();
  413. }
  414. }
  415. else
  416. {
  417. // Collection of SDOs for IAS components (auditors, request handlers, protocols).
  418. // New components cannot be added to this collection by a script or UI.
  419. // Instead, component parameters and class information should be added to ias.mdb
  420. _ASSERT( pDSContainer );
  421. m_pDSContainer = pDSContainer;
  422. m_pDSContainer->AddRef();
  423. hr = Load();
  424. }
  425. if ( FAILED(hr) )
  426. InternalShutdown();
  427. else
  428. m_fSdoInitialized = TRUE;
  429. return hr;
  430. }
  431. //////////////////////////////////////////////////////////////////////////////
  432. void CSdoCollection::InternalShutdown()
  433. {
  434. ReleaseItems();
  435. if ( m_pDSContainer )
  436. {
  437. m_pDSContainer->Release();
  438. m_pDSContainer = NULL;
  439. }
  440. if ( m_pSdoMachine )
  441. {
  442. m_pSdoMachine->Release();
  443. m_pSdoMachine = NULL;
  444. }
  445. m_fSdoInitialized = FALSE;
  446. }
  447. /////////////////////////////////////////////////////////////////////////////
  448. HRESULT CSdoCollection::InternalAdd(
  449. /*[in]*/ BSTR bstrName,
  450. /*[in/out]*/ IDispatch **ppItem
  451. )
  452. {
  453. HRESULT hr = S_OK;
  454. try
  455. {
  456. do
  457. {
  458. // Does the caller want us to create the item?
  459. //
  460. if ( NULL == *ppItem )
  461. {
  462. // Yes... Attempt to create the item
  463. //
  464. if ( ! m_fCreateOnAdd )
  465. {
  466. IASTracePrintf("Error in SDO Collection - Add() - Cannot create on add...");
  467. hr = E_INVALIDARG;
  468. break;
  469. }
  470. _ASSERT( NULL != bstrName );
  471. if ( NULL == bstrName )
  472. {
  473. IASTracePrintf("Error in SDO Collection - Add() - NULL object name...");
  474. hr = E_INVALIDARG;
  475. break;
  476. }
  477. SDO_TRACE_VERBOSE_1("Creating new item and additing it to SDO collection at $%p...",this);
  478. _variant_t varName = bstrName;
  479. CComPtr<IDataStoreObject> pDSObject;
  480. // Does the collection have a data store container associated with it?
  481. //
  482. if ( m_pDSContainer )
  483. {
  484. // Yes... Create a new data store object and associate it with the SDO
  485. //
  486. hr = m_pDSContainer->Create(
  487. m_DatastoreClass,
  488. bstrName,
  489. &pDSObject
  490. );
  491. if ( FAILED(hr) )
  492. {
  493. IASTracePrintf("Error in SDO Collection - Add() - Could not create a data store object...");
  494. break;
  495. }
  496. }
  497. CComPtr<ISdo> pSdo;
  498. pSdo.p = ::MakeSDO(
  499. bstrName,
  500. m_CreateClassId,
  501. m_pSdoMachine,
  502. pDSObject,
  503. static_cast<ISdoCollection*>(this),
  504. true
  505. );
  506. if ( NULL == pSdo.p )
  507. {
  508. IASTracePrintf("Error in Collection SDO - Add() - MakeSDO() failed...");
  509. hr = E_FAIL;
  510. break;
  511. }
  512. CComPtr<IDispatch> pDispatch;
  513. hr = pSdo->QueryInterface(IID_IDispatch, (void**)&pDispatch);
  514. if ( FAILED(hr) )
  515. {
  516. IASTracePrintf("Error in SDO Collection - Add() - QueryInterface(IID_IDispatch) failed...");
  517. break;
  518. }
  519. m_Objects.push_back((IDispatch*)pDispatch.p);
  520. (*ppItem = pDispatch.p)->AddRef();
  521. }
  522. else
  523. {
  524. // No... Just add the specified item to the collection
  525. //
  526. m_Objects.push_back(*ppItem);
  527. }
  528. } while ( FALSE );
  529. }
  530. catch (bad_alloc)
  531. {
  532. IASTracePrintf("Error in SDO Collection - Add() - Out of memory...");
  533. hr = E_OUTOFMEMORY;
  534. }
  535. catch(...)
  536. {
  537. IASTracePrintf("Error in SDO Collection - Add() - Caught unhandled exception...");
  538. hr = E_FAIL;
  539. }
  540. return hr;
  541. }
  542. //////////////////////////////////////////////////////////////////////////////
  543. HRESULT CSdoCollection::InternalIsNameUnique(
  544. /*[in]*/ BSTR bstrName,
  545. /*[out]*/ VARIANT_BOOL* pBool
  546. )
  547. {
  548. _variant_t vtSdoName;
  549. VariantArrayIterator p = m_Objects.begin();
  550. while ( p != m_Objects.end() )
  551. {
  552. if ( FAILED((dynamic_cast<ISdo*>((*p).pdispVal))->GetProperty(PROPERTY_SDO_NAME, &vtSdoName)) )
  553. {
  554. IASTracePrintf("Error in SDO Collection - GetProperty(PROPERTY_SDO_NAME) failed...");
  555. *pBool = VARIANT_FALSE;
  556. return E_FAIL;
  557. }
  558. if ( 0 == lstrcmpi(bstrName, V_BSTR(&vtSdoName)) )
  559. {
  560. IASTracePrintf("Error in SDO Collection - Add() - Sdo Name is Not Unique...");
  561. *pBool = VARIANT_FALSE;
  562. return S_OK;
  563. }
  564. vtSdoName.Clear();
  565. p++;
  566. }
  567. *pBool = VARIANT_TRUE;
  568. return S_OK;
  569. }
  570. //////////////////////////////////////////////////////////////////////////////
  571. HRESULT CSdoCollection::Load()
  572. {
  573. CSdoLock theLock(*this);
  574. HRESULT hr = E_FAIL;
  575. _ASSERT ( m_pDSContainer );
  576. if ( m_pDSContainer )
  577. {
  578. SDO_TRACE_VERBOSE_1("SDO Collection at $%p is loading its items from the data store...",this);
  579. CComPtr<IUnknown> pUnknown;
  580. hr = m_pDSContainer->get__NewEnum(&pUnknown);
  581. if ( FAILED(hr) )
  582. {
  583. IASTracePrintf("Error in SDO Collection SDO - Load() - IDataStoreContainer::get__NewEnum() failed...");
  584. return E_FAIL;
  585. }
  586. CComPtr<IEnumVARIANT> pEnumVariant;
  587. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)&pEnumVariant);
  588. if ( FAILED(hr) )
  589. {
  590. IASTracePrintf("Error in SDO Collection SDO - Load() - QueryInterface(IID_IEnumVARIANT) failed...");
  591. return E_FAIL;
  592. }
  593. CComBSTR bstrClassID(SDO_STOCK_PROPERTY_CLASS_ID);
  594. if (!bstrClassID) { return E_OUTOFMEMORY; }
  595. CComPtr<IDataStoreObject> pDSObject;
  596. CComPtr<ISdo> pSdoArchive;
  597. CComPtr<IDispatch> pDispatch;
  598. CComPtr<ISdo> pSdo;
  599. hr = ::SDONextObjectFromContainer(pEnumVariant, &pDSObject);
  600. while ( S_OK == hr )
  601. {
  602. if ( 0 == m_CreateClassId.length() )
  603. {
  604. _variant_t vtComponentClassId;
  605. hr = pDSObject->GetValue(bstrClassID, &vtComponentClassId);
  606. if ( FAILED(hr) )
  607. {
  608. IASTracePrintf("Error in SDO Collection SDO - LoadSdo() - IDataStoreObject::GetValue() failed...");
  609. break;
  610. }
  611. pSdo.p = ::MakeSDO(
  612. NULL,
  613. V_BSTR(&vtComponentClassId),
  614. m_pSdoMachine,
  615. pDSObject.p,
  616. static_cast<ISdoCollection*>(this),
  617. false
  618. );
  619. }
  620. else
  621. {
  622. pSdo.p = ::MakeSDO(
  623. NULL,
  624. m_CreateClassId,
  625. m_pSdoMachine,
  626. pDSObject.p,
  627. static_cast<ISdoCollection*>(this),
  628. false
  629. );
  630. }
  631. if ( NULL == pSdo.p )
  632. {
  633. IASTracePrintf("Error in SDO Collection SDO - LoadSdo() - MakeSDO() failed...");
  634. break;
  635. }
  636. hr = pSdo->QueryInterface(IID_IDispatch, (void**)&pDispatch);
  637. if ( FAILED(hr) )
  638. {
  639. IASTracePrintf("Error in SDO Collection SDO - Load() - QueryInterface(IID_IDispatch) failed...");
  640. break;
  641. }
  642. _variant_t vtName;
  643. hr = pSdo->GetProperty(PROPERTY_SDO_NAME, &vtName);
  644. if ( FAILED(hr) )
  645. {
  646. IASTracePrintf("Error in SDO Collection SDO - Load() - GetProperty(PROPERTY_SDO_NAME) failed...");
  647. break;
  648. }
  649. hr = InternalAdd(V_BSTR(&vtName), &pDispatch.p);
  650. if ( FAILED(hr) )
  651. break;
  652. vtName.Clear();
  653. pDispatch.Release();
  654. pDSObject.Release();
  655. pSdo.Release();
  656. hr = ::SDONextObjectFromContainer(pEnumVariant, &pDSObject);
  657. }
  658. if ( S_FALSE == hr )
  659. hr = S_OK;
  660. }
  661. return hr;
  662. }
  663. //////////////////////////////////////////////////////////////////////////////
  664. void CSdoCollection::ReleaseItems()
  665. {
  666. if ( ! m_Objects.empty() )
  667. {
  668. VariantArrayIterator p = m_Objects.begin();
  669. while( p != m_Objects.end() )
  670. p = m_Objects.erase(p);
  671. }
  672. }