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.

1077 lines
19 KiB

  1. //
  2. // Microsoft Windows
  3. // Copyright (C) Microsoft Corporation, 1992 - 1995
  4. //
  5. // File: cdomain.cxx
  6. //
  7. // Contents: Microsoft ADs NDS Provider Tree Object
  8. //
  9. //
  10. // History: 01-30-95 krishnag Created.
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "nds.hxx"
  14. #pragma hdrstop
  15. // Class CNDSTree
  16. DEFINE_IDispatch_Implementation(CNDSTree)
  17. DEFINE_IADs_Implementation(CNDSTree)
  18. CNDSTree::CNDSTree():
  19. _pPropertyCache(NULL)
  20. {
  21. VariantInit(&_vFilter);
  22. _hADsContext = NULL;
  23. _pszNDSTreeName = _pszNDSDn = NULL;
  24. ENLIST_TRACKING(CNDSTree);
  25. }
  26. HRESULT
  27. CNDSTree::CreateTreeObject(
  28. BSTR bstrADsPath,
  29. CCredentials& Credentials,
  30. DWORD dwObjectState,
  31. REFIID riid,
  32. void **ppvObj
  33. )
  34. {
  35. HRESULT hr = S_OK;
  36. WCHAR szADsParent[MAX_PATH];
  37. WCHAR szCommonName[MAX_PATH];
  38. //
  39. // Determine the parent and rdn name
  40. //
  41. hr = BuildADsParentPath(
  42. bstrADsPath,
  43. szADsParent,
  44. szCommonName
  45. );
  46. //
  47. // call the helper function
  48. //
  49. hr = CNDSTree::CreateTreeObject(
  50. szADsParent,
  51. szCommonName,
  52. L"user",
  53. Credentials,
  54. dwObjectState,
  55. riid,
  56. ppvObj
  57. );
  58. RRETURN(hr);
  59. }
  60. HRESULT
  61. CNDSTree::CreateTreeObject(
  62. BSTR Parent,
  63. BSTR CommonName,
  64. BSTR ClassName,
  65. CCredentials& Credentials,
  66. DWORD dwObjectState,
  67. REFIID riid,
  68. void **ppvObj
  69. )
  70. {
  71. CNDSTree FAR * pTree = NULL;
  72. HRESULT hr = S_OK;
  73. hr = AllocateTree(Credentials, &pTree);
  74. BAIL_ON_FAILURE(hr);
  75. hr = pTree->InitializeCoreObject(
  76. Parent,
  77. CommonName,
  78. ClassName,
  79. L"",
  80. CLSID_NDSTree,
  81. dwObjectState
  82. );
  83. BAIL_ON_FAILURE(hr);
  84. hr = BuildNDSPathFromADsPath2(
  85. pTree->_ADsPath,
  86. &(pTree->_pszNDSTreeName),
  87. &(pTree->_pszNDSDn)
  88. );
  89. BAIL_ON_FAILURE(hr);
  90. hr = ADsNdsOpenContext(
  91. pTree->_pszNDSTreeName,
  92. Credentials,
  93. &(pTree->_hADsContext)
  94. );
  95. BAIL_ON_FAILURE(hr);
  96. hr = pTree->QueryInterface(riid, ppvObj);
  97. BAIL_ON_FAILURE(hr);
  98. pTree->Release();
  99. RRETURN(hr);
  100. error:
  101. delete pTree;
  102. RRETURN(hr);
  103. }
  104. CNDSTree::~CNDSTree( )
  105. {
  106. VariantClear(&_vFilter);
  107. if (_hADsContext) {
  108. ADsNdsCloseContext(_hADsContext);
  109. }
  110. if (_pszNDSTreeName) {
  111. FreeADsMem(_pszNDSTreeName);
  112. }
  113. if (_pszNDSDn) {
  114. FreeADsMem(_pszNDSDn);
  115. }
  116. delete _pDispMgr;
  117. delete _pPropertyCache;
  118. }
  119. STDMETHODIMP
  120. CNDSTree::QueryInterface(REFIID iid, LPVOID FAR* ppv)
  121. {
  122. if (ppv == NULL) {
  123. RRETURN(E_POINTER);
  124. }
  125. if (IsEqualIID(iid, IID_IUnknown))
  126. {
  127. *ppv = (IADs FAR *) this;
  128. }
  129. else if (IsEqualIID(iid, IID_IADsContainer))
  130. {
  131. *ppv = (IADsContainer FAR *) this;
  132. }
  133. else if (IsEqualIID(iid, IID_IADs))
  134. {
  135. *ppv = (IADs FAR *) this;
  136. }
  137. else if (IsEqualIID(iid, IID_IDispatch))
  138. {
  139. *ppv = (IADs FAR *) this;
  140. }
  141. else
  142. {
  143. *ppv = NULL;
  144. return E_NOINTERFACE;
  145. }
  146. AddRef();
  147. return NOERROR;
  148. }
  149. HRESULT
  150. CNDSTree::SetInfo()
  151. {
  152. DWORD dwStatus = 0L;
  153. WCHAR szNDSPathName[MAX_PATH];
  154. HANDLE hOperationData = NULL;
  155. HANDLE hObject = NULL;
  156. HRESULT hr = S_OK;
  157. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  158. hr = NDSCreateObject();
  159. BAIL_ON_FAILURE(hr);
  160. //
  161. // If the create succeded, set the object type to bound
  162. //
  163. SetObjectState(ADS_OBJECT_BOUND);
  164. }else {
  165. hr = NDSSetObject();
  166. BAIL_ON_FAILURE(hr);
  167. }
  168. error:
  169. RRETURN(hr);
  170. }
  171. HRESULT
  172. CNDSTree::NDSSetObject()
  173. {
  174. NDS_BUFFER_HANDLE hOperationData = NULL;
  175. HRESULT hr = S_OK;
  176. hr = ADsNdsCreateBuffer(
  177. _hADsContext,
  178. DSV_MODIFY_ENTRY,
  179. &hOperationData
  180. );
  181. BAIL_ON_FAILURE(hr);
  182. hr = _pPropertyCache->NDSMarshallProperties(
  183. _hADsContext,
  184. hOperationData
  185. );
  186. BAIL_ON_FAILURE(hr);
  187. hr = ADsNdsModifyObject(
  188. _hADsContext,
  189. _pszNDSDn,
  190. hOperationData
  191. );
  192. BAIL_ON_FAILURE(hr);
  193. error:
  194. if (hOperationData) {
  195. ADsNdsFreeBuffer(hOperationData);
  196. }
  197. RRETURN(hr);
  198. }
  199. HRESULT
  200. CNDSTree::NDSCreateObject()
  201. {
  202. NDS_BUFFER_HANDLE hOperationData = NULL;
  203. HRESULT hr = S_OK;
  204. BOOLEAN fUserObject = FALSE;
  205. BSTR bstrClass = NULL;
  206. hr = ADsNdsCreateBuffer(
  207. _hADsContext,
  208. DSV_ADD_ENTRY,
  209. &hOperationData
  210. );
  211. BAIL_ON_FAILURE(hr);
  212. hr = get_CoreADsClass(&bstrClass);
  213. if (SUCCEEDED(hr)) {
  214. if (_wcsicmp(bstrClass, L"user") == 0) {
  215. fUserObject = TRUE;
  216. }
  217. }
  218. hr = _pPropertyCache->NDSMarshallProperties(
  219. _hADsContext,
  220. hOperationData
  221. );
  222. BAIL_ON_FAILURE(hr);
  223. hr = ADsNdsAddObject(
  224. _hADsContext,
  225. _pszNDSDn,
  226. hOperationData
  227. );
  228. BAIL_ON_FAILURE(hr);
  229. if (fUserObject) {
  230. hr = ADsNdsGenObjectKey(_hADsContext,
  231. _pszNDSDn);
  232. BAIL_ON_FAILURE(hr);
  233. }
  234. error:
  235. if (bstrClass) {
  236. ADsFreeString(bstrClass);
  237. }
  238. if (hOperationData) {
  239. ADsNdsFreeBuffer(hOperationData);
  240. }
  241. RRETURN(hr);
  242. }
  243. HRESULT
  244. CNDSTree::GetInfo()
  245. {
  246. RRETURN(GetInfo(TRUE));
  247. }
  248. HRESULT
  249. CNDSTree::GetInfo(
  250. BOOL fExplicit
  251. )
  252. {
  253. NDS_CONTEXT_HANDLE hADsContext = NULL;
  254. HRESULT hr = S_OK;
  255. PNDS_ATTR_INFO lpEntries = NULL;
  256. DWORD dwNumEntries = 0, i = 0;
  257. if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  258. hr = E_ADS_OBJECT_UNBOUND;
  259. BAIL_ON_FAILURE(hr);
  260. }
  261. hr = ADsNdsReadObject(
  262. _hADsContext,
  263. _pszNDSDn,
  264. DS_ATTRIBUTE_VALUES,
  265. NULL,
  266. (DWORD) -1, // signifies all attributes need to be returned
  267. NULL,
  268. &lpEntries,
  269. &dwNumEntries
  270. );
  271. BAIL_ON_FAILURE(hr);
  272. for (i = 0; i < dwNumEntries; i++) {
  273. //
  274. // unmarshall this property into the
  275. // property cache
  276. //
  277. //
  278. hr = _pPropertyCache->unmarshallproperty(
  279. lpEntries[i].szAttributeName,
  280. lpEntries[i].lpValue,
  281. lpEntries[i].dwNumberOfValues,
  282. lpEntries[i].dwSyntaxId,
  283. fExplicit
  284. );
  285. CONTINUE_ON_FAILURE(hr);
  286. }
  287. error:
  288. FreeNdsAttrInfo( lpEntries, dwNumEntries );
  289. RRETURN(hr);
  290. }
  291. STDMETHODIMP
  292. CNDSTree::GetInfoEx(THIS_ VARIANT vProperties, long lnReserved)
  293. {
  294. RRETURN(E_NOTIMPL);
  295. }
  296. /* IADsContainer methods */
  297. STDMETHODIMP
  298. CNDSTree::get_Count(long FAR* retval)
  299. {
  300. RRETURN(E_NOTIMPL);
  301. }
  302. STDMETHODIMP
  303. CNDSTree::get_Filter(THIS_ VARIANT FAR* pVar)
  304. {
  305. VariantInit(pVar);
  306. RRETURN(VariantCopy(pVar, &_vFilter));
  307. }
  308. STDMETHODIMP
  309. CNDSTree::put_Filter(THIS_ VARIANT Var)
  310. {
  311. VariantClear(&_vFilter);
  312. RRETURN(VariantCopy(&_vFilter, &Var));
  313. }
  314. STDMETHODIMP
  315. CNDSTree::put_Hints(THIS_ VARIANT Var)
  316. {
  317. RRETURN( E_NOTIMPL);
  318. }
  319. STDMETHODIMP
  320. CNDSTree::get_Hints(THIS_ VARIANT FAR* pVar)
  321. {
  322. RRETURN(E_NOTIMPL);
  323. }
  324. STDMETHODIMP
  325. CNDSTree::GetObject(
  326. BSTR ClassName,
  327. BSTR RelativeName,
  328. IDispatch * FAR* ppObject
  329. )
  330. {
  331. HRESULT hr = S_OK;
  332. hr = ::RelativeGetObject(
  333. _ADsPath,
  334. ClassName,
  335. RelativeName,
  336. _Credentials,
  337. ppObject,
  338. FALSE
  339. );
  340. RRETURN(hr);
  341. }
  342. STDMETHODIMP
  343. CNDSTree::get__NewEnum(
  344. THIS_ IUnknown * FAR* retval
  345. )
  346. {
  347. HRESULT hr;
  348. IUnknown FAR* punkEnum=NULL;
  349. IEnumVARIANT * penum = NULL;
  350. *retval = NULL;
  351. hr = CNDSTreeEnum::Create(
  352. (CNDSTreeEnum **)&penum,
  353. _ADsPath,
  354. _vFilter,
  355. _Credentials
  356. );
  357. BAIL_ON_FAILURE(hr);
  358. hr = penum->QueryInterface(
  359. IID_IUnknown,
  360. (VOID FAR* FAR*)retval
  361. );
  362. BAIL_ON_FAILURE(hr);
  363. if (penum) {
  364. penum->Release();
  365. }
  366. RRETURN(NOERROR);
  367. error:
  368. if (penum) {
  369. delete penum;
  370. }
  371. RRETURN(hr);
  372. }
  373. STDMETHODIMP
  374. CNDSTree::Create(
  375. THIS_ BSTR ClassName,
  376. BSTR RelativeName,
  377. IDispatch * FAR* ppObject
  378. )
  379. {
  380. HRESULT hr = S_OK;
  381. IADs * pADs = NULL;
  382. VARIANT var;
  383. WCHAR szNDSTreeName[MAX_PATH];
  384. DWORD dwSyntaxId = 0;
  385. //
  386. // Get the TreeName for this object
  387. //
  388. hr = BuildNDSTreeNameFromADsPath(
  389. _ADsPath,
  390. szNDSTreeName
  391. );
  392. BAIL_ON_FAILURE(hr);
  393. //
  394. // Validate if this class really exists in the schema
  395. // and validate that this object can be created in this
  396. // container
  397. //
  398. hr = CNDSGenObject::CreateGenericObject(
  399. _ADsPath,
  400. RelativeName,
  401. ClassName,
  402. _Credentials,
  403. ADS_OBJECT_UNBOUND,
  404. IID_IDispatch,
  405. (void **)ppObject
  406. );
  407. BAIL_ON_FAILURE(hr);
  408. error:
  409. RRETURN(hr);
  410. }
  411. STDMETHODIMP
  412. CNDSTree::Delete(
  413. THIS_ BSTR bstrClassName,
  414. BSTR bstrRelativeName
  415. )
  416. {
  417. HRESULT hr = S_OK;
  418. BSTR bstrChildPath = NULL;
  419. LPWSTR pszNDSTreeName = NULL;
  420. LPWSTR pszChildNDSDn = NULL;
  421. LPWSTR ppszAttrs[] = {L"object Class"};
  422. PNDS_ATTR_INFO pAttrEntries = NULL;
  423. DWORD dwNumEntries = 0;
  424. LPWSTR pszObjectClassName = NULL;
  425. hr = BuildADsPath(
  426. _ADsPath,
  427. bstrRelativeName,
  428. &bstrChildPath
  429. );
  430. BAIL_ON_FAILURE(hr);
  431. hr = BuildNDSPathFromADsPath2(
  432. bstrChildPath,
  433. &pszNDSTreeName,
  434. &pszChildNDSDn
  435. );
  436. BAIL_ON_FAILURE(hr);
  437. hr = ADsNdsReadObject(
  438. _hADsContext,
  439. pszChildNDSDn,
  440. DS_ATTRIBUTE_VALUES,
  441. ppszAttrs,
  442. 1,
  443. NULL,
  444. &pAttrEntries,
  445. &dwNumEntries
  446. );
  447. BAIL_ON_FAILURE(hr);
  448. if (dwNumEntries != 1) {
  449. BAIL_ON_FAILURE(hr = E_ADS_BAD_PATHNAME);
  450. }
  451. pszObjectClassName = (pAttrEntries[0].lpValue) ?
  452. pAttrEntries[0].lpValue[0].NdsValue.value_20.ClassName :
  453. NULL;
  454. if (!pszObjectClassName) {
  455. BAIL_ON_FAILURE(E_FAIL);
  456. }
  457. if (_wcsicmp(pszObjectClassName, bstrClassName)) {
  458. hr = E_ADS_BAD_PARAMETER;
  459. BAIL_ON_FAILURE(hr);
  460. }
  461. hr = ADsNdsRemoveObject(
  462. _hADsContext,
  463. pszChildNDSDn
  464. );
  465. BAIL_ON_FAILURE(hr);
  466. error:
  467. if (bstrChildPath) {
  468. SysFreeString(bstrChildPath);
  469. }
  470. if (pszNDSTreeName) {
  471. FreeADsStr(pszNDSTreeName);
  472. }
  473. if (pszChildNDSDn) {
  474. FreeADsStr(pszChildNDSDn);
  475. }
  476. if (pAttrEntries) {
  477. FreeNdsAttrInfo(pAttrEntries, dwNumEntries);
  478. }
  479. RRETURN(hr);
  480. }
  481. STDMETHODIMP
  482. CNDSTree::CopyHere(
  483. THIS_ BSTR SourceName,
  484. BSTR NewName,
  485. IDispatch * FAR* ppObject
  486. )
  487. {
  488. RRETURN(E_NOTIMPL);
  489. }
  490. STDMETHODIMP
  491. CNDSTree::MoveHere(
  492. THIS_ BSTR SourceName,
  493. BSTR NewName,
  494. IDispatch * FAR* ppObject
  495. )
  496. {
  497. RRETURN(E_NOTIMPL);
  498. }
  499. HRESULT
  500. CNDSTree::AllocateTree(
  501. CCredentials& Credentials,
  502. CNDSTree ** ppTree
  503. )
  504. {
  505. CNDSTree FAR * pTree = NULL;
  506. CDispatchMgr FAR * pDispMgr = NULL;
  507. CPropertyCache FAR * pPropertyCache = NULL;
  508. HRESULT hr = S_OK;
  509. pTree = new CNDSTree();
  510. if (pTree == NULL) {
  511. hr = E_OUTOFMEMORY;
  512. }
  513. BAIL_ON_FAILURE(hr);
  514. pDispMgr = new CDispatchMgr;
  515. if (pDispMgr == NULL) {
  516. hr = E_OUTOFMEMORY;
  517. }
  518. BAIL_ON_FAILURE(hr);
  519. hr = LoadTypeInfoEntry(pDispMgr,
  520. LIBID_ADs,
  521. IID_IADs,
  522. (IADs *)pTree,
  523. DISPID_REGULAR
  524. );
  525. BAIL_ON_FAILURE(hr);
  526. hr = LoadTypeInfoEntry(pDispMgr,
  527. LIBID_ADs,
  528. IID_IADsContainer,
  529. (IADsContainer *)pTree,
  530. DISPID_NEWENUM
  531. );
  532. BAIL_ON_FAILURE(hr);
  533. hr = CPropertyCache::createpropertycache(
  534. (CCoreADsObject FAR *)pTree,
  535. &pPropertyCache
  536. );
  537. BAIL_ON_FAILURE(hr);
  538. pTree->_Credentials = Credentials;
  539. pTree->_pPropertyCache = pPropertyCache;
  540. pTree->_pDispMgr = pDispMgr;
  541. *ppTree = pTree;
  542. RRETURN(hr);
  543. error:
  544. delete pDispMgr;
  545. RRETURN(hr);
  546. }
  547. STDMETHODIMP
  548. CNDSTree::Get(
  549. THIS_ BSTR bstrName,
  550. VARIANT FAR* pvProp
  551. )
  552. {
  553. HRESULT hr = S_OK;
  554. DWORD dwSyntaxId;
  555. DWORD dwNumValues;
  556. LPNDSOBJECT pNdsSrcObjects = NULL;
  557. //
  558. // retrieve data object from cache; if one exists
  559. //
  560. hr = _pPropertyCache->getproperty(
  561. bstrName,
  562. &dwSyntaxId,
  563. &dwNumValues,
  564. &pNdsSrcObjects
  565. );
  566. BAIL_ON_FAILURE(hr);
  567. //
  568. // translate the Nds objects to variants
  569. //
  570. hr = NdsTypeToVarTypeCopyConstruct(
  571. pNdsSrcObjects,
  572. dwNumValues,
  573. pvProp,
  574. FALSE
  575. );
  576. BAIL_ON_FAILURE(hr);
  577. error:
  578. if (pNdsSrcObjects) {
  579. NdsTypeFreeNdsObjects(
  580. pNdsSrcObjects,
  581. dwNumValues
  582. );
  583. }
  584. RRETURN(hr);
  585. }
  586. STDMETHODIMP
  587. CNDSTree::GetEx(
  588. THIS_ BSTR bstrName,
  589. VARIANT FAR* pvProp
  590. )
  591. {
  592. HRESULT hr = S_OK;
  593. DWORD dwSyntaxId;
  594. DWORD dwNumValues;
  595. LPNDSOBJECT pNdsSrcObjects = NULL;
  596. //
  597. // retrieve data object from cache; if one exists
  598. //
  599. hr = _pPropertyCache->getproperty(
  600. bstrName,
  601. &dwSyntaxId,
  602. &dwNumValues,
  603. &pNdsSrcObjects
  604. );
  605. BAIL_ON_FAILURE(hr);
  606. //
  607. // translate the Nds objects to variants
  608. //
  609. hr = NdsTypeToVarTypeCopyConstruct(
  610. pNdsSrcObjects,
  611. dwNumValues,
  612. pvProp,
  613. TRUE
  614. );
  615. BAIL_ON_FAILURE(hr);
  616. error:
  617. if (pNdsSrcObjects) {
  618. NdsTypeFreeNdsObjects(
  619. pNdsSrcObjects,
  620. dwNumValues
  621. );
  622. }
  623. RRETURN(hr);
  624. }
  625. STDMETHODIMP
  626. CNDSTree::Put(
  627. THIS_ BSTR bstrName,
  628. VARIANT vProp
  629. )
  630. {
  631. HRESULT hr = S_OK;
  632. DWORD dwSyntaxId = 0;
  633. DWORD dwIndex = 0;
  634. LPNDSOBJECT pNdsDestObjects = NULL;
  635. WCHAR szNDSTreeName[MAX_PATH];
  636. //
  637. // Issue: How do we handle multi-valued support
  638. //
  639. DWORD dwNumValues = 1;
  640. //
  641. // Get the TreeName for this object
  642. //
  643. hr = BuildNDSTreeNameFromADsPath(
  644. _ADsPath,
  645. szNDSTreeName
  646. );
  647. BAIL_ON_FAILURE(hr);
  648. //
  649. // check if this is a legal property for this object,
  650. //
  651. hr = ValidatePropertyinCache(
  652. szNDSTreeName,
  653. _ADsClass,
  654. bstrName,
  655. _Credentials,
  656. &dwSyntaxId
  657. );
  658. BAIL_ON_FAILURE(hr);
  659. //
  660. // check if the variant maps to the syntax of this property
  661. //
  662. hr = VarTypeToNdsTypeCopyConstruct(
  663. dwSyntaxId,
  664. &vProp,
  665. &dwNumValues,
  666. &pNdsDestObjects
  667. );
  668. BAIL_ON_FAILURE(hr);
  669. //
  670. // Find this property in the cache
  671. //
  672. hr = _pPropertyCache->findproperty(
  673. bstrName,
  674. &dwIndex
  675. );
  676. //
  677. // If this property does not exist in the
  678. // cache, add this property into the cache.
  679. //
  680. if (FAILED(hr)) {
  681. hr = _pPropertyCache->addproperty(
  682. bstrName,
  683. dwSyntaxId,
  684. dwNumValues,
  685. pNdsDestObjects
  686. );
  687. //
  688. // If the operation fails for some reason
  689. // move on to the next property
  690. //
  691. BAIL_ON_FAILURE(hr);
  692. }
  693. //
  694. // Now update the property in the cache
  695. //
  696. hr = _pPropertyCache->putproperty(
  697. bstrName,
  698. CACHE_PROPERTY_MODIFIED,
  699. dwSyntaxId,
  700. dwNumValues,
  701. pNdsDestObjects
  702. );
  703. BAIL_ON_FAILURE(hr);
  704. error:
  705. if (pNdsDestObjects) {
  706. NdsTypeFreeNdsObjects(
  707. pNdsDestObjects,
  708. dwNumValues
  709. );
  710. }
  711. RRETURN(hr);
  712. }
  713. STDMETHODIMP
  714. CNDSTree::PutEx(
  715. THIS_ long lnControlCode,
  716. BSTR bstrName,
  717. VARIANT vProp
  718. )
  719. {
  720. HRESULT hr = S_OK;
  721. DWORD dwSyntaxId = 0;
  722. DWORD dwIndex = 0;
  723. LPNDSOBJECT pNdsDestObjects = NULL;
  724. WCHAR szNDSTreeName[MAX_PATH];
  725. //
  726. // Issue: How do we handle multi-valued support
  727. //
  728. DWORD dwNumValues = 1;
  729. //
  730. // Get the TreeName for this object
  731. //
  732. hr = BuildNDSTreeNameFromADsPath(
  733. _ADsPath,
  734. szNDSTreeName
  735. );
  736. BAIL_ON_FAILURE(hr);
  737. //
  738. // check if this is a legal property for this object,
  739. //
  740. hr = ValidatePropertyinCache(
  741. szNDSTreeName,
  742. _ADsClass,
  743. bstrName,
  744. _Credentials,
  745. &dwSyntaxId
  746. );
  747. BAIL_ON_FAILURE(hr);
  748. //
  749. // check if the variant maps to the syntax of this property
  750. //
  751. hr = VarTypeToNdsTypeCopyConstruct(
  752. dwSyntaxId,
  753. &vProp,
  754. &dwNumValues,
  755. &pNdsDestObjects
  756. );
  757. BAIL_ON_FAILURE(hr);
  758. //
  759. // Find this property in the cache
  760. //
  761. hr = _pPropertyCache->findproperty(
  762. bstrName,
  763. &dwIndex
  764. );
  765. //
  766. // If this property does not exist in the
  767. // cache, add this property into the cache.
  768. //
  769. if (FAILED(hr)) {
  770. hr = _pPropertyCache->addproperty(
  771. bstrName,
  772. dwSyntaxId,
  773. dwNumValues,
  774. pNdsDestObjects
  775. );
  776. //
  777. // If the operation fails for some reason
  778. // move on to the next property
  779. //
  780. BAIL_ON_FAILURE(hr);
  781. }
  782. //
  783. // Now update the property in the cache
  784. //
  785. hr = _pPropertyCache->putproperty(
  786. bstrName,
  787. CACHE_PROPERTY_MODIFIED,
  788. dwSyntaxId,
  789. dwNumValues,
  790. pNdsDestObjects
  791. );
  792. BAIL_ON_FAILURE(hr);
  793. error:
  794. if (pNdsDestObjects) {
  795. NdsTypeFreeNdsObjects(
  796. pNdsDestObjects,
  797. dwNumValues
  798. );
  799. }
  800. RRETURN(hr);
  801. }