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.

1209 lines
24 KiB

  1. //+---------------------------------------------------------------------------;
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: cprops.cxx
  7. //
  8. // Contents: Property Cache functionality for NDS
  9. //
  10. // Functions:
  11. // CPropertyCache::addproperty
  12. // CPropertyCache::updateproperty
  13. // CPropertyCache::findproperty
  14. // CPropertyCache::getproperty
  15. // CPropertyCache::putproperty
  16. // CProperyCache::CPropertyCache
  17. // CPropertyCache::~CPropertyCache
  18. // CPropertyCache::createpropertycache
  19. //
  20. // History: 25-Apr-96 KrishnaG Created.
  21. //
  22. //----------------------------------------------------------------------------
  23. #include "nds.hxx"
  24. #if DBG
  25. DECLARE_INFOLEVEL(NDSMarshall);
  26. DECLARE_DEBUG(NDSMarshall);
  27. #define NDSMarshallDebugOut(x) NDSMarshallInlineDebugOut x
  28. #endif
  29. //+------------------------------------------------------------------------
  30. //
  31. // Function: CPropertyCache::addproperty
  32. //
  33. // Synopsis:
  34. //
  35. //
  36. //
  37. // Arguments: [szPropertyName] --
  38. // [vt] --
  39. // [vaData] --
  40. //
  41. //
  42. //-------------------------------------------------------------------------
  43. HRESULT
  44. CPropertyCache::
  45. addproperty(
  46. LPWSTR szPropertyName,
  47. DWORD dwSyntaxId,
  48. DWORD dwNumValues,
  49. PNDSOBJECT pNdsObject
  50. )
  51. {
  52. HRESULT hr = S_OK;
  53. PPROPERTY pNewProperty = NULL;
  54. LPWSTR tempString = NULL;
  55. PPROPERTY pNewProperties = NULL;
  56. //
  57. // Allocate the string first
  58. //
  59. tempString = AllocADsStr(szPropertyName);
  60. if (!tempString)
  61. BAIL_ON_FAILURE(hr=E_OUTOFMEMORY);
  62. //
  63. // extend the property cache by adding a new property entry
  64. //
  65. pNewProperties = (PPROPERTY)ReallocADsMem(
  66. _pProperties,
  67. _cb,
  68. _cb + sizeof(PROPERTY)
  69. );
  70. if (!pNewProperties) {
  71. hr = E_OUTOFMEMORY;
  72. BAIL_ON_FAILURE(hr);
  73. }
  74. _pProperties = pNewProperties;
  75. pNewProperty = (PPROPERTY)((LPBYTE)_pProperties + _cb);
  76. //
  77. // Since the memory has already been allocated in tempString
  78. // just set the value/pointer now.
  79. //
  80. pNewProperty->szPropertyName = tempString;
  81. //
  82. // BugBug - add in the NDSOBJECT code
  83. //
  84. //
  85. // Update the index
  86. //
  87. _dwMaxProperties++;
  88. _cb += sizeof(PROPERTY);
  89. RRETURN(hr);
  90. error:
  91. if (tempString)
  92. FreeADsStr(tempString);
  93. RRETURN(hr);
  94. }
  95. //+------------------------------------------------------------------------
  96. //
  97. // Function: CPropertyCache::updateproperty
  98. //
  99. // Synopsis:
  100. //
  101. //
  102. //
  103. // Arguments: [szPropertyName] --
  104. // [vaData] --
  105. //
  106. //-------------------------------------------------------------------------
  107. HRESULT
  108. CPropertyCache::
  109. updateproperty(
  110. LPWSTR szPropertyName,
  111. DWORD dwSyntaxId,
  112. DWORD dwNumValues,
  113. PNDSOBJECT pNdsObject,
  114. BOOL fExplicit
  115. )
  116. {
  117. HRESULT hr;
  118. DWORD dwIndex;
  119. PNDSOBJECT pNdsTempObject = NULL;
  120. PPROPERTY pThisProperty = NULL;
  121. hr = findproperty(
  122. szPropertyName,
  123. &dwIndex
  124. );
  125. BAIL_ON_FAILURE(hr);
  126. pThisProperty = _pProperties + dwIndex;
  127. if (!fExplicit) {
  128. if ((PROPERTY_FLAGS(pThisProperty) == CACHE_PROPERTY_MODIFIED) ||
  129. (PROPERTY_FLAGS(pThisProperty) == CACHE_PROPERTY_CLEARED)) {
  130. hr = S_OK;
  131. goto error;
  132. }
  133. }
  134. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  135. NdsTypeFreeNdsObjects(
  136. PROPERTY_NDSOBJECT(pThisProperty),
  137. PROPERTY_NUMVALUES(pThisProperty)
  138. );
  139. PROPERTY_NDSOBJECT(pThisProperty) = NULL;
  140. }
  141. PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
  142. PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;
  143. hr = NdsTypeCopyConstruct(
  144. pNdsObject,
  145. dwNumValues,
  146. &pNdsTempObject
  147. );
  148. BAIL_ON_FAILURE(hr);
  149. PROPERTY_NDSOBJECT(pThisProperty) = pNdsTempObject;
  150. PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_INITIALIZED;
  151. error:
  152. RRETURN(hr);
  153. }
  154. //+------------------------------------------------------------------------
  155. //
  156. // Function: CPropertyCache::findproperty
  157. //
  158. // Synopsis:
  159. //
  160. //
  161. //
  162. // Arguments: [szPropertyName] --
  163. // [pdwIndex] --
  164. //
  165. //-------------------------------------------------------------------------
  166. HRESULT
  167. CPropertyCache::
  168. findproperty(
  169. LPWSTR szPropertyName,
  170. PDWORD pdwIndex
  171. )
  172. {
  173. DWORD i = 0;
  174. PPROPERTY pThisProperty = NULL;
  175. for (i = 0; i < _dwMaxProperties; i++) {
  176. pThisProperty = _pProperties + i;
  177. if (!_wcsicmp(pThisProperty->szPropertyName, szPropertyName)) {
  178. *pdwIndex = i;
  179. RRETURN(S_OK);
  180. }
  181. }
  182. *pdwIndex = 0;
  183. RRETURN(E_ADS_PROPERTY_NOT_FOUND);
  184. }
  185. //+------------------------------------------------------------------------
  186. //
  187. // Function: CPropertyCache::getproperty
  188. //
  189. // Synopsis:
  190. //
  191. //
  192. //
  193. // Arguments: [szPropertyName] -- Property to retrieve from the cache
  194. // [pvaData] -- Data returned in a variant
  195. //
  196. //-------------------------------------------------------------------------
  197. HRESULT
  198. CPropertyCache::
  199. getproperty(
  200. LPWSTR szPropertyName,
  201. PDWORD pdwSyntaxId,
  202. PDWORD pdwNumValues,
  203. PNDSOBJECT * ppNdsObject
  204. )
  205. {
  206. HRESULT hr;
  207. DWORD dwIndex = 0L;
  208. PPROPERTY pThisProperty = NULL;
  209. hr = findproperty(
  210. szPropertyName,
  211. &dwIndex
  212. );
  213. if (hr == E_ADS_PROPERTY_NOT_FOUND) {
  214. //
  215. // Now call the GetInfo function
  216. //
  217. hr = _pCoreADsObject->GetInfo(
  218. FALSE
  219. );
  220. BAIL_ON_FAILURE(hr);
  221. hr = findproperty(
  222. szPropertyName,
  223. &dwIndex
  224. );
  225. }
  226. BAIL_ON_FAILURE(hr);
  227. pThisProperty = _pProperties + dwIndex;
  228. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  229. *pdwSyntaxId = (DWORD)PROPERTY_SYNTAX(pThisProperty);
  230. *pdwNumValues = (DWORD)PROPERTY_NUMVALUES(pThisProperty);
  231. hr = NdsTypeCopyConstruct(
  232. PROPERTY_NDSOBJECT(pThisProperty),
  233. PROPERTY_NUMVALUES(pThisProperty),
  234. ppNdsObject
  235. );
  236. BAIL_ON_FAILURE(hr);
  237. }else {
  238. *ppNdsObject = NULL;
  239. *pdwNumValues = 0;
  240. *pdwSyntaxId = 0;
  241. hr = E_FAIL;
  242. }
  243. error:
  244. RRETURN(hr);
  245. }
  246. //+------------------------------------------------------------------------
  247. //
  248. // Function: CPropertyCache::putproperty
  249. //
  250. // Synopsis:
  251. //
  252. //
  253. //
  254. // Arguments: [szPropertyName] -- Clsid index
  255. // [vaData] -- Matching clsid returned in *pclsid
  256. //
  257. //-------------------------------------------------------------------------
  258. HRESULT
  259. CPropertyCache::
  260. putproperty(
  261. LPWSTR szPropertyName,
  262. DWORD dwFlags,
  263. DWORD dwSyntaxId,
  264. DWORD dwNumValues,
  265. PNDSOBJECT pNdsObject
  266. )
  267. {
  268. HRESULT hr;
  269. DWORD dwIndex = 0L;
  270. PNDSOBJECT pNdsTempObject = NULL;
  271. PPROPERTY pThisProperty = NULL;
  272. hr = findproperty(
  273. szPropertyName,
  274. &dwIndex
  275. );
  276. BAIL_ON_FAILURE(hr);
  277. pThisProperty = _pProperties + dwIndex;
  278. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  279. NdsTypeFreeNdsObjects(
  280. PROPERTY_NDSOBJECT(pThisProperty),
  281. PROPERTY_NUMVALUES(pThisProperty)
  282. );
  283. PROPERTY_NDSOBJECT(pThisProperty) = NULL;
  284. }
  285. switch (dwFlags) {
  286. case CACHE_PROPERTY_MODIFIED:
  287. PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
  288. PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;
  289. hr = NdsTypeCopyConstruct(
  290. pNdsObject,
  291. dwNumValues,
  292. &pNdsTempObject
  293. );
  294. BAIL_ON_FAILURE(hr);
  295. PROPERTY_NDSOBJECT(pThisProperty) = pNdsTempObject;
  296. PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_MODIFIED;
  297. break;
  298. case CACHE_PROPERTY_CLEARED:
  299. PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
  300. PROPERTY_NUMVALUES(pThisProperty) = 0;
  301. PROPERTY_NDSOBJECT(pThisProperty) = NULL;
  302. PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_CLEARED;
  303. break;
  304. case CACHE_PROPERTY_APPENDED:
  305. PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
  306. PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;
  307. hr = NdsTypeCopyConstruct(
  308. pNdsObject,
  309. dwNumValues,
  310. &pNdsTempObject
  311. );
  312. BAIL_ON_FAILURE(hr);
  313. PROPERTY_NDSOBJECT(pThisProperty) = pNdsTempObject;
  314. PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_APPENDED;
  315. break;
  316. case CACHE_PROPERTY_DELETED:
  317. PROPERTY_SYNTAX(pThisProperty) = dwSyntaxId;
  318. PROPERTY_NUMVALUES(pThisProperty) = dwNumValues;
  319. hr = NdsTypeCopyConstruct(
  320. pNdsObject,
  321. dwNumValues,
  322. &pNdsTempObject
  323. );
  324. BAIL_ON_FAILURE(hr);
  325. PROPERTY_NDSOBJECT(pThisProperty) = pNdsTempObject;
  326. PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_DELETED;
  327. break;
  328. }
  329. error:
  330. RRETURN(hr);
  331. }
  332. //+------------------------------------------------------------------------
  333. //
  334. // Function: CPropertyCache
  335. //
  336. // Synopsis:
  337. //
  338. //
  339. //
  340. // Arguments:
  341. //
  342. //
  343. //-------------------------------------------------------------------------
  344. CPropertyCache::
  345. CPropertyCache():
  346. _dwMaxProperties(0),
  347. _dwCurrentIndex(0),
  348. _pProperties(NULL),
  349. _cb(0),
  350. _pCoreADsObject(NULL)
  351. {
  352. }
  353. //+------------------------------------------------------------------------
  354. //
  355. // Function: ~CPropertyCache
  356. //
  357. // Synopsis:
  358. //
  359. //
  360. //
  361. // Arguments:
  362. //
  363. //
  364. //-------------------------------------------------------------------------
  365. CPropertyCache::
  366. ~CPropertyCache()
  367. {
  368. DWORD i = 0;
  369. PPROPERTY pThisProperty = NULL;
  370. if (_pProperties) {
  371. for (i = 0; i < _dwMaxProperties; i++) {
  372. pThisProperty = _pProperties + i;
  373. if (pThisProperty->szPropertyName){
  374. FreeADsStr(pThisProperty->szPropertyName);
  375. pThisProperty->szPropertyName = NULL;
  376. }
  377. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  378. NdsTypeFreeNdsObjects(
  379. PROPERTY_NDSOBJECT(pThisProperty),
  380. PROPERTY_NUMVALUES(pThisProperty)
  381. );
  382. PROPERTY_NDSOBJECT(pThisProperty) = NULL;
  383. }
  384. }
  385. FreeADsMem(_pProperties);
  386. }
  387. }
  388. //+------------------------------------------------------------------------
  389. //
  390. // Function:
  391. //
  392. // Synopsis:
  393. //
  394. //
  395. //
  396. // Arguments:
  397. //
  398. //
  399. //-------------------------------------------------------------------------
  400. HRESULT
  401. CPropertyCache::
  402. createpropertycache(
  403. CCoreADsObject FAR * pCoreADsObject,
  404. CPropertyCache FAR *FAR * ppPropertyCache
  405. )
  406. {
  407. CPropertyCache FAR * pPropertyCache = NULL;
  408. pPropertyCache = new CPropertyCache();
  409. if (!pPropertyCache) {
  410. RRETURN(E_FAIL);
  411. }
  412. pPropertyCache->_pCoreADsObject = pCoreADsObject;
  413. *ppPropertyCache = pPropertyCache;
  414. RRETURN(S_OK);
  415. }
  416. //+------------------------------------------------------------------------
  417. //
  418. // Function:
  419. //
  420. // Synopsis:
  421. //
  422. //
  423. //
  424. // Arguments:
  425. //
  426. //
  427. //-------------------------------------------------------------------------
  428. HRESULT
  429. CPropertyCache::
  430. unmarshallproperty(
  431. LPWSTR szPropertyName,
  432. PNDSOBJECT pNdsObject,
  433. DWORD dwNumValues,
  434. DWORD dwSyntaxId,
  435. BOOL fExplicit
  436. )
  437. {
  438. DWORD dwIndex = 0;
  439. HRESULT hr = S_OK;
  440. //
  441. // Find this property in the cache
  442. //
  443. hr = findproperty(
  444. szPropertyName,
  445. &dwIndex
  446. );
  447. //
  448. // If this property does not exist in the
  449. // cache, add this property into the cache.
  450. //
  451. if (FAILED(hr)) {
  452. hr = addproperty(
  453. szPropertyName,
  454. dwSyntaxId,
  455. dwNumValues,
  456. pNdsObject
  457. );
  458. //
  459. // If the operation fails for some reason
  460. // move on to the next property
  461. //
  462. BAIL_ON_FAILURE(hr);
  463. }
  464. //
  465. // Now update the property in the cache
  466. //
  467. hr = updateproperty(
  468. szPropertyName,
  469. dwSyntaxId,
  470. dwNumValues,
  471. pNdsObject,
  472. fExplicit
  473. );
  474. BAIL_ON_FAILURE(hr);
  475. error:
  476. RRETURN(hr);
  477. }
  478. HRESULT
  479. CPropertyCache::
  480. NDSUnMarshallProperties(
  481. HANDLE hOperationData,
  482. BOOL fExplicit
  483. )
  484. {
  485. DWORD dwNumberOfEntries = 0L;
  486. LPNDS_ATTR_INFO lpEntries = NULL;
  487. HRESULT hr = S_OK;
  488. DWORD i = 0;
  489. DWORD dwStatus = 0L;
  490. //
  491. // Compute the number of attributes in the
  492. // read buffer.
  493. //
  494. // dwStatus = NwNdsGetAttrListFromBuffer(
  495. // hOperationData,
  496. // &dwNumberOfEntries,
  497. // &lpEntries
  498. // );
  499. //
  500. CHECK_AND_SET_EXTENDED_ERROR(dwStatus, hr);
  501. for (i = 0; i < dwNumberOfEntries; i++) {
  502. //
  503. // unmarshall this property into the
  504. // property cache
  505. //
  506. hr = unmarshallproperty(
  507. lpEntries[i].szAttributeName,
  508. lpEntries[i].lpValue,
  509. lpEntries[i].dwNumberOfValues,
  510. lpEntries[i].dwSyntaxId,
  511. fExplicit
  512. );
  513. CONTINUE_ON_FAILURE(hr);
  514. }
  515. error:
  516. RRETURN(hr);
  517. }
  518. HRESULT
  519. CPropertyCache::
  520. marshallproperty(
  521. NDS_CONTEXT_HANDLE hADsContext,
  522. NDS_BUFFER_HANDLE hOperationData,
  523. LPWSTR szPropertyName,
  524. DWORD dwFlags,
  525. PNDSOBJECT lpValues,
  526. DWORD dwNumValues,
  527. DWORD dwSyntaxId
  528. )
  529. {
  530. HRESULT hr = S_OK;
  531. switch (dwFlags) {
  532. case CACHE_PROPERTY_MODIFIED:
  533. hr = ADsNdsPutInBuffer(
  534. hADsContext,
  535. hOperationData,
  536. szPropertyName,
  537. dwSyntaxId,
  538. NULL,
  539. 0,
  540. DS_CLEAR_ATTRIBUTE
  541. );
  542. BAIL_ON_FAILURE(hr);
  543. hr = ADsNdsPutInBuffer(
  544. hADsContext,
  545. hOperationData,
  546. szPropertyName,
  547. dwSyntaxId,
  548. lpValues,
  549. dwNumValues,
  550. DS_ADD_ATTRIBUTE
  551. );
  552. BAIL_ON_FAILURE(hr);
  553. break;
  554. case CACHE_PROPERTY_CLEARED:
  555. hr = ADsNdsPutInBuffer(
  556. hADsContext,
  557. hOperationData,
  558. szPropertyName,
  559. dwSyntaxId,
  560. NULL,
  561. 0,
  562. DS_CLEAR_ATTRIBUTE
  563. );
  564. BAIL_ON_FAILURE(hr);
  565. break;
  566. case CACHE_PROPERTY_APPENDED:
  567. hr = ADsNdsPutInBuffer(
  568. hADsContext,
  569. hOperationData,
  570. szPropertyName,
  571. dwSyntaxId,
  572. lpValues,
  573. dwNumValues,
  574. DS_ADD_VALUE
  575. );
  576. BAIL_ON_FAILURE(hr);
  577. break;
  578. case CACHE_PROPERTY_DELETED:
  579. hr = ADsNdsPutInBuffer(
  580. hADsContext,
  581. hOperationData,
  582. szPropertyName,
  583. dwSyntaxId,
  584. lpValues,
  585. dwNumValues,
  586. DS_REMOVE_VALUE
  587. );
  588. BAIL_ON_FAILURE(hr);
  589. break;
  590. default:
  591. break;
  592. }
  593. #if DBG
  594. NDSMarshallDebugOut((
  595. DEB_TRACE,
  596. "dwSyntaxId: %ld \n", dwSyntaxId
  597. ));
  598. #endif
  599. error:
  600. RRETURN(hr);
  601. }
  602. HRESULT
  603. CPropertyCache::
  604. NDSMarshallProperties(
  605. NDS_CONTEXT_HANDLE hADsContext,
  606. NDS_BUFFER_HANDLE hOperationData
  607. )
  608. {
  609. HRESULT hr = S_OK;
  610. DWORD i = 0;
  611. PPROPERTY pThisProperty = NULL;
  612. BYTE lpBuffer[2048];
  613. for (i = 0; i < _dwMaxProperties ; i++) {
  614. pThisProperty = _pProperties + i;
  615. //
  616. // Bypass any property that has not been
  617. // modified
  618. //
  619. if (PROPERTY_FLAGS(pThisProperty) == 0) {
  620. continue;
  621. }
  622. hr = marshallproperty(
  623. hADsContext,
  624. hOperationData,
  625. PROPERTY_NAME(pThisProperty),
  626. PROPERTY_FLAGS(pThisProperty),
  627. PROPERTY_NDSOBJECT(pThisProperty),
  628. PROPERTY_NUMVALUES(pThisProperty),
  629. PROPERTY_SYNTAX(pThisProperty)
  630. );
  631. CONTINUE_ON_FAILURE(hr);
  632. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  633. NdsTypeFreeNdsObjects(
  634. PROPERTY_NDSOBJECT(pThisProperty),
  635. PROPERTY_NUMVALUES(pThisProperty)
  636. );
  637. PROPERTY_NDSOBJECT(pThisProperty) = NULL;
  638. }
  639. wcscpy(pThisProperty->szPropertyName, TEXT(""));
  640. PROPERTY_SYNTAX(pThisProperty) = 0;
  641. PROPERTY_NUMVALUES(pThisProperty) = 0;
  642. PROPERTY_FLAGS(pThisProperty) = CACHE_PROPERTY_INITIALIZED;
  643. }
  644. RRETURN(hr);
  645. }
  646. //+------------------------------------------------------------------------
  647. //
  648. // Function: CPropertyCache::getproperty
  649. //
  650. // Synopsis:
  651. //
  652. //
  653. //
  654. // Arguments: [szPropertyName] -- Property to retrieve from the cache
  655. // [pvaData] -- Data returned in a variant
  656. //
  657. //-------------------------------------------------------------------------
  658. HRESULT
  659. CPropertyCache::
  660. unboundgetproperty(
  661. LPWSTR szPropertyName,
  662. PDWORD pdwSyntaxId,
  663. PDWORD pdwNumValues,
  664. PNDSOBJECT * ppNdsObject
  665. )
  666. {
  667. HRESULT hr;
  668. DWORD dwIndex = 0L;
  669. PPROPERTY pThisProperty = NULL;
  670. hr = findproperty(
  671. szPropertyName,
  672. &dwIndex
  673. );
  674. BAIL_ON_FAILURE(hr);
  675. pThisProperty = _pProperties + dwIndex;
  676. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  677. *pdwSyntaxId = (DWORD)PROPERTY_SYNTAX(pThisProperty);
  678. *pdwNumValues = (DWORD)PROPERTY_NUMVALUES(pThisProperty);
  679. hr = NdsTypeCopyConstruct(
  680. PROPERTY_NDSOBJECT(pThisProperty),
  681. PROPERTY_NUMVALUES(pThisProperty),
  682. ppNdsObject
  683. );
  684. BAIL_ON_FAILURE(hr);
  685. }else {
  686. *ppNdsObject = NULL;
  687. *pdwNumValues = 0;
  688. *pdwSyntaxId = 0;
  689. hr = E_FAIL;
  690. }
  691. error:
  692. RRETURN(hr);
  693. }
  694. //+------------------------------------------------------------------------
  695. //
  696. // Function: ~CPropertyCache
  697. //
  698. // Synopsis:
  699. //
  700. //
  701. //
  702. // Arguments:
  703. //
  704. //
  705. //-------------------------------------------------------------------------
  706. void
  707. CPropertyCache::
  708. flushpropcache()
  709. {
  710. DWORD i = 0;
  711. PPROPERTY pThisProperty = NULL;
  712. if (_pProperties) {
  713. for (i = 0; i < _dwMaxProperties; i++) {
  714. pThisProperty = _pProperties + i;
  715. if (pThisProperty->szPropertyName) {
  716. FreeADsStr(pThisProperty->szPropertyName);
  717. pThisProperty->szPropertyName = NULL;
  718. }
  719. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  720. NdsTypeFreeNdsObjects(
  721. PROPERTY_NDSOBJECT(pThisProperty),
  722. PROPERTY_NUMVALUES(pThisProperty)
  723. );
  724. PROPERTY_NDSOBJECT(pThisProperty) = NULL;
  725. }
  726. }
  727. FreeADsMem(_pProperties);
  728. }
  729. //
  730. // Reset the property cache
  731. //
  732. _pProperties = NULL;
  733. _dwMaxProperties = 0;
  734. _cb = 0;
  735. _dwCurrentIndex = 0;
  736. }
  737. //+------------------------------------------------------------------------
  738. //
  739. // Function: CPropertyCache::getproperty
  740. //
  741. // Synopsis:
  742. //
  743. //
  744. //
  745. // Arguments: [szPropertyName] -- Property to retrieve from the cache
  746. // [pvaData] -- Data returned in a variant
  747. //
  748. //-------------------------------------------------------------------------
  749. HRESULT
  750. CPropertyCache::
  751. unboundgetproperty(
  752. DWORD dwIndex,
  753. PDWORD pdwSyntaxId,
  754. PDWORD pdwNumValues,
  755. PNDSOBJECT * ppNdsObject
  756. )
  757. {
  758. HRESULT hr;
  759. PPROPERTY pThisProperty = NULL;
  760. if (!_pProperties) {
  761. RRETURN(E_FAIL);
  762. }
  763. if (dwIndex < 0 || dwIndex > (_dwMaxProperties - 1) )
  764. RRETURN(E_FAIL);
  765. pThisProperty = _pProperties + dwIndex;
  766. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  767. *pdwSyntaxId = (DWORD)PROPERTY_SYNTAX(pThisProperty);
  768. *pdwNumValues = (DWORD)PROPERTY_NUMVALUES(pThisProperty);
  769. hr = NdsTypeCopyConstruct(
  770. PROPERTY_NDSOBJECT(pThisProperty),
  771. PROPERTY_NUMVALUES(pThisProperty),
  772. ppNdsObject
  773. );
  774. BAIL_ON_FAILURE(hr);
  775. }else {
  776. *ppNdsObject = NULL;
  777. *pdwNumValues = 0;
  778. *pdwSyntaxId = 0;
  779. hr = E_FAIL;
  780. }
  781. error:
  782. RRETURN(hr);
  783. }
  784. BOOL
  785. CPropertyCache::
  786. index_valid(
  787. )
  788. {
  789. if (_dwCurrentIndex < 0 || _dwCurrentIndex > _dwMaxProperties - 1)
  790. return(FALSE);
  791. else
  792. return(TRUE);
  793. }
  794. BOOL
  795. CPropertyCache::
  796. index_valid(
  797. DWORD dwIndex
  798. )
  799. {
  800. if (dwIndex < 0 || dwIndex > _dwMaxProperties - 1)
  801. return(FALSE);
  802. else
  803. return(TRUE);
  804. }
  805. void
  806. CPropertyCache::
  807. reset_propindex(
  808. )
  809. {
  810. _dwCurrentIndex = 0;
  811. }
  812. HRESULT
  813. CPropertyCache::
  814. skip_propindex(
  815. DWORD dwElements
  816. )
  817. {
  818. DWORD newIndex = _dwCurrentIndex + dwElements;
  819. if (!index_valid() || !_dwMaxProperties)
  820. RRETURN(E_FAIL);
  821. //
  822. // BugBug it will be better to return IndexOutOfRange or something like that
  823. //
  824. if (_dwCurrentIndex < 0 || _dwCurrentIndex > _dwMaxProperties-1)
  825. RRETURN(E_FAIL);
  826. if ( newIndex < 0 || newIndex > _dwMaxProperties )
  827. RRETURN(E_FAIL);
  828. _dwCurrentIndex = newIndex;
  829. RRETURN(S_OK);
  830. }
  831. HRESULT
  832. CPropertyCache::
  833. get_PropertyCount(
  834. PDWORD pdwMaxProperties
  835. )
  836. {
  837. *pdwMaxProperties = _dwMaxProperties;
  838. RRETURN(S_OK);
  839. }
  840. DWORD
  841. CPropertyCache::
  842. get_CurrentIndex(
  843. )
  844. {
  845. return(_dwCurrentIndex);
  846. }
  847. LPWSTR
  848. CPropertyCache::
  849. get_CurrentPropName(
  850. )
  851. {
  852. PPROPERTY pThisProperty = NULL;
  853. if (!index_valid())
  854. return(PROPERTY_NAME(pThisProperty));
  855. pThisProperty = _pProperties + _dwCurrentIndex;
  856. return(PROPERTY_NAME(pThisProperty));
  857. }
  858. LPWSTR
  859. CPropertyCache::
  860. get_PropName(
  861. DWORD dwIndex
  862. )
  863. {
  864. PPROPERTY pThisProperty = NULL;
  865. if (!index_valid(dwIndex))
  866. return(NULL);
  867. pThisProperty = _pProperties + dwIndex;
  868. return(PROPERTY_NAME(pThisProperty));
  869. }
  870. HRESULT
  871. CPropertyCache::
  872. deleteproperty(
  873. DWORD dwIndex
  874. )
  875. {
  876. HRESULT hr = S_OK;
  877. PPROPERTY pNewProperties = NULL;
  878. PPROPERTY pThisProperty = _pProperties + dwIndex;
  879. if (!index_valid(dwIndex)) {
  880. hr = E_FAIL;
  881. BAIL_ON_FAILURE(hr);
  882. }
  883. if (_dwMaxProperties == 1) {
  884. //
  885. // Deleting everything
  886. //
  887. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  888. NdsTypeFreeNdsObjects(
  889. PROPERTY_NDSOBJECT(pThisProperty),
  890. PROPERTY_NUMVALUES(pThisProperty)
  891. );
  892. PROPERTY_NDSOBJECT(pThisProperty) = NULL;
  893. }
  894. FreeADsMem(_pProperties);
  895. _pProperties = NULL;
  896. _dwMaxProperties = 0;
  897. _cb = 0;
  898. RRETURN(hr);
  899. }
  900. pNewProperties = (PPROPERTY)AllocADsMem(
  901. _cb - sizeof(PROPERTY)
  902. );
  903. if (!pNewProperties) {
  904. hr = E_OUTOFMEMORY;
  905. BAIL_ON_FAILURE(hr);
  906. }
  907. //
  908. // Copying the memory before the deleted item
  909. //
  910. if (dwIndex != 0) {
  911. memcpy( pNewProperties,
  912. _pProperties,
  913. dwIndex * sizeof(PROPERTY));
  914. }
  915. //
  916. // Copying the memory following the deleted item
  917. //
  918. if (dwIndex != (_dwMaxProperties-1)) {
  919. memcpy( pNewProperties + dwIndex,
  920. _pProperties + dwIndex + 1,
  921. (_dwMaxProperties - dwIndex - 1) * sizeof(PROPERTY));
  922. }
  923. if (PROPERTY_NDSOBJECT(pThisProperty)) {
  924. NdsTypeFreeNdsObjects(
  925. PROPERTY_NDSOBJECT(pThisProperty),
  926. PROPERTY_NUMVALUES(pThisProperty)
  927. );
  928. PROPERTY_NDSOBJECT(pThisProperty) = NULL;
  929. }
  930. FreeADsMem(_pProperties);
  931. _pProperties = pNewProperties;
  932. _dwMaxProperties--;
  933. _cb -= sizeof(PROPERTY);
  934. error:
  935. RRETURN(hr);
  936. }
  937.