Source code of Windows XP (NT5)
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.

831 lines
22 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright(C) 1997-1998 Microsoft Corporation all rights reserved.
  4. //
  5. // Module: sdoprofile.cpp
  6. //
  7. // Project: Everest
  8. //
  9. // Description: IAS Server Data Object - Profile Object Implementation
  10. //
  11. // Author: TLP 1/23/98
  12. //
  13. /////////////////////////////////////////////////////////////////////////////
  14. #include "stdafx.h"
  15. // C++ Exception Specification ignored
  16. #pragma warning(disable:4290)
  17. #include <iasattr.h>
  18. #include <attrcvt.h>
  19. #include <varvec.h>
  20. #include "sdoprofile.h"
  21. #include "sdohelperfuncs.h"
  22. #include <attrdef.h>
  23. #include <sdoattribute.h>
  24. #include <sdodictionary.h>
  25. //////////////////////////////////////////////////////////////////////////////
  26. CSdoProfile::CSdoProfile()
  27. : m_pSdoDictionary(NULL),
  28. m_ulAttributeCount(0),
  29. m_pAttributePositions(NULL)
  30. {
  31. }
  32. //////////////////////////////////////////////////////////////////////////////
  33. CSdoProfile::~CSdoProfile()
  34. {
  35. ShutdownAction();
  36. }
  37. //////////////////////////////////////////////////////////////////////////////
  38. HRESULT CSdoProfile::FinalInitialize(
  39. /*[in]*/ bool fInitNew,
  40. /*[in]*/ ISdoMachine* pAttachedMachine
  41. )
  42. {
  43. CComPtr<IUnknown> pUnknown;
  44. HRESULT hr = pAttachedMachine->GetDictionarySDO(&pUnknown);
  45. if ( SUCCEEDED(hr) )
  46. {
  47. hr = pUnknown->QueryInterface(IID_ISdoDictionaryOld, (void**)&m_pSdoDictionary);
  48. if ( SUCCEEDED(hr) )
  49. {
  50. hr = InitializeCollection(
  51. PROPERTY_PROFILE_ATTRIBUTES_COLLECTION,
  52. SDO_PROG_ID_ATTRIBUTE,
  53. pAttachedMachine,
  54. NULL
  55. );
  56. if ( SUCCEEDED(hr) )
  57. {
  58. if ( ! fInitNew )
  59. hr = Load();
  60. }
  61. }
  62. }
  63. return hr;
  64. }
  65. //////////////////////////////////////////////////////////////////////////////
  66. HRESULT CSdoProfile::Load()
  67. {
  68. HRESULT hr = LoadAttributes();
  69. if ( SUCCEEDED(hr) )
  70. hr = LoadProperties();
  71. return hr;
  72. }
  73. //////////////////////////////////////////////////////////////////////////////
  74. HRESULT CSdoProfile::Save()
  75. {
  76. HRESULT hr = SaveAttributes();
  77. if ( SUCCEEDED(hr) )
  78. hr = SaveProperties();
  79. return hr;
  80. }
  81. //////////////////////////////////////////////////////////////////////////////
  82. // IPolicyAction Implementation
  83. //////////////////////////////////////////////////////////////////////////////
  84. //////////////////////////////////////////////////////////////////////////////
  85. STDMETHODIMP CSdoProfile::InitializeAction()
  86. {
  87. CSdoLock theLock(*this);
  88. _ASSERT( IsSdoInitialized() );
  89. SDO_TRACE_VERBOSE_1("Profile SDO at $%p is initializing a policy action...",this);
  90. HRESULT hr = S_OK;
  91. if ( IsSdoInitialized() && NULL == m_pAttributePositions )
  92. {
  93. ULONG ulCount = 0;
  94. do
  95. {
  96. // Determine the number of IAS attributes in the profile
  97. //
  98. hr = GetAttributeCount(ulCount);
  99. if ( FAILED(hr) )
  100. break;
  101. // Profile always has at least the NP-Policy-Name attribute
  102. //
  103. ulCount++;
  104. // Allocate and initialize the appropriate number of attribute
  105. // position structures.
  106. //
  107. m_pAttributePositions = (PATTRIBUTEPOSITION) new (std::nothrow) ATTRIBUTEPOSITION[ulCount];
  108. if ( NULL == m_pAttributePositions )
  109. {
  110. IASTracePrintf("Error in Profile SDO - InitializeAction() - Memory allocation failed...");
  111. hr = E_FAIL;
  112. break;
  113. }
  114. memset(
  115. m_pAttributePositions,
  116. 0,
  117. sizeof(ATTRIBUTEPOSITION) * ulCount
  118. );
  119. m_ulAttributeCount = ulCount;
  120. // Now create and initialize the attributes in the policy action.
  121. // If no error occurs then ulCount == m_ulAttributeCount when
  122. // the conversion completes
  123. //
  124. ulCount = 0;
  125. // Add the policy name attribute to the Profile
  126. //
  127. hr = AddPolicyNameAttribute(ulCount);
  128. if ( FAILED(hr) )
  129. break;
  130. hr = ConvertAttributes(ulCount);
  131. if ( FAILED(hr) )
  132. break;
  133. } while ( FALSE );
  134. if ( FAILED(hr) )
  135. {
  136. ShutdownAction();
  137. }
  138. else
  139. {
  140. _ASSERT ( ulCount == m_ulAttributeCount );
  141. }
  142. }
  143. return hr;
  144. }
  145. //////////////////////////////////////////////////////////////////////////////
  146. STDMETHODIMP CSdoProfile::ShutdownAction()
  147. {
  148. DWORD i;
  149. SDO_TRACE_VERBOSE_1("Profile SDO at $%p is shutting down a policy action...",this);
  150. if ( m_pAttributePositions )
  151. {
  152. PATTRIBUTEPOSITION pAttrPos = m_pAttributePositions;
  153. for ( i = 0; i < m_ulAttributeCount; i++ )
  154. {
  155. if ( NULL != pAttrPos->pAttribute )
  156. IASAttributeRelease(pAttrPos->pAttribute);
  157. pAttrPos++;
  158. }
  159. delete [] m_pAttributePositions;
  160. m_pAttributePositions = NULL;
  161. m_ulAttributeCount = 0;
  162. }
  163. return S_OK;
  164. }
  165. //////////////////////////////////////////////////////////////////////////////
  166. STDMETHODIMP CSdoProfile::DoAction(
  167. /*[in]*/ IRequest* pRequest
  168. )
  169. {
  170. _ASSERT( IsSdoInitialized() );
  171. HRESULT hr = S_OK;
  172. do
  173. {
  174. if ( m_pAttributePositions )
  175. {
  176. CComPtr<IAttributesRaw> pAttributesRaw;
  177. hr = pRequest->QueryInterface(IID_IAttributesRaw, (void**)&pAttributesRaw);
  178. if ( FAILED(hr) )
  179. {
  180. IASTracePrintf("Error in Profile SDO - DoAction() - QueryInterface(IAttributesRAW) failed...");
  181. break;
  182. }
  183. hr = pAttributesRaw->AddAttributes(
  184. m_ulAttributeCount,
  185. m_pAttributePositions
  186. );
  187. if ( FAILED(hr) )
  188. {
  189. IASTracePrintf("Error in Profile SDO - DoAction() - AddAttributes() failed...");
  190. break;
  191. }
  192. }
  193. } while ( FALSE );
  194. return hr;
  195. }
  196. //////////////////////////////////////////////////////////////////////////////
  197. // Profile class private member functions
  198. //////////////////////////////////////////////////////////////////////////////
  199. //////////////////////////////////////////////////////////////////////////////
  200. HRESULT CSdoProfile::GetAttributeCount(ULONG& ulCount)
  201. {
  202. HRESULT hr = E_FAIL;
  203. ulCount = 0;
  204. do
  205. {
  206. CComPtr<IEnumVARIANT> pEnumAttributes;
  207. hr = SDOGetCollectionEnumerator(
  208. dynamic_cast<ISdo*>(this),
  209. PROPERTY_PROFILE_ATTRIBUTES_COLLECTION,
  210. &pEnumAttributes
  211. );
  212. if ( FAILED(hr) )
  213. {
  214. IASTracePrintf("Error in Profile SDO - GetAttributeCount() - SDOGetCollectionEnumerator() failed...");
  215. break;
  216. }
  217. CComPtr<ISdo> pSdoAttribute;
  218. hr = SDONextObjectFromCollection(pEnumAttributes, &pSdoAttribute);
  219. while ( S_OK == hr )
  220. {
  221. {
  222. _variant_t vt;
  223. hr = pSdoAttribute->GetProperty(PROPERTY_ATTRIBUTE_VALUE, &vt);
  224. if ( FAILED(hr) )
  225. break;
  226. if ( (VT_ARRAY | VT_VARIANT) == V_VT(&vt) )
  227. {
  228. CVariantVector<VARIANT> Attribute(&vt);
  229. ulCount += Attribute.size();
  230. }
  231. else
  232. {
  233. ulCount++;
  234. }
  235. }
  236. pSdoAttribute.Release();
  237. hr = SDONextObjectFromCollection(pEnumAttributes, &pSdoAttribute);
  238. }
  239. if ( S_FALSE == hr )
  240. hr = S_OK;
  241. } while ( FALSE );
  242. return hr;
  243. }
  244. //////////////////////////////////////////////////////////////////////////////
  245. HRESULT CSdoProfile::ConvertAttributes(ULONG& ulCount)
  246. {
  247. HRESULT hr = E_FAIL;
  248. do
  249. {
  250. CComPtr<IEnumVARIANT> pEnumAttributes;
  251. hr = SDOGetCollectionEnumerator(
  252. dynamic_cast<ISdo*>(this),
  253. PROPERTY_PROFILE_ATTRIBUTES_COLLECTION,
  254. &pEnumAttributes
  255. );
  256. if ( FAILED(hr) )
  257. {
  258. IASTracePrintf("Error in Profile SDO - ConvertAttributes() - SDOGetCollectionEnumerator() failed...");
  259. break;
  260. }
  261. CComPtr<ISdo> pSdoAttribute;
  262. hr = SDONextObjectFromCollection(pEnumAttributes, &pSdoAttribute);
  263. while ( S_OK == hr )
  264. {
  265. // Convert the SDO attribute to an IAS attribute
  266. //
  267. hr = ConvertSDOAttrToIASAttr(pSdoAttribute, ulCount);
  268. if ( FAILED(hr) )
  269. {
  270. IASTracePrintf("Error in Profile SDO - InitializeAction() - ConvertSDOAttrToIASAttr() failed...");
  271. break;
  272. }
  273. // Next SDO Attribute
  274. //
  275. pSdoAttribute.Release();
  276. hr = SDONextObjectFromCollection(pEnumAttributes, &pSdoAttribute);
  277. }
  278. if ( S_FALSE == hr )
  279. hr = S_OK;
  280. } while ( FALSE );
  281. return hr;
  282. }
  283. //////////////////////////////////////////////////////////////////////////////
  284. HRESULT CSdoProfile::AddPolicyNameAttribute(ULONG& ulCount)
  285. {
  286. HRESULT hr = E_FAIL;
  287. do
  288. {
  289. _ASSERT( ulCount < m_ulAttributeCount );
  290. _variant_t vtPolicyName;
  291. hr = GetPropertyInternal(
  292. PROPERTY_SDO_NAME,
  293. &vtPolicyName
  294. );
  295. if ( FAILED(hr) )
  296. break;
  297. PIASATTRIBUTE pIASAttr = IASAttributeFromVariant(
  298. &vtPolicyName,
  299. IASTYPE_STRING
  300. );
  301. if ( NULL == pIASAttr )
  302. break;
  303. pIASAttr->dwId = IAS_ATTRIBUTE_NP_NAME;
  304. pIASAttr->dwFlags = IAS_INCLUDE_IN_ACCEPT | IAS_INCLUDE_IN_REJECT;
  305. (m_pAttributePositions+ulCount)->pAttribute = pIASAttr;
  306. ulCount++;
  307. hr = S_OK;
  308. } while ( FALSE );
  309. return hr;
  310. }
  311. //////////////////////////////////////////////////////////////////////////////
  312. HRESULT CSdoProfile::ConvertSDOAttrToIASAttr(
  313. /*[in]*/ ISdo* pSdoAttribute,
  314. /*[in/out]*/ ULONG& ulCount
  315. )
  316. {
  317. HRESULT hr;
  318. DWORD dwAttrID;
  319. IASTYPE itAttrType;
  320. PIASATTRIBUTE pIASAttr;
  321. _variant_t vt;
  322. try
  323. {
  324. // Get the pertinent information from the SDO Attribute
  325. //
  326. hr = pSdoAttribute->GetProperty(PROPERTY_ATTRIBUTE_ID, &vt);
  327. if ( FAILED(hr) )
  328. return E_FAIL;
  329. dwAttrID = vt.lVal;
  330. hr = pSdoAttribute->GetProperty(PROPERTY_ATTRIBUTE_SYNTAX, &vt);
  331. if ( FAILED(hr) )
  332. return E_FAIL;
  333. itAttrType = (IASTYPE) vt.lVal;
  334. hr = pSdoAttribute->GetProperty(PROPERTY_ATTRIBUTE_VALUE, &vt);
  335. if ( FAILED(hr) )
  336. return E_FAIL;
  337. // If the attribute is represented by a safearray of homogeneous variants then we'll
  338. // make an IAS attribute of the appropriate type out of each variant in the safe array.
  339. //
  340. // If the attribute value is variant then we'll covert the variant to an IAS
  341. // attribute of the appropriate type
  342. //
  343. if ( V_VT(&vt) == (VT_ARRAY | VT_VARIANT) )
  344. {
  345. {
  346. _variant_t vtAttribute;
  347. CVariantVector<VARIANT> Attribute(&vt);
  348. ULONG ulAttributeCount = 0;
  349. while ( ulAttributeCount < Attribute.size() )
  350. {
  351. _ASSERT( ulCount < m_ulAttributeCount );
  352. vtAttribute = Attribute[ulAttributeCount];
  353. if ( RADIUS_ATTRIBUTE_VENDOR_SPECIFIC == dwAttrID)
  354. {
  355. pIASAttr = VSAAttributeFromVariant(&vtAttribute, itAttrType);
  356. }
  357. else
  358. {
  359. pIASAttr = IASAttributeFromVariant(&vtAttribute, itAttrType);
  360. }
  361. if ( NULL == pIASAttr )
  362. {
  363. hr = E_FAIL;
  364. break;
  365. }
  366. pIASAttr->dwId = dwAttrID;
  367. pIASAttr->dwFlags |= IAS_INCLUDE_IN_ACCEPT;
  368. (m_pAttributePositions+ulCount)->pAttribute = pIASAttr;
  369. ulAttributeCount++;
  370. ulCount++;
  371. }
  372. }
  373. }
  374. else
  375. {
  376. _ASSERT( ulCount < m_ulAttributeCount );
  377. if ( RADIUS_ATTRIBUTE_VENDOR_SPECIFIC == dwAttrID )
  378. {
  379. pIASAttr = VSAAttributeFromVariant (&vt, itAttrType);
  380. }
  381. else
  382. {
  383. pIASAttr = IASAttributeFromVariant(&vt, itAttrType);
  384. }
  385. if ( NULL != pIASAttr )
  386. {
  387. pIASAttr->dwId = dwAttrID;
  388. pIASAttr->dwFlags |= IAS_INCLUDE_IN_ACCEPT;
  389. (m_pAttributePositions+ulCount)->pAttribute = pIASAttr;
  390. ulCount++;
  391. }
  392. else
  393. {
  394. hr = E_FAIL;
  395. }
  396. }
  397. }
  398. catch (...)
  399. {
  400. hr = E_FAIL;
  401. }
  402. return hr;
  403. }
  404. //////////////////////////////////////////////////////////////////////////////
  405. // Load the Profile SDO's attributes from the persistent store
  406. //////////////////////////////////////////////////////////////////////////////
  407. HRESULT CSdoProfile::LoadAttributes()
  408. {
  409. HRESULT hr;
  410. ATTRIBUTEID AttributeID;
  411. SDO_TRACE_VERBOSE_1("Profile SDO at $%p is loading profile attributes from the data store...",this);
  412. _variant_t vtAttributes;
  413. hr = GetPropertyInternal(PROPERTY_PROFILE_ATTRIBUTES_COLLECTION, &vtAttributes);
  414. if ( FAILED(hr) )
  415. {
  416. IASTracePrintf("Error in Profile SDO - LoadAttributes() - Could not get attributes collection...");
  417. return E_FAIL;
  418. }
  419. CComPtr<ISdoCollection> pAttributes;
  420. hr = vtAttributes.pdispVal->QueryInterface(IID_ISdoCollection, (void**)&pAttributes);
  421. if ( FAILED(hr) )
  422. {
  423. IASTracePrintf("Error in Profile SDO - LoadAttributes() - QueryInterface(ISdoCollection) failed...");
  424. return E_FAIL;
  425. }
  426. // Clear the current contents of the profile attributes collection
  427. //
  428. pAttributes->RemoveAll();
  429. // Create a new attribute SDO for each profile attribute
  430. //
  431. CComPtr<IUnknown> pUnknown;
  432. hr = m_pDSObject->get__NewEnum(&pUnknown);
  433. if ( FAILED(hr) )
  434. {
  435. IASTracePrintf("Error in Profile SDO - LoadAttributes() - get__NewEnum() failed...");
  436. return E_FAIL;
  437. }
  438. CComPtr<IEnumVARIANT> pEnumVariant;
  439. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)&pEnumVariant);
  440. if ( FAILED(hr) )
  441. {
  442. IASTracePrintf("Error in Profile SDO - LoadAttributes() - QueryInterface(IEnumVARIANT) failed...");
  443. return E_FAIL;
  444. }
  445. _variant_t vtDSProperty;
  446. DWORD dwRetrieved = 1;
  447. hr = pEnumVariant->Next(1, &vtDSProperty, &dwRetrieved);
  448. if ( S_FALSE == hr )
  449. {
  450. IASTracePrintf("Error in Profile SDO - LoadAttributes() - No profile object properties...");
  451. return E_FAIL;
  452. }
  453. BSTR bstrName = NULL;
  454. CComPtr<IDataStoreProperty> pDSProperty;
  455. while ( S_OK == hr )
  456. {
  457. hr = vtDSProperty.pdispVal->QueryInterface(IID_IDataStoreProperty, (void**)&pDSProperty);
  458. if ( FAILED(hr) )
  459. {
  460. IASTracePrintf("Error in Profile SDO - LoadAttributes() - QueryInterface(IEnumDataStoreProperty) failed...");
  461. break;
  462. }
  463. hr = pDSProperty->get_Name(&bstrName);
  464. if ( FAILED(hr) )
  465. {
  466. IASTracePrintf("Error in Profile SDO - LoadAttributes() - get_Name() failed for %ls...", bstrName);
  467. break;
  468. }
  469. // If the attribute is not in the dictionary, then it's not an
  470. // attribute and it doesn't belong in the SDO collection.
  471. const AttributeDefinition* def = m_pSdoDictionary->findByLdapName(
  472. bstrName
  473. );
  474. if (def)
  475. {
  476. // Create an attribute SDO.
  477. CComPtr<SdoAttribute> attr;
  478. hr = SdoAttribute::createInstance(def, &attr);
  479. if (FAILED(hr)) { break; }
  480. // Set the value from the datastore.
  481. if (attr->def->restrictions & MULTIVALUED)
  482. {
  483. hr = pDSProperty->get_ValueEx(&attr->value);
  484. }
  485. else
  486. {
  487. hr = pDSProperty->get_Value(&attr->value);
  488. }
  489. if (FAILED(hr))
  490. {
  491. IASTraceFailure("IDataStore2::GetValue", hr);
  492. break;
  493. }
  494. // Add the attribute to the attributes collection.
  495. hr = pAttributes->Add(def->name, (IDispatch**)&attr);
  496. if (FAILED(hr)) { break; }
  497. SDO_TRACE_VERBOSE_2("Profile SDO at $%p loaded attribute '%S'",
  498. this, bstrName);
  499. }
  500. // Next profile object property
  501. //
  502. pDSProperty.Release();
  503. vtDSProperty.Clear();
  504. SysFreeString(bstrName);
  505. bstrName = NULL;
  506. dwRetrieved = 1;
  507. hr = pEnumVariant->Next(1, &vtDSProperty, &dwRetrieved);
  508. }
  509. if ( S_FALSE == hr )
  510. hr = S_OK;
  511. if ( bstrName )
  512. SysFreeString(bstrName);
  513. return hr;
  514. }
  515. //////////////////////////////////////////////////////////////////////////////
  516. // Save the Profile SDO's attributes to the persistent store
  517. //////////////////////////////////////////////////////////////////////////////
  518. HRESULT CSdoProfile::SaveAttributes()
  519. {
  520. HRESULT hr;
  521. SDO_TRACE_VERBOSE_1("Profile SDO at $%p is saving profile attributes...",this);
  522. hr = ClearAttributes();
  523. if ( FAILED(hr) )
  524. return E_FAIL;
  525. _variant_t vtAttributes;
  526. hr = GetPropertyInternal(PROPERTY_PROFILE_ATTRIBUTES_COLLECTION, &vtAttributes);
  527. if ( FAILED(hr) )
  528. {
  529. IASTracePrintf("Error in Profile SDO - LoadAttributes() - Could not get attributes collection...");
  530. return E_FAIL;
  531. }
  532. CComPtr<ISdoCollection> pAttributes;
  533. hr = vtAttributes.pdispVal->QueryInterface(IID_ISdoCollection, (void**)&pAttributes);
  534. if ( FAILED(hr) )
  535. {
  536. IASTracePrintf("Error in Profile SDO - LoadAttributes() - QueryInterface(ISdoCollection) failed...");
  537. return E_FAIL;
  538. }
  539. // Store the "Value" property of each Attribute SDO as a
  540. // profile attribute value.
  541. //
  542. CComPtr<IUnknown> pUnknown;
  543. hr = pAttributes->get__NewEnum(&pUnknown);
  544. if ( FAILED(hr) )
  545. {
  546. IASTracePrintf("Error in Profile SDO - SaveAttributes() - get__NewEnum() failed...");
  547. return E_FAIL;
  548. }
  549. CComPtr<IEnumVARIANT> pEnumVariant;
  550. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)&pEnumVariant);
  551. if ( FAILED(hr) )
  552. {
  553. IASTracePrintf("Error in Profile SDO - SaveAttributes() - QueryInterface(IEnumVARIANT) failed...");
  554. return E_FAIL;
  555. }
  556. _variant_t vtAttribute;
  557. DWORD dwRetrieved = 1;
  558. hr = pEnumVariant->Next(1, &vtAttribute, &dwRetrieved);
  559. if ( S_FALSE == hr )
  560. {
  561. SDO_TRACE_VERBOSE_1("Profile SDO at $%p has an empty attributes collection...",this);
  562. return S_OK;
  563. }
  564. CComPtr<ISdo> pSdo;
  565. _variant_t vtName;
  566. _variant_t vtValue;
  567. _variant_t vtMultiValued;
  568. while ( S_OK == hr )
  569. {
  570. hr = vtAttribute.pdispVal->QueryInterface(IID_ISdo, (void**)&pSdo);
  571. if ( FAILED(hr) )
  572. {
  573. IASTracePrintf("Error in Profile SDO - SaveAttributes() - QueryInterface(ISdo) failed...");
  574. hr = E_FAIL;
  575. break;
  576. }
  577. hr = pSdo->GetProperty(PROPERTY_ATTRIBUTE_DISPLAY_NAME, &vtName);
  578. if ( FAILED(hr) )
  579. break;
  580. if ( 0 == lstrlen(V_BSTR(&vtName)) )
  581. {
  582. IASTracePrintf("Error in Profile SDO - SaveAttributes() - dictionary corrupt?...");
  583. hr = E_FAIL;
  584. break;
  585. }
  586. hr = pSdo->GetProperty(PROPERTY_ATTRIBUTE_VALUE, &vtValue);
  587. if ( FAILED(hr) )
  588. break;
  589. hr = pSdo->GetProperty(PROPERTY_ATTRIBUTE_ALLOW_MULTIPLE, &vtMultiValued);
  590. if ( FAILED(hr) )
  591. break;
  592. if ( V_BOOL(&vtMultiValued) == VARIANT_TRUE )
  593. {
  594. _variant_t vtType;
  595. hr = pSdo->GetProperty(PROPERTY_ATTRIBUTE_SYNTAX, &vtType);
  596. if ( FAILED(hr) )
  597. break;
  598. hr = m_pDSObject->PutValue(V_BSTR(&vtName), &vtValue);
  599. }
  600. else
  601. {
  602. hr = m_pDSObject->PutValue(V_BSTR(&vtName), &vtValue);
  603. }
  604. if ( FAILED(hr) )
  605. {
  606. IASTracePrintf("Error in Profile SDO - SaveAttributes() - PutValue() failed...");
  607. break;
  608. }
  609. SDO_TRACE_VERBOSE_2("Profile SDO at $%p saved attribute '%ls'...", this, vtName.bstrVal);
  610. pSdo.Release();
  611. vtAttribute.Clear();
  612. vtName.Clear();
  613. vtValue.Clear();
  614. vtMultiValued.Clear();
  615. dwRetrieved = 1;
  616. hr = pEnumVariant->Next(1, &vtAttribute, &dwRetrieved);
  617. }
  618. if ( S_FALSE == hr )
  619. hr = S_OK;
  620. return hr;
  621. }
  622. //////////////////////////////////////////////////////////////////////////////
  623. // Deletes the Profile SDO's attributes from the persistent store
  624. //////////////////////////////////////////////////////////////////////////////
  625. HRESULT CSdoProfile::ClearAttributes(void)
  626. {
  627. HRESULT hr;
  628. ATTRIBUTEID AttributeID;
  629. SDO_TRACE_VERBOSE_1("Profile SDO at $%p is clearing its profile attributes...",this);
  630. _ASSERT( NULL != m_pDSObject);
  631. // Set each profile attribute that has a representation in the IAS dictionary to VT_EMPTY
  632. //
  633. CComPtr<IUnknown> pUnknown;
  634. hr = m_pDSObject->get__NewEnum(&pUnknown);
  635. if ( FAILED(hr) )
  636. {
  637. IASTracePrintf("Error in Profile SDO - ClearAttributes() - get__NewEnum() failed...");
  638. return E_FAIL;
  639. }
  640. CComPtr<IEnumVARIANT> pEnumVariant;
  641. hr = pUnknown->QueryInterface(IID_IEnumVARIANT, (void**)&pEnumVariant);
  642. if ( FAILED(hr) )
  643. {
  644. IASTracePrintf("Error in Profile SDO - ClearAttributes() - QueryInterface(IEnumVARIANT) failed...");
  645. return E_FAIL;
  646. }
  647. DWORD dwRetrieved = 1;
  648. _variant_t vtDSProperty;
  649. hr = pEnumVariant->Next(1, &vtDSProperty, &dwRetrieved);
  650. if ( S_FALSE == hr )
  651. {
  652. SDO_TRACE_VERBOSE_1("Profile SDO at $%p has no profile attributes in the data store...",this);
  653. return S_OK;
  654. }
  655. BSTR bstrName = NULL;
  656. CComPtr<IDataStoreProperty> pDSProperty;
  657. _variant_t vtEmpty;
  658. while ( S_OK == hr )
  659. {
  660. hr = vtDSProperty.pdispVal->QueryInterface(IID_IDataStoreProperty, (void**)&pDSProperty);
  661. if ( FAILED(hr) )
  662. {
  663. IASTracePrintf("Error in Profile SDO - ClearAttributes() - QueryInterface(IDataStoreProperty) failed...");
  664. hr = E_FAIL;
  665. break;
  666. }
  667. hr = pDSProperty->get_Name(&bstrName);
  668. if ( FAILED(hr) )
  669. {
  670. IASTracePrintf("Error in Profile SDO - ClearAttributes() - IDataStoreProperty::Name() failed...");
  671. break;
  672. }
  673. hr = m_pSdoDictionary->GetAttributeID(bstrName, &AttributeID);
  674. if ( SUCCEEDED(hr) )
  675. {
  676. hr = m_pDSObject->PutValue(bstrName, &vtEmpty);
  677. if ( FAILED(hr) )
  678. {
  679. IASTracePrintf("Error in Profile SDO - ClearAttributes() - IDataStoreObject::PutValue() failed...");
  680. break;
  681. }
  682. SDO_TRACE_VERBOSE_2("Profile SDO at $%p cleared attribute '%ls'...", this, bstrName);
  683. }
  684. pDSProperty.Release();
  685. vtDSProperty.Clear();
  686. SysFreeString(bstrName);
  687. bstrName = NULL;
  688. dwRetrieved = 1;
  689. hr = pEnumVariant->Next(1, &vtDSProperty, &dwRetrieved);
  690. }
  691. if ( S_FALSE == hr )
  692. hr = S_OK;
  693. if ( bstrName )
  694. SysFreeString(bstrName);
  695. return hr;
  696. }