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.

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