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.

1711 lines
33 KiB

  1. // prop.cpp : Implementation of CMetaPropertySet
  2. #include "stdafx.h"
  3. #include "Property.h"
  4. #include "util.h"
  5. HRESULT SaveObjectToField(VARIANT var, ADODB::Field *pfield)
  6. {
  7. HRESULT hr;
  8. if ((var.vt != VT_UNKNOWN) && (var.vt != VT_DISPATCH))
  9. return E_INVALIDARG;
  10. CComPtr<IStream> pstream;
  11. hr = CreateStreamOnHGlobal(NULL, TRUE, &pstream);
  12. if (FAILED(hr))
  13. return hr;
  14. CComQIPtr<IPersistStream> ppersiststream(var.punkVal);
  15. if (ppersiststream != NULL)
  16. {
  17. // Write a tag to indicate IPersistStream was used.
  18. char ch = Format_IPersistStream;
  19. ULONG cb = sizeof(ch);
  20. hr = pstream->Write(&ch, cb, &cb);
  21. if (FAILED(hr))
  22. return hr;
  23. hr = OleSaveToStream(ppersiststream, pstream);
  24. if (FAILED(hr))
  25. return hr;
  26. }
  27. else
  28. {
  29. CComQIPtr<IPersistPropertyBag> ppersistpropbag(var.punkVal);
  30. if (ppersistpropbag == NULL)
  31. return E_INVALIDARG;
  32. // Write a tag to indicate IPersistPropertyBag was used.
  33. char ch = Format_IPersistPropertyBag;
  34. ULONG cb = sizeof(ch);
  35. hr = pstream->Write(&ch, cb, &cb);
  36. if (FAILED(hr))
  37. return hr;
  38. hr = SaveToPropBagInStream(ppersistpropbag, pstream);
  39. if (FAILED(hr))
  40. return hr;
  41. }
  42. HANDLE hdata;
  43. hr = GetHGlobalFromStream(pstream, &hdata);
  44. if (FAILED(hr))
  45. return hr;
  46. long cb = GlobalSize(hdata);
  47. SAFEARRAY *parray = SafeArrayCreateVector(VT_UI1, 0, cb);
  48. if (parray == NULL)
  49. return E_OUTOFMEMORY;
  50. BYTE *pbDst;
  51. hr = SafeArrayAccessData(parray, (void **) &pbDst);
  52. if (FAILED(hr))
  53. return hr;
  54. BYTE *pbSrc = (BYTE *) GlobalLock(hdata);
  55. memcpy(pbDst, pbSrc, cb);
  56. GlobalUnlock(hdata);
  57. SafeArrayUnaccessData(parray);
  58. _variant_t varT;
  59. varT.vt = VT_ARRAY | VT_UI1;
  60. varT.parray = parray;
  61. hr = pfield->AppendChunk(varT);
  62. if (FAILED(hr))
  63. return hr;
  64. return S_OK;
  65. }
  66. HRESULT LoadObjectFromField(ADODB::Field *pfield, VARIANT *pvar)
  67. {
  68. HRESULT hr;
  69. long cb;
  70. hr = pfield->get_ActualSize(&cb);
  71. if (FAILED(hr))
  72. return hr;
  73. _variant_t varData;
  74. hr = pfield->GetChunk(cb, &varData);
  75. if (FAILED(hr))
  76. return hr;
  77. if ((varData.vt & VT_ARRAY) == 0)
  78. return E_FAIL;
  79. BYTE *pbSrc;
  80. hr = SafeArrayAccessData(varData.parray, (void **) &pbSrc);
  81. if (FAILED(hr))
  82. return hr;
  83. HANDLE hdata;
  84. BOOL fFree = FALSE;
  85. hdata = GlobalHandle(pbSrc);
  86. if (hdata == NULL)
  87. {
  88. hdata = GlobalAlloc(GHND, cb);
  89. if (hdata == NULL)
  90. {
  91. SafeArrayUnaccessData(varData.parray);
  92. return E_OUTOFMEMORY;
  93. }
  94. BYTE *pbDst = (BYTE *) GlobalLock(hdata);
  95. memcpy(pbDst, pbSrc, cb);
  96. fFree = TRUE;
  97. }
  98. else
  99. {
  100. BYTE *pbTest = (BYTE *) GlobalLock(hdata);
  101. int i = 0;
  102. if (pbTest != pbSrc)
  103. i++;
  104. GlobalUnlock(hdata);
  105. }
  106. CComPtr<IUnknown> punk;
  107. {
  108. CComPtr<IStream> pstream;
  109. hr = CreateStreamOnHGlobal(hdata, fFree, &pstream);
  110. if (FAILED(hr))
  111. {
  112. if (fFree)
  113. GlobalFree(hdata);
  114. return hr;
  115. }
  116. char ch;
  117. ULONG cbT = sizeof(ch);
  118. hr = pstream->Read(&ch, cbT, &cbT);
  119. switch (ch)
  120. {
  121. case Format_IPersistStream:
  122. hr = OleLoadFromStream(pstream, __uuidof(IUnknown), (void **) &punk);
  123. break;
  124. case Format_IPersistPropertyBag:
  125. hr = LoadFromPropBagInStream(pstream, &punk);
  126. break;
  127. default:
  128. return STG_E_DOCFILECORRUPT;
  129. }
  130. }
  131. SafeArrayUnaccessData(varData.parray);
  132. if (FAILED(hr))
  133. return hr;
  134. pvar->vt = VT_UNKNOWN;
  135. pvar->punkVal = punk.Detach();
  136. return S_OK;
  137. }
  138. HRESULT SeekPropsRS(ADODB::_RecordsetPtr prs, boolean fSQLServer,
  139. long idObj, long idPropType, boolean fAnyProvider, long idProvider, long idLang)
  140. {
  141. _ASSERTE(idObj != 0);
  142. HRESULT hr;
  143. if (fAnyProvider && idProvider != NULL)
  144. {
  145. // First try to find the specified provider, only if it is not found
  146. // do we look for any provider.
  147. hr = SeekPropsRS(prs, fSQLServer, idObj, idPropType, FALSE, idProvider, idLang);
  148. if (SUCCEEDED(hr))
  149. return hr;
  150. idProvider = NULL;
  151. }
  152. try
  153. {
  154. TCHAR szFind[32];
  155. DeclarePerfTimerOff(perf, "SeekPropsRS");
  156. #if 1
  157. {
  158. static bool fDump= FALSE;
  159. if (fDump)
  160. {
  161. prs->MoveFirst();
  162. while (!prs->EndOfFile)
  163. {
  164. long idObjCur = prs->Fields->Item["idObj"]->Value;
  165. long idPropTypeCur = prs->Fields->Item["idPropType"]->Value;
  166. TRACE("idObj = %d idPropType = %d\n", idObjCur, idPropTypeCur);
  167. prs->MoveNext();
  168. }
  169. }
  170. }
  171. #endif
  172. PerfTimerReset();
  173. if (fSQLServer)
  174. {
  175. prs->MoveFirst();
  176. wsprintf(szFind, _T("idObj = %d"), idObj);
  177. prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
  178. wsprintf(szFind, _T("idPropType = %d"), idPropType);
  179. prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
  180. }
  181. else
  182. {
  183. // Create elements used in the array
  184. _variant_t varCriteria[4];
  185. varCriteria[0] = idObj;
  186. varCriteria[1] = idPropType;
  187. varCriteria[2] = idProvider;
  188. varCriteria[3] = idLang;
  189. const int nCrit = sizeof varCriteria /
  190. sizeof varCriteria[0];
  191. // Create SafeArray Bounds and initialize the array
  192. SAFEARRAYBOUND rgsabound[1];
  193. rgsabound[0].lLbound = 0;
  194. rgsabound[0].cElements = nCrit;
  195. SAFEARRAY *psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound );
  196. hr = S_OK;
  197. // Set the values for each element of the array
  198. for( long i = 0 ; i < nCrit && SUCCEEDED( hr );i++)
  199. {
  200. hr = SafeArrayPutElement(psa, &i,&varCriteria[i]);
  201. }
  202. // Initialize and fill the SafeArray
  203. VARIANT var;
  204. var.vt = VT_VARIANT | VT_ARRAY;
  205. V_ARRAY(&var) = psa;
  206. hr = prs->Seek(var,
  207. fAnyProvider ? ADODB::adSeekAfterEQ : ADODB::adSeekFirstEQ);
  208. if (FAILED(hr))
  209. return hr;
  210. if (prs->EndOfFile)
  211. return E_INVALIDARG;
  212. if (!fAnyProvider)
  213. return S_OK;
  214. }
  215. while (TRUE)
  216. {
  217. if (prs->EndOfFile)
  218. break;
  219. long idObjCur = prs->Fields->Item["idObj"]->Value;
  220. if (idObjCur != idObj)
  221. break;
  222. long idPropTypeCur = prs->Fields->Item["idPropType"]->Value;
  223. if (idPropTypeCur != idPropType)
  224. break;
  225. long idLang2 = prs->Fields->Item["idLanguage"]->Value;
  226. long idProvider2 = prs->Fields->Item["idProvider"]->Value;
  227. if ((idLang == idLang2) && (fAnyProvider || (idProvider == idProvider2)))
  228. {
  229. PerfTimerDump("Successful seek");
  230. return S_OK;
  231. }
  232. prs->MoveNext();
  233. }
  234. PerfTimerDump("Failed seek");
  235. return E_INVALIDARG;
  236. }
  237. catch (_com_error & e)
  238. {
  239. TCHAR sz[1024];
  240. wsprintf(sz, _T("Error: %s"), e.ErrorMessage());
  241. return e.Error();
  242. }
  243. }
  244. /////////////////////////////////////////////////////////////////////////////
  245. // CMetaPropertySet
  246. HRESULT CMetaPropertySet::Load()
  247. {
  248. HRESULT hr;
  249. ADODB::_RecordsetPtr prs;
  250. hr = m_pdb->get_PropTypesRS(&prs);
  251. if (FAILED(hr))
  252. return hr;
  253. if (!CreatePropTypes())
  254. return E_OUTOFMEMORY;
  255. prs->MoveFirst();
  256. TCHAR szFind[20];
  257. wsprintf(szFind, _T("idPropSet = %d"), m_id);
  258. prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
  259. while (!prs->EndOfFile)
  260. {
  261. CComPtr<CMetaPropertyType> pproptype;
  262. long idPropSet = prs->Fields->Item["idPropSet"]->Value;
  263. if (idPropSet != m_id)
  264. break;
  265. bstr_t bstrName = prs->Fields->Item["Name"]->Value;
  266. long idPropType = prs->Fields->Item["idProp"]->Value;
  267. long id = prs->Fields->Item["id"]->Value;
  268. variant_t varNil;
  269. hr = m_pproptypes->Cache(id, idPropType, bstrName, &pproptype);
  270. prs->MoveNext();
  271. }
  272. return S_OK;
  273. }
  274. STDMETHODIMP CMetaPropertySet::get_Name(BSTR *pbstrName)
  275. {
  276. ENTER_API
  277. {
  278. ValidateOut(pbstrName);
  279. *pbstrName = m_bstrName.copy();
  280. return S_OK;
  281. }
  282. LEAVE_API
  283. }
  284. bool CMetaPropertySet::CreatePropTypes()
  285. {
  286. if (m_pproptypes == NULL)
  287. {
  288. CComPtr<CMetaPropertyTypes> pproptypes = NewComObject(CMetaPropertyTypes);
  289. if (pproptypes == NULL)
  290. return FALSE;
  291. pproptypes->Init(m_pdb, this);
  292. m_pproptypes = pproptypes;
  293. }
  294. return TRUE;
  295. }
  296. STDMETHODIMP CMetaPropertySet::get_MetaPropertyTypes(IMetaPropertyTypes **ppproptypes)
  297. {
  298. ENTER_API
  299. {
  300. ValidateOutPtr<IMetaPropertyTypes>(ppproptypes, NULL);
  301. if (!CreatePropTypes())
  302. return E_OUTOFMEMORY;
  303. (*ppproptypes = m_pproptypes)->AddRef();
  304. return S_OK;
  305. }
  306. LEAVE_API
  307. }
  308. /////////////////////////////////////////////////////////////////////////////
  309. // CMetaPropertySets
  310. HRESULT CMetaPropertySets::Load()
  311. {
  312. HRESULT hr;
  313. ADODB::_RecordsetPtr prs;
  314. hr = m_pdb->get_PropSetsRS(&prs);
  315. if (FAILED(hr))
  316. return hr;
  317. prs->MoveFirst();
  318. while (!prs->EndOfFile)
  319. {
  320. // Read in all the records
  321. CComPtr<CMetaPropertySet> ppropset;
  322. long id = prs->Fields->Item["id"]->Value;
  323. bstr_t bstrName = prs->Fields->Item["Name"]->Value;
  324. hr = Cache(id, bstrName, &ppropset);
  325. if (SUCCEEDED(hr) && ppropset != NULL)
  326. {
  327. ppropset->Load();
  328. }
  329. prs->MoveNext();
  330. }
  331. return S_OK;
  332. }
  333. STDMETHODIMP CMetaPropertySets::get_Count(long *plCount)
  334. {
  335. ENTER_API
  336. {
  337. ValidateOut<long>(plCount);
  338. *plCount = m_map.size();
  339. return S_OK;
  340. }
  341. LEAVE_API
  342. }
  343. STDMETHODIMP CMetaPropertySets::get_Item(VARIANT varIndex, IMetaPropertySet **pppropset)
  344. {
  345. ENTER_API
  346. {
  347. ValidateOutPtr<IMetaPropertySet>(pppropset, NULL);
  348. if (varIndex.vt == VT_BSTR)
  349. return get_ItemWithName(varIndex.bstrVal, pppropset);
  350. _variant_t var(varIndex);
  351. try
  352. {
  353. var.ChangeType(VT_I4);
  354. }
  355. catch (_com_error &)
  356. {
  357. return E_INVALIDARG;
  358. }
  359. long i = var.lVal;
  360. if ((i < 0) || (i >= m_map.size()))
  361. return E_INVALIDARG;
  362. t_map::iterator it = m_map.begin();
  363. while (i--)
  364. it++;
  365. *pppropset = (*it).second;
  366. if (*pppropset != NULL)
  367. (*pppropset)->AddRef();
  368. return S_OK;
  369. }
  370. LEAVE_API
  371. }
  372. STDMETHODIMP CMetaPropertySets::get_ItemWithName(BSTR bstrName, IMetaPropertySet **pppropset)
  373. {
  374. ENTER_API
  375. {
  376. ValidateIn(bstrName);
  377. ValidateOutPtr<IMetaPropertySet>(pppropset, NULL);
  378. t_map::iterator it = m_map.find(bstrName);
  379. if (it == m_map.end())
  380. return E_INVALIDARG;
  381. *pppropset = (*it).second;
  382. (*pppropset)->AddRef();
  383. return S_OK;
  384. }
  385. LEAVE_API
  386. }
  387. STDMETHODIMP CMetaPropertySets::get_Lookup(BSTR bstrName, IMetaPropertyType **ppproptype)
  388. {
  389. ENTER_API
  390. {
  391. HRESULT hr;
  392. ValidateIn(bstrName);
  393. ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
  394. if (bstrName == NULL)
  395. return E_INVALIDARG;
  396. wchar_t *szDot = wcschr(bstrName, L'.');
  397. if (szDot == NULL)
  398. return E_INVALIDARG;
  399. _bstr_t bstrPropTypeName(szDot+1);
  400. _bstr_t bstrPropSetName = SysAllocStringLen(bstrName, szDot - bstrName);
  401. CComPtr<IMetaPropertySet> ppropset;
  402. hr = get_AddNew(bstrPropSetName, &ppropset);
  403. if (FAILED(hr))
  404. return hr;
  405. CComPtr<IMetaPropertyTypes> pproptypes;
  406. hr = ppropset->get_MetaPropertyTypes(&pproptypes);
  407. if (FAILED(hr))
  408. return hr;
  409. CComPtr<IMetaPropertyType> pproptype;
  410. _variant_t varNil;
  411. hr = pproptypes->get_AddNew(0, bstrPropTypeName, &pproptype);
  412. if (FAILED(hr))
  413. return hr;
  414. *ppproptype = pproptype.Detach();
  415. return S_OK;
  416. }
  417. LEAVE_API
  418. }
  419. HRESULT CMetaPropertySets::Cache(long id, BSTR bstrName, CMetaPropertySet **pppropset)
  420. {
  421. CComPtr<CMetaPropertySet> ppropset = NULL;
  422. t_map::iterator it = m_map.find(bstrName);
  423. if (it != m_map.end())
  424. {
  425. ppropset = (*it).second;
  426. }
  427. else
  428. {
  429. ppropset = NewComObject(CMetaPropertySet);
  430. if (ppropset == NULL)
  431. return E_OUTOFMEMORY;
  432. ppropset->Init(m_pdb, id, bstrName);
  433. BSTR bstrNameT = SysAllocString(bstrName);
  434. if (bstrNameT == NULL)
  435. return E_OUTOFMEMORY;
  436. ppropset.CopyTo(&m_map[bstrNameT]);
  437. }
  438. *pppropset = ppropset.Detach();
  439. return S_OK;
  440. }
  441. STDMETHODIMP CMetaPropertySets::get_AddNew(BSTR bstrName, IMetaPropertySet **pppropset)
  442. {
  443. ENTER_API
  444. {
  445. ValidateIn(bstrName);
  446. ValidateOutPtr<IMetaPropertySet>(pppropset, NULL);
  447. HRESULT hr;
  448. hr = get_ItemWithName(bstrName, pppropset);
  449. if (SUCCEEDED(hr))
  450. return hr;
  451. static long idCur = 1;
  452. long id;
  453. if (m_pdb == NULL)
  454. id = idCur++;
  455. else
  456. {
  457. ADODB::_RecordsetPtr prs;
  458. hr = m_pdb->get_PropSetsRS(&prs);
  459. if (FAILED(hr))
  460. return hr;
  461. // Create a new record.
  462. hr = prs->AddNew();
  463. prs->Fields->Item["Name"]->Value = bstrName;
  464. hr = prs->Update();
  465. id = prs->Fields->Item["id"]->Value;
  466. }
  467. CMetaPropertySet *ppropset;
  468. hr = Cache(id, bstrName, &ppropset);
  469. *pppropset = ppropset;
  470. return hr;
  471. }
  472. LEAVE_API
  473. }
  474. /////////////////////////////////////////////////////////////////////////////
  475. // CMetaPropertyType
  476. STDMETHODIMP CMetaPropertyType::get_MetaPropertySet(IMetaPropertySet **pppropset)
  477. {
  478. ENTER_API
  479. {
  480. ValidateOutPtr<IMetaPropertySet>(pppropset, m_ppropset);
  481. (*pppropset)->AddRef();
  482. return S_OK;
  483. }
  484. LEAVE_API
  485. }
  486. STDMETHODIMP CMetaPropertyType::get_ID(long *pid)
  487. {
  488. ENTER_API
  489. {
  490. ValidateOut<long>(pid, m_idPropType);
  491. return S_OK;
  492. }
  493. LEAVE_API
  494. }
  495. STDMETHODIMP CMetaPropertyType::get_Name(BSTR *pbstrName)
  496. {
  497. ENTER_API
  498. {
  499. ValidateOut(pbstrName);
  500. *pbstrName = m_bstrName.copy();
  501. return S_OK;
  502. }
  503. LEAVE_API
  504. }
  505. HRESULT CMetaPropertyType::GetNew(long idProvider, long lang, VARIANT varValue, IMetaProperty **ppprop)
  506. {
  507. ENTER_API
  508. {
  509. ValidateOutPtr<IMetaProperty>(ppprop, NULL);
  510. CComPtr<CMetaProperty> pprop = NewComObject(CMetaProperty);
  511. if (pprop == NULL)
  512. return E_OUTOFMEMORY;
  513. pprop->Init(m_pdb, m_id, idProvider, lang, varValue);
  514. *ppprop = pprop.Detach();
  515. return S_OK;
  516. }
  517. LEAVE_API
  518. }
  519. STDMETHODIMP CMetaPropertyType::get_Cond(BSTR bstrCond, long lang, VARIANT varValue, IMetaPropertyCondition **pppropcond)
  520. {
  521. ENTER_API
  522. {
  523. ValidateIn(bstrCond);
  524. ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
  525. if (bstrCond == NULL)
  526. return E_INVALIDARG;
  527. HRESULT hr;
  528. CComPtr<IMetaProperty> pprop;
  529. hr = get_New(lang, varValue, &pprop);
  530. if (FAILED(hr))
  531. return hr;
  532. return pprop->get_Cond(bstrCond, pppropcond);
  533. }
  534. LEAVE_API
  535. }
  536. /////////////////////////////////////////////////////////////////////////////
  537. // CMetaPropertyTypes
  538. STDMETHODIMP CMetaPropertyTypes::get_Count(long *plCount)
  539. {
  540. ENTER_API
  541. {
  542. ValidateOut<long>(plCount, m_map.size());
  543. return S_OK;
  544. }
  545. LEAVE_API
  546. }
  547. STDMETHODIMP CMetaPropertyTypes::get_Item(VARIANT varIndex, IMetaPropertyType **ppproptype)
  548. {
  549. ENTER_API
  550. {
  551. ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
  552. if (varIndex.vt == VT_BSTR)
  553. return get_ItemWithName(varIndex.bstrVal, ppproptype);
  554. _variant_t var(varIndex);
  555. try
  556. {
  557. var.ChangeType(VT_I4);
  558. }
  559. catch (_com_error &)
  560. {
  561. return E_INVALIDARG;
  562. }
  563. long i = var.lVal;
  564. if ((i < 0) || (i >= m_map.size()))
  565. return E_INVALIDARG;
  566. t_map::iterator it = m_map.begin();
  567. while (i--)
  568. it++;
  569. *ppproptype = (*it).second;
  570. if (*ppproptype != NULL)
  571. (*ppproptype)->AddRef();
  572. return S_OK;
  573. }
  574. LEAVE_API
  575. }
  576. STDMETHODIMP CMetaPropertyTypes::get_MetaPropertySet(IMetaPropertySet **pppropset)
  577. {
  578. ENTER_API
  579. {
  580. ValidateOutPtr<IMetaPropertySet>(pppropset, m_ppropset);
  581. if (*pppropset != NULL)
  582. (*pppropset)->AddRef();
  583. return S_OK;
  584. }
  585. LEAVE_API
  586. }
  587. STDMETHODIMP CMetaPropertyTypes::get_ItemWithName(BSTR bstrName, IMetaPropertyType **ppproptype)
  588. {
  589. ENTER_API
  590. {
  591. ValidateIn(bstrName);
  592. ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
  593. t_map::iterator it = m_map.find(bstrName);
  594. if (it == m_map.end())
  595. return E_INVALIDARG;
  596. (*ppproptype = (*it).second)->AddRef();
  597. return S_OK;
  598. }
  599. LEAVE_API
  600. }
  601. STDMETHODIMP CMetaPropertyTypes::get_ItemWithID(long id, IMetaPropertyType **ppproptype)
  602. {
  603. ENTER_API
  604. {
  605. ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
  606. for (t_map::iterator it = m_map.begin(); it != m_map.end(); it++)
  607. {
  608. CComPtr<IMetaPropertyType> pproptype = (*it).second;
  609. long idCur;
  610. pproptype->get_ID(&idCur);
  611. if (idCur == id)
  612. {
  613. *ppproptype = pproptype.Detach();
  614. return S_OK;
  615. }
  616. }
  617. return E_INVALIDARG;
  618. }
  619. LEAVE_API
  620. }
  621. HRESULT CMetaPropertyTypes::Cache(long id, long idPropType, BSTR bstrName,
  622. CMetaPropertyType **ppproptype)
  623. {
  624. CComPtr<CMetaPropertyType> pproptype;
  625. t_map::iterator it = m_map.find(bstrName);
  626. if (it != m_map.end())
  627. {
  628. pproptype = (*it).second;
  629. }
  630. else
  631. {
  632. pproptype = NewComObject(CMetaPropertyType);
  633. if (pproptype == NULL)
  634. return E_OUTOFMEMORY;
  635. pproptype->Init(m_pdb, m_ppropset, id, idPropType, bstrName);
  636. BSTR bstrT = SysAllocString(bstrName);
  637. pproptype.CopyTo(&m_map[bstrT]);
  638. m_pdb->put_MetaPropertyType(id, pproptype);
  639. }
  640. *ppproptype = pproptype.Detach();
  641. return S_OK;
  642. }
  643. STDMETHODIMP CMetaPropertyTypes::get_AddNew(long idProp, BSTR bstrName, IMetaPropertyType **ppproptype)
  644. {
  645. ENTER_API
  646. {
  647. ValidateIn(bstrName);
  648. ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
  649. HRESULT hr;
  650. hr = get_ItemWithName(bstrName, ppproptype);
  651. if (SUCCEEDED(hr))
  652. return hr;
  653. CComPtr<CMetaPropertyType> pproptype;
  654. static long idCur = 1;
  655. long id;
  656. if (m_pdb == NULL)
  657. id = idCur++;
  658. else
  659. {
  660. ADODB::_RecordsetPtr prs;
  661. hr = m_pdb->get_PropTypesRS(&prs);
  662. if (FAILED(hr))
  663. return hr;
  664. // Create a new record.
  665. hr = prs->AddNew();
  666. prs->Fields->Item["idPropSet"]->Value = m_ppropset->GetID();
  667. prs->Fields->Item["idProp"]->Value = idProp;
  668. prs->Fields->Item["Name"]->Value = bstrName;
  669. hr = prs->Update();
  670. id = prs->Fields->Item["id"]->Value;
  671. }
  672. hr = Cache(id, idProp, bstrName, &pproptype);
  673. if (FAILED(hr))
  674. return hr;
  675. *ppproptype = pproptype.Detach();
  676. return S_OK;
  677. }
  678. LEAVE_API
  679. }
  680. /////////////////////////////////////////////////////////////////////////////
  681. // CMetaProperty
  682. STDMETHODIMP CMetaProperty::get_MetaPropertyType(IMetaPropertyType **ppproptype)
  683. {
  684. ENTER_API
  685. {
  686. ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
  687. return m_pdb->get_MetaPropertyType(m_idPropType, ppproptype);
  688. }
  689. LEAVE_API
  690. }
  691. STDMETHODIMP CMetaProperty::get_Language(long *pidLang)
  692. {
  693. ENTER_API
  694. {
  695. ValidateOut<long>(pidLang, m_idLang);
  696. return S_OK;
  697. }
  698. LEAVE_API
  699. }
  700. STDMETHODIMP CMetaProperty::get_Value(VARIANT *pvarValue)
  701. {
  702. ENTER_API
  703. {
  704. ValidateOut(pvarValue);
  705. return VariantCopy(pvarValue, &m_varValue);
  706. }
  707. LEAVE_API
  708. }
  709. STDMETHODIMP CMetaProperty::put_Value(VARIANT varValue)
  710. {
  711. ENTER_API
  712. {
  713. // Changing the value, so must reset the provider.
  714. m_idProvider = m_pdb->GetIDGuideDataProvider();
  715. return PutValue(varValue);
  716. }
  717. LEAVE_API
  718. }
  719. STDMETHODIMP CMetaProperty::PutValue(VARIANT varValue)
  720. {
  721. HRESULT hr;
  722. ADODB::_RecordsetPtr prs;
  723. m_varValue = varValue;
  724. hr = m_pdb->get_PropsIndexed(&prs);
  725. if (FAILED(hr))
  726. return hr;
  727. hr = SeekPropsRS(prs, m_pdb->FSQLServer(), m_idObj,
  728. m_idPropType, FALSE, m_idProvider, m_idLang);
  729. if (FAILED(hr))
  730. {
  731. hr = AddNew(prs);
  732. if (FAILED(hr))
  733. return hr;
  734. }
  735. hr = SaveValue(prs);
  736. if (FAILED(hr))
  737. {
  738. prs->CancelUpdate();
  739. return hr;
  740. }
  741. hr = prs->Update();
  742. if (FAILED(hr))
  743. return hr;
  744. m_pdb->Broadcast_ItemChanged(m_idObj);
  745. return hr;
  746. }
  747. STDMETHODIMP CMetaProperty::get_QueryClause(long &i, TCHAR *szOp, _bstr_t *pbstr)
  748. {
  749. TCHAR *szFieldName;
  750. TCHAR *szValue = NULL;
  751. switch (m_varValue.vt)
  752. {
  753. default:
  754. return E_INVALIDARG;
  755. case VT_EMPTY:
  756. return E_NOTIMPL; //Special case
  757. case VT_I2:
  758. case VT_I4:
  759. {
  760. szFieldName = _T("lValue");
  761. int cb = 32;
  762. szValue = new TCHAR [cb];
  763. if (szValue == NULL)
  764. return E_OUTOFMEMORY;
  765. _sntprintf(szValue, cb, _T("%d"), (long) m_varValue);
  766. }
  767. break;
  768. case VT_R4:
  769. case VT_R8:
  770. {
  771. szFieldName = _T("fValue");
  772. int cb = 32;
  773. szValue = new TCHAR [cb];
  774. if (szValue == NULL)
  775. return E_OUTOFMEMORY;
  776. _sntprintf(szValue, cb, _T("%.17f"), (double) m_varValue);
  777. }
  778. break;
  779. case VT_DATE:
  780. {
  781. szFieldName = _T("fValue");
  782. _variant_t varT;
  783. ::VariantChangeTypeEx(&varT, &m_varValue,
  784. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, VT_BSTR);
  785. long cb = SysStringLen(varT.bstrVal) + 3;
  786. szValue = new TCHAR [cb];
  787. if (szValue == NULL)
  788. return E_OUTOFMEMORY;
  789. _sntprintf(szValue, cb, _T("#%s#"), (const TCHAR *) varT.bstrVal);
  790. }
  791. break;
  792. case VT_BSTR:
  793. {
  794. _bstr_t bstr = m_varValue.bstrVal;
  795. int cb = bstr.length() + 3; // Add on 2 quotes and null terminator
  796. szValue = new TCHAR [cb];
  797. if (szValue == NULL)
  798. return E_OUTOFMEMORY;
  799. if (bstr.length() < 255)
  800. {
  801. szFieldName = _T("sValue");
  802. _sntprintf(szValue, cb, _T("\"%s\""),
  803. (const TCHAR *) bstr);
  804. }
  805. else
  806. {
  807. delete [] szValue;
  808. return E_INVALIDARG; //UNDONE: What to do?
  809. }
  810. }
  811. break;
  812. }
  813. int cb = -1;
  814. int cbBuf = 128;
  815. TCHAR *sz = NULL;
  816. while (cb < 0)
  817. {
  818. delete [] sz;
  819. sz = new TCHAR [cbBuf];
  820. if (sz == NULL)
  821. return E_OUTOFMEMORY;
  822. cb = _sntprintf(sz, cbBuf,
  823. _T("(Props_%i.idPropType = %i) AND (Props_%i.%s %s %s)"),
  824. i, m_idPropType, i, szFieldName, szOp, szValue);
  825. cbBuf *= 2;
  826. }
  827. i++;
  828. *pbstr = sz;
  829. delete [] sz;
  830. delete [] szValue;
  831. return S_OK;
  832. }
  833. STDMETHODIMP CMetaProperty::get_Cond(BSTR bstrCond, IMetaPropertyCondition **pppropcond)
  834. {
  835. ENTER_API
  836. {
  837. ValidateIn(bstrCond);
  838. ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
  839. if (bstrCond == NULL)
  840. return E_INVALIDARG;
  841. CComPtr<CMetaPropertyCondition1Prop> ppropcond = NULL;
  842. if (wcscmp(bstrCond, L"=") == 0)
  843. {
  844. ppropcond = NewComObject(CMetaPropertyConditionEQ);
  845. }
  846. else if ((wcscmp(bstrCond, L"!=") == 0) || (wcscmp(bstrCond, L"<>") == 0))
  847. {
  848. ppropcond = NewComObject(CMetaPropertyConditionNE);
  849. }
  850. else if (_wcsicmp(bstrCond, L"LIKE") == 0)
  851. {
  852. ppropcond = NewComObject(CMetaPropertyConditionLike);
  853. }
  854. else if (_wcsicmp(bstrCond, L"NOT LIKE") == 0)
  855. {
  856. ppropcond = NewComObject(CMetaPropertyConditionNotLike);
  857. }
  858. else if (wcscmp(bstrCond, L"<") == 0)
  859. {
  860. ppropcond = NewComObject(CMetaPropertyConditionLT);
  861. }
  862. else if (wcscmp(bstrCond, L"<=") == 0)
  863. {
  864. ppropcond = NewComObject(CMetaPropertyConditionLE);
  865. }
  866. else if (wcscmp(bstrCond, L">") == 0)
  867. {
  868. ppropcond = NewComObject(CMetaPropertyConditionGT);
  869. }
  870. else if (wcscmp(bstrCond, L">=") == 0)
  871. {
  872. ppropcond = NewComObject(CMetaPropertyConditionGE);
  873. }
  874. else
  875. {
  876. return E_INVALIDARG;
  877. }
  878. if (ppropcond == NULL)
  879. return E_OUTOFMEMORY;
  880. ppropcond->Init(this);
  881. *pppropcond = ppropcond.Detach();
  882. return S_OK;
  883. }
  884. LEAVE_API
  885. }
  886. HRESULT CMetaProperty::AddNew(ADODB::_RecordsetPtr prs)
  887. {
  888. HRESULT hr;
  889. // Create a new record.
  890. hr = prs->AddNew();
  891. if (FAILED(hr))
  892. return hr;
  893. prs->Fields->Item["idObj"]->Value = m_idObj;
  894. prs->Fields->Item["idPropType"]->Value = m_idPropType;
  895. prs->Fields->Item["idProvider"]->Value = m_idProvider;
  896. prs->Fields->Item["idLanguage"]->Value = m_idLang;
  897. return S_OK;
  898. }
  899. HRESULT CMetaProperty::SaveValue(ADODB::_RecordsetPtr prs)
  900. {
  901. HRESULT hr;
  902. try
  903. {
  904. VARTYPE vt = m_varValue.vt;
  905. IUnknown *punk;
  906. switch (vt)
  907. {
  908. default:
  909. return E_INVALIDARG;
  910. case VT_EMPTY:
  911. break;
  912. case VT_I2:
  913. case VT_I4:
  914. prs->Fields->Item["lValue"]->Value = m_varValue;
  915. break;
  916. case VT_R4:
  917. case VT_R8:
  918. case VT_DATE:
  919. prs->Fields->Item["fValue"]->Value = m_varValue;
  920. break;
  921. case VT_BSTR_BLOB:
  922. case VT_BSTR:
  923. prs->Fields->Item["sValue"]->Value = m_varValue;
  924. break;
  925. case VT_DISPATCH:
  926. case VT_UNKNOWN:
  927. #if 0
  928. hr = SaveObjectToField(m_varValue, prs->Fields->Item["oValue"]);
  929. if (FAILED(hr))
  930. return hr;
  931. #else
  932. punk = m_varValue.punkVal;
  933. goto SaveObj;
  934. #endif
  935. break;
  936. case VT_BYREF | VT_UNKNOWN:
  937. punk = *m_varValue.ppunkVal;
  938. vt = VT_UNKNOWN;
  939. SaveObj:
  940. {
  941. // Temporarily set to NULL
  942. prs->Fields->Item["ValueType"]->Value = _variant_t((long) VT_UNKNOWN);
  943. prs->Fields->Item["lValue"]->Value = _variant_t((long) NULL);
  944. if (punk != NULL)
  945. {
  946. hr = prs->Update();
  947. long idObj;
  948. hr = m_pdb->SaveObject(punk, &idObj);
  949. if (FAILED(hr))
  950. return hr;
  951. // Seek back and fix it up.
  952. hr = SeekPropsRS(prs, m_pdb->FSQLServer(), m_idObj,
  953. m_idPropType, FALSE, m_idProvider, m_idLang);
  954. if (FAILED(hr))
  955. return hr;
  956. prs->Fields->Item["lValue"]->Value = idObj;
  957. }
  958. }
  959. break;
  960. }
  961. prs->Fields->Item["ValueType"]->Value = _variant_t((long) vt);
  962. }
  963. catch (_com_error & e)
  964. {
  965. return e.Error();
  966. }
  967. return S_OK;
  968. }
  969. HRESULT CMetaProperty::LoadValue(ADODB::_RecordsetPtr prs)
  970. {
  971. HRESULT hr;
  972. _variant_t varType = prs->Fields->Item["ValueType"]->Value;
  973. try
  974. {
  975. varType.ChangeType(VT_I4);
  976. }
  977. catch (_com_error &)
  978. {
  979. return E_INVALIDARG;
  980. }
  981. switch (varType.lVal)
  982. {
  983. default:
  984. return E_INVALIDARG;
  985. case VT_EMPTY:
  986. m_varValue.Clear();
  987. break;
  988. case VT_I2:
  989. case VT_I4:
  990. m_varValue = prs->Fields->Item["lValue"]->Value;
  991. break;
  992. case VT_R4:
  993. case VT_R8:
  994. case VT_DATE:
  995. m_varValue = prs->Fields->Item["fValue"]->Value;
  996. break;
  997. case VT_BSTR_BLOB:
  998. case VT_BSTR:
  999. m_varValue = prs->Fields->Item["sValue"]->Value;
  1000. m_varValue.vt = varType.lVal;
  1001. break;
  1002. case VT_UNKNOWN:
  1003. #if 0
  1004. hr = LoadObjectFromField(prs->Fields->Item["oValue"], &m_varValue);
  1005. if (FAILED(hr))
  1006. return hr;
  1007. #else
  1008. {
  1009. CComPtr<IUnknown> punk;
  1010. long idObj = prs->Fields->Item["lValue"]->Value;
  1011. if (idObj != NULL)
  1012. {
  1013. hr = m_pdb->CacheObject(idObj, (long) 0, &punk);
  1014. if (FAILED(hr))
  1015. return hr;
  1016. }
  1017. m_varValue = punk;
  1018. }
  1019. #endif
  1020. break;
  1021. }
  1022. return S_OK;
  1023. }
  1024. /////////////////////////////////////////////////////////////////////////////
  1025. // CMetaProperties
  1026. STDMETHODIMP CMetaProperties::get_Count(long *plCount)
  1027. {
  1028. ENTER_API
  1029. {
  1030. ValidateOut<long>(plCount, 0);
  1031. HRESULT hr;
  1032. ADODB::_RecordsetPtr prs;
  1033. hr = m_pdb->get_PropsIndexed(&prs);
  1034. prs->MoveFirst();
  1035. TCHAR szFind[32];
  1036. wsprintf(szFind, _T("idObj = %d"), m_idObj);
  1037. hr = prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
  1038. if (FAILED(hr))
  1039. return S_OK;
  1040. if (m_idPropType != 0)
  1041. {
  1042. wsprintf(szFind, _T("idPropType = %d"), m_idPropType);
  1043. prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
  1044. if (prs->EndOfFile)
  1045. return S_OK;
  1046. }
  1047. // UNDONE: This is not the most efficient, but it's what works for now.
  1048. while (!prs->EndOfFile)
  1049. {
  1050. long idObj2 = prs->Fields->Item["idObj"]->Value;
  1051. if (m_idObj != idObj2)
  1052. break;
  1053. if (m_idPropType != 0)
  1054. {
  1055. long idPropType = prs->Fields->Item["idPropType"]->Value;
  1056. if (m_idPropType != idPropType)
  1057. break;
  1058. }
  1059. (*plCount)++;
  1060. hr = prs->MoveNext();
  1061. if (FAILED(hr))
  1062. return hr;
  1063. }
  1064. return S_OK;
  1065. }
  1066. LEAVE_API
  1067. }
  1068. HRESULT CMetaProperties::Load(long idPropType, ADODB::_RecordsetPtr prs, IMetaProperty **ppprop)
  1069. {
  1070. HRESULT hr;
  1071. CComPtr<IMetaPropertyType> pproptype;
  1072. CComPtr<IMetaProperty> pprop;
  1073. hr = m_pdb->get_MetaPropertyType(idPropType, &pproptype);
  1074. if (FAILED(hr))
  1075. return hr;
  1076. long idLang = prs->Fields->Item["idLanguage"]->Value;
  1077. long idProvider = prs->Fields->Item["idProvider"]->Value;
  1078. CComQIPtr<CMetaPropertyType> pproptypeT(pproptype);
  1079. _variant_t varValue;
  1080. hr = pproptypeT->GetNew(idProvider, idLang, varValue, &pprop);
  1081. if (FAILED(hr))
  1082. return hr;
  1083. CComQIPtr<CMetaProperty> ppropT(pprop);
  1084. ppropT->SetObjectID(m_idObj);
  1085. hr = ppropT->LoadValue(prs);
  1086. if (FAILED(hr))
  1087. return hr;
  1088. *ppprop = pprop.Detach();
  1089. return S_OK;
  1090. }
  1091. STDMETHODIMP CMetaProperties::get_Item(VARIANT varIndex, IMetaProperty **ppprop)
  1092. {
  1093. ENTER_API
  1094. {
  1095. ValidateOutPtr<IMetaProperty>(ppprop, NULL);
  1096. HRESULT hr;
  1097. if (varIndex.vt == VT_BSTR)
  1098. {
  1099. CComPtr<IMetaPropertyType> pproptype;
  1100. hr = m_pdb->get_MetaPropertyType(varIndex.bstrVal, &pproptype);
  1101. if (FAILED(hr))
  1102. return E_INVALIDARG;
  1103. hr = get_ItemWith(pproptype, 0, ppprop);
  1104. if (FAILED(hr))
  1105. {
  1106. CComPtr<IGuideDataProvider> pprovider;
  1107. m_pdb->get_GuideDataProvider(&pprovider);
  1108. _variant_t varNil;
  1109. hr = get_AddNew(pproptype, pprovider, 0, varNil, ppprop);
  1110. }
  1111. return hr;
  1112. }
  1113. _variant_t var(varIndex);
  1114. try
  1115. {
  1116. var.ChangeType(VT_I4);
  1117. }
  1118. catch (_com_error &)
  1119. {
  1120. return E_INVALIDARG;
  1121. }
  1122. if (var.lVal < 0)
  1123. return E_INVALIDARG;
  1124. ADODB::_RecordsetPtr prs;
  1125. hr = m_pdb->get_PropsIndexed(&prs);
  1126. prs->MoveFirst();
  1127. TCHAR szFind[32];
  1128. wsprintf(szFind, _T("idObj = %d"), m_idObj);
  1129. prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
  1130. if (prs->EndOfFile)
  1131. return E_INVALIDARG;
  1132. if (m_idPropType != 0)
  1133. {
  1134. wsprintf(szFind, _T("idPropType = %d"), m_idPropType);
  1135. prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
  1136. if (prs->EndOfFile)
  1137. return E_INVALIDARG;
  1138. }
  1139. if (var.lVal > 0)
  1140. {
  1141. hr = prs->Move(var.lVal);
  1142. if (FAILED(hr))
  1143. return hr;
  1144. }
  1145. if (prs->EndOfFile)
  1146. return E_INVALIDARG;
  1147. long idObj2 = prs->Fields->Item["idObj"]->Value;
  1148. if (m_idObj != idObj2)
  1149. return E_INVALIDARG;
  1150. long idPropType = prs->Fields->Item["idPropType"]->Value;
  1151. if (m_idPropType != 0 && (m_idPropType != idPropType))
  1152. return E_INVALIDARG;
  1153. return Load(idPropType, prs, ppprop);
  1154. }
  1155. LEAVE_API
  1156. }
  1157. HRESULT CMetaProperties::get_AddNew(IMetaPropertyType *pproptype,
  1158. IGuideDataProvider *pprovider, long lang, VARIANT varValue,
  1159. IMetaProperty **ppprop)
  1160. {
  1161. ENTER_API
  1162. {
  1163. ValidateInPtr<IMetaPropertyType>(pproptype);
  1164. ValidateOutPtr<IMetaProperty>(ppprop, NULL);
  1165. HRESULT hr;
  1166. CComQIPtr<CMetaPropertyType> pproptypeT(pproptype);
  1167. long idProvider = 0;
  1168. if (pprovider != NULL)
  1169. pprovider->get_ID(&idProvider);
  1170. hr = pproptypeT->GetNew(idProvider, lang, varValue, ppprop);
  1171. if (FAILED(hr))
  1172. return hr;
  1173. return Add(*ppprop);
  1174. }
  1175. LEAVE_API
  1176. }
  1177. STDMETHODIMP CMetaProperties::get_AddNew(IMetaPropertyType *pproptype, long lang, VARIANT varValue, IMetaProperty **ppprop)
  1178. {
  1179. ENTER_API
  1180. {
  1181. ValidateInPtr<IMetaPropertyType>(pproptype);
  1182. ValidateOutPtr<IMetaProperty>(ppprop, NULL);
  1183. HRESULT hr = pproptype->get_New(lang, varValue, ppprop);
  1184. if (FAILED(hr))
  1185. return hr;
  1186. return Add(*ppprop);
  1187. }
  1188. LEAVE_API
  1189. }
  1190. #if 0
  1191. STDMETHODIMP CMetaProperties::get_UpdateOrAddNew(IMetaPropertyType *pproptype, long lang, VARIANT varValue, IMetaProperty **ppprop)
  1192. {
  1193. HRESULT hr;
  1194. CComPtr<IMetaProperty> pprop;
  1195. hr = get_ItemWith(pproptype, lang, &pprop);
  1196. if (FAILED(hr))
  1197. return AddNew(pproptype, lang, varValue, ppprop);
  1198. hr = pprop->put_Value(varValue);
  1199. if (FAILED(hr))
  1200. return hr;
  1201. *ppprop = pprop.Detach();
  1202. return S_OK;
  1203. }
  1204. #endif
  1205. STDMETHODIMP CMetaProperties::Add(IMetaProperty *pprop)
  1206. {
  1207. HRESULT hr;
  1208. if (pprop == NULL)
  1209. return E_FAIL;
  1210. ADODB::_RecordsetPtr prs;
  1211. m_pdb->get_PropsRS(&prs);
  1212. CComQIPtr<CMetaProperty> ppropT(pprop);
  1213. hr = ppropT->SetObjectID(m_idObj);
  1214. if (FAILED(hr))
  1215. return hr;
  1216. hr = ppropT->AddNew(prs);
  1217. if (FAILED(hr))
  1218. return hr;
  1219. hr = ppropT->SaveValue(prs);
  1220. if (FAILED(hr))
  1221. {
  1222. prs->CancelUpdate();
  1223. return hr;
  1224. }
  1225. hr = prs->Update();
  1226. if (FAILED(hr))
  1227. return hr;
  1228. m_pdb->Broadcast_ItemChanged(m_idObj);
  1229. return hr;
  1230. }
  1231. STDMETHODIMP CMetaProperties::get_ItemWithTypeProviderLang(IMetaPropertyType *pproptype,
  1232. IGuideDataProvider *pprovider, long idLang, IMetaProperty **ppprop)
  1233. {
  1234. ENTER_API
  1235. {
  1236. ValidateInPtr<IMetaPropertyType>(pproptype);
  1237. ValidateOutPtr<IMetaProperty>(ppprop, NULL);
  1238. long idProvider = 0;
  1239. if (pprovider != NULL)
  1240. pprovider->get_ID(&idProvider);
  1241. return get_ItemWithTypeProviderLang(pproptype, FALSE, idProvider, idLang, ppprop);
  1242. }
  1243. LEAVE_API
  1244. }
  1245. HRESULT CMetaProperties::get_ItemWithTypeProviderLang(IMetaPropertyType *pproptype,
  1246. boolean fAnyProvider, long idProvider, long idLang, IMetaProperty **ppprop)
  1247. {
  1248. HRESULT hr;
  1249. ADODB::_RecordsetPtr prs;
  1250. CComQIPtr<CMetaPropertyType> pproptypeT(pproptype);
  1251. long idPropType = pproptypeT->GetID();
  1252. hr = m_pdb->get_PropsIndexed(&prs);
  1253. hr = SeekPropsRS(prs, m_pdb->FSQLServer(), m_idObj,
  1254. idPropType, fAnyProvider, idProvider, idLang);
  1255. if (FAILED(hr))
  1256. return hr;
  1257. return Load(idPropType, prs, ppprop);
  1258. }
  1259. STDMETHODIMP CMetaProperties::get_ItemWith(IMetaPropertyType *pproptype, long idLang, IMetaProperty **ppprop)
  1260. {
  1261. ENTER_API
  1262. {
  1263. ValidateInPtr<IMetaPropertyType>(pproptype);
  1264. ValidateOutPtr<IMetaProperty>(ppprop);
  1265. long idProvider = m_pdb->GetIDGuideDataProvider();
  1266. return get_ItemWithTypeProviderLang(pproptype, TRUE, idProvider, idLang, ppprop);
  1267. }
  1268. LEAVE_API
  1269. }
  1270. STDMETHODIMP CMetaProperties::get_ItemsWithMetaPropertyType(IMetaPropertyType *ptype, IMetaProperties **ppprops)
  1271. {
  1272. ENTER_API
  1273. {
  1274. ValidateInPtr<IMetaPropertyType>(ptype);
  1275. ValidateOutPtr<IMetaProperties>(ppprops, NULL);
  1276. CComQIPtr<CMetaPropertyType> ptypeT(ptype);
  1277. if (ptypeT == NULL)
  1278. return E_POINTER;
  1279. long idPropType;
  1280. idPropType = ptypeT->GetID();
  1281. CComPtr<CMetaProperties> pprops = NewComObject(CMetaProperties);
  1282. if (pprops != NULL)
  1283. pprops->Init(m_idObj, idPropType, m_pdb);
  1284. *ppprops = pprops.Detach();
  1285. return S_OK;
  1286. }
  1287. LEAVE_API
  1288. }
  1289. /////////////////////////////////////////////////////////////////////////////
  1290. // CMetaPropertyCondition
  1291. STDMETHODIMP CMetaPropertyCondition::get_And(IMetaPropertyCondition *ppropcond2, IMetaPropertyCondition **pppropcond)
  1292. {
  1293. ENTER_API
  1294. {
  1295. ValidateInPtr<IMetaPropertyCondition>(ppropcond2);
  1296. ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
  1297. CComPtr<CMetaPropertyConditionAnd> ppropcond = NewComObject(CMetaPropertyConditionAnd);
  1298. if (ppropcond == NULL)
  1299. return E_OUTOFMEMORY;
  1300. ppropcond->Init(this, ppropcond2);
  1301. *pppropcond = ppropcond.Detach();
  1302. return S_OK;
  1303. }
  1304. LEAVE_API
  1305. }
  1306. STDMETHODIMP CMetaPropertyCondition::get_Or(IMetaPropertyCondition *ppropcond2, IMetaPropertyCondition **pppropcond)
  1307. {
  1308. ENTER_API
  1309. {
  1310. ValidateInPtr<IMetaPropertyCondition>(ppropcond2);
  1311. ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
  1312. CComPtr<CMetaPropertyConditionOr> ppropcond = NewComObject(CMetaPropertyConditionOr);
  1313. if (ppropcond == NULL)
  1314. return E_OUTOFMEMORY;
  1315. ppropcond->Init(this, ppropcond2);
  1316. *pppropcond = ppropcond.Detach();
  1317. return S_OK;
  1318. }
  1319. LEAVE_API
  1320. }
  1321. #if 0
  1322. STDMETHODIMP CMetaPropertyCondition::get_Not(IMetaPropertyCondition **pppropcond)
  1323. {
  1324. ENTER_API
  1325. {
  1326. ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
  1327. CComPtr<CMetaPropertyConditionNot> ppropcond = NewComObject(CMetaPropertyConditionNot);
  1328. if (ppropcond == NULL)
  1329. return E_OUTOFMEMORY;
  1330. ppropcond->Init(this);
  1331. *pppropcond = ppropcond.Detach();
  1332. return S_OK;
  1333. }
  1334. LEAVE_API
  1335. }
  1336. STDMETHODIMP CMetaPropertyCondition::get_Test(IMetaProperties *pprops, BOOL *pfOk)
  1337. {
  1338. ENTER_API
  1339. {
  1340. ValidateInPtr<IMetaProperties>(pprops);
  1341. ValidateOut<BOOL>(pfOk, FALSE);
  1342. return S_OK;
  1343. }
  1344. LEAVE_API
  1345. }
  1346. #endif