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.

1270 lines
30 KiB

  1. //***************************************************************************
  2. //
  3. // VPTASKSJ.CPP
  4. //
  5. // Module: WBEM VIEW PROVIDER
  6. //
  7. // Purpose: Contains the join methods for taskobject implementation
  8. //
  9. // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include <provexpt.h>
  14. #include <provcoll.h>
  15. #include <provtempl.h>
  16. #include <provmt.h>
  17. #include <typeinfo.h>
  18. #include <process.h>
  19. #include <objbase.h>
  20. #include <objidl.h>
  21. #include <stdio.h>
  22. #include <wbemidl.h>
  23. #include <provcont.h>
  24. #include <provevt.h>
  25. #include <provthrd.h>
  26. #include <provlog.h>
  27. #include <cominit.h>
  28. #include <dsgetdc.h>
  29. #include <lmcons.h>
  30. #include <lmapibuf.h>
  31. #include <instpath.h>
  32. #include <genlex.h>
  33. #include <sql_1.h>
  34. #include <objpath.h>
  35. #include <vpdefs.h>
  36. #include <vpcfac.h>
  37. #include <vpquals.h>
  38. #include <vpserv.h>
  39. #include <vptasks.h>
  40. #include <wbemtime.h>
  41. BOOL CompareSimplePropertyValues(VARIANT* v1, VARIANT* v2, CIMTYPE ct)
  42. {
  43. BOOL retVal = FALSE;
  44. if (v1->vt == v2->vt)
  45. {
  46. switch (ct)
  47. {
  48. case CIM_BOOLEAN:
  49. {
  50. if (VT_BOOL == v1->vt)
  51. {
  52. if (v1->boolVal == v2->boolVal)
  53. {
  54. retVal = TRUE;
  55. }
  56. }
  57. }
  58. break;
  59. case CIM_UINT8:
  60. {
  61. if (VT_UI1 == v1->vt)
  62. {
  63. if (v1->bVal == v2->bVal)
  64. {
  65. retVal = TRUE;
  66. }
  67. }
  68. }
  69. break;
  70. case CIM_SINT16:
  71. case CIM_CHAR16:
  72. case CIM_SINT8:
  73. {
  74. if (VT_I2 == v1->vt)
  75. {
  76. if (v1->iVal == v2->iVal)
  77. {
  78. retVal = TRUE;
  79. }
  80. }
  81. }
  82. break;
  83. case CIM_UINT32:
  84. case CIM_SINT32:
  85. case CIM_UINT16:
  86. {
  87. if (VT_I4 == v1->vt)
  88. {
  89. if (v1->lVal == v2->lVal)
  90. {
  91. retVal = TRUE;
  92. }
  93. }
  94. }
  95. break;
  96. case CIM_REFERENCE:
  97. //TO DO:
  98. //references should be normalised for equality checks.
  99. //should do this once CIMOM does...
  100. case CIM_STRING:
  101. case CIM_SINT64:
  102. case CIM_UINT64:
  103. {
  104. if (VT_BSTR == v1->vt)
  105. {
  106. if (0 == _wcsicmp(v1->bstrVal,v2->bstrVal))
  107. {
  108. retVal = TRUE;
  109. }
  110. }
  111. }
  112. break;
  113. case CIM_DATETIME:
  114. {
  115. if (VT_BSTR == v1->vt)
  116. {
  117. WBEMTime t1(v1->bstrVal);
  118. WBEMTime t2(v2->bstrVal);
  119. if (t1 == t2)
  120. {
  121. retVal = TRUE;
  122. }
  123. }
  124. }
  125. break;
  126. default:
  127. {
  128. //unsupported by this function
  129. }
  130. }
  131. }
  132. return retVal;
  133. }
  134. //Validate:
  135. //1) All classes mentioned in join exist.
  136. //2) All properties mentioned in join map to view class properties
  137. //3) All classes mentioned in sources are mentioned in join
  138. //4) Any != operator is not applied to two properties which map to the same view property
  139. //5) All clauses have different classes being checked
  140. BOOL WbemTaskObject::ValidateJoin()
  141. {
  142. //3) check all sources mentioned in join
  143. //this check with (1) will do the trick
  144. if (m_JoinOnArray.m_AllClasses.GetCount() != m_SourceArray.GetSize())
  145. {
  146. return FALSE;
  147. }
  148. //1) check all join classes exist
  149. POSITION pos = m_JoinOnArray.m_AllClasses.GetStartPosition();
  150. while (pos)
  151. {
  152. int val;
  153. CStringW tmpStr;
  154. m_JoinOnArray.m_AllClasses.GetNextAssoc(pos, tmpStr, val);
  155. if (!m_ClassToIndexMap.Lookup(tmpStr, val))
  156. {
  157. return FALSE;
  158. }
  159. }
  160. wchar_t** classA = m_JoinOnArray.GetAClasses();
  161. wchar_t** propsA = m_JoinOnArray.GetAProperties();
  162. wchar_t** classB = m_JoinOnArray.GetBClasses();
  163. wchar_t** propsB = m_JoinOnArray.GetBProperties();
  164. UINT* ops = m_JoinOnArray.GetOperators();
  165. //(2), (4) and (5) validations
  166. //=============================
  167. for (int x = 0; x < m_JoinOnArray.GetCount(); x++)
  168. {
  169. if (_wcsicmp(classA[x], classB[x]) == 0)
  170. {
  171. return FALSE;
  172. }
  173. int indexA;
  174. if (m_ClassToIndexMap.Lookup(classA[x], indexA))
  175. {
  176. int indexB;
  177. if (m_ClassToIndexMap.Lookup(classB[x], indexB))
  178. {
  179. POSITION pos = m_PropertyMap.GetStartPosition();
  180. CStringW propA;
  181. CStringW propB;
  182. while (pos)
  183. {
  184. CStringW key;
  185. CPropertyQualifierItem* pItem;
  186. m_PropertyMap.GetNextAssoc(pos, key, pItem);
  187. if (pItem->m_SrcPropertyNames[indexA].CompareNoCase(propsA[x]) == 0)
  188. {
  189. propA = key;
  190. if (!propB.IsEmpty())
  191. {
  192. break;
  193. }
  194. }
  195. if (pItem->m_SrcPropertyNames[indexB].CompareNoCase(propsB[x]) == 0)
  196. {
  197. propB = key;
  198. if (!propA.IsEmpty())
  199. {
  200. break;
  201. }
  202. }
  203. }
  204. //check both properties exist (2)
  205. if (propA.IsEmpty() || propB.IsEmpty())
  206. {
  207. return FALSE;
  208. }
  209. //validate expression (4)
  210. if (ops[x] == CJoinOnQualifierArray::NOT_EQUALS_OPERATOR && (propA.CompareNoCase(propB) == 0))
  211. {
  212. return FALSE;
  213. }
  214. }
  215. else
  216. {
  217. return FALSE;
  218. }
  219. }
  220. else
  221. {
  222. return FALSE;
  223. }
  224. }
  225. return TRUE;
  226. }
  227. #ifdef VP_PERFORMANT_JOINS
  228. //should not compile with compiler flag set til I'm ready
  229. BOOL WbemTaskObject::CreateAndIndicateJoinsPerf(WbemProvErrorObject &a_ErrorObject, BOOL a_bSingle)
  230. {
  231. BOOL retVal = TRUE;
  232. //check all queries were asked...
  233. if (m_ObjSinkArray.GetSize() != m_SourceArray.GetSize())
  234. {
  235. retVal = FALSE;
  236. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  237. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  238. a_ErrorObject.SetMessage ( L"A source query failed or was not executed therefore a join could not be created." );
  239. }
  240. //check we got results from all queries...
  241. for (UINT x = 0; x < m_ObjSinkArray.GetSize(); x++)
  242. {
  243. if ((m_ObjSinkArray[x] == NULL) || FAILED(m_ObjSinkArray[x]->GetResult()) || !m_ObjSinkArray[x]->m_ObjArray.GetSize())
  244. {
  245. if (!a_bSingle)
  246. {
  247. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  248. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  249. a_ErrorObject.SetMessage ( L"A source query failed or returned no instances." );
  250. }
  251. retVal = FALSE;
  252. break;
  253. }
  254. }
  255. //perform the join of all results...
  256. if (retVal)
  257. {
  258. CMap<CStringW, LPCWSTR, int, int> t_JoinedClasses;
  259. CList<IWbemClassObject*, IWbemClassObject*> t_ResultObjs;
  260. retVal = JoinTwoColumns(a_ErrorObject, t_JoinedClasses, t_ResultObjs);
  261. wchar_t** t_clsA = m_JoinOnArray.GetAClasses();
  262. wchar_t** t_clsB = m_JoinOnArray.GetBClasses();
  263. wchar_t** t_prpsA = m_JoinOnArray.GetAProperties();
  264. wchar_t** t_prpsB = m_JoinOnArray.GetBProperties();
  265. while ( retVal && (t_JoinedClasses.GetCount() != m_SourceArray.GetSize()) )
  266. {
  267. DWORD t_column = m_SourceArray.GetSize() + 1;
  268. CList <int, int> t_IndexArray;
  269. wchar_t *t_classname = NULL;
  270. //find a column not already joined that can be joined now...
  271. for (x = 0; x < m_JoinOnArray.GetCount(); x++)
  272. {
  273. if (!m_JoinOnArray.m_bDone[x])
  274. {
  275. int dummyInt = 0;
  276. if (t_classname == NULL)
  277. {
  278. if (t_JoinedClasses.Lookup(t_clsA[x], dummyInt))
  279. {
  280. if (!m_ClassToIndexMap.Lookup(t_clsB[x], (int &)t_column))
  281. {
  282. retVal = FALSE;
  283. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  284. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  285. a_ErrorObject.SetMessage ( L"An unexpected error ocurred performing the join." );
  286. }
  287. t_classname = t_clsB[x];
  288. t_JoinedClasses.SetAt(t_classname, 0);
  289. m_JoinOnArray.m_bDone[x] = TRUE;
  290. t_IndexArray.AddTail(x);
  291. //want all clauses the same way around...
  292. t_clsB[x] = t_clsA[x];
  293. t_clsA[x] = t_classname;
  294. wchar_t *t_tmpStr = t_prpsA[x];
  295. t_prpsA[x] = t_prpsB[x];
  296. t_prpsB[x] = t_tmpStr;
  297. }
  298. else if (t_JoinedClasses.Lookup(t_clsB[x], dummyInt))
  299. {
  300. if (!m_ClassToIndexMap.Lookup(t_clsA[x], (int &)t_column))
  301. {
  302. retVal = FALSE;
  303. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  304. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  305. a_ErrorObject.SetMessage ( L"An unexpected error ocurred performing the join." );
  306. }
  307. t_classname = t_clsA[x];
  308. t_JoinedClasses.SetAt(t_classname, 0);
  309. m_JoinOnArray.m_bDone[x] = TRUE;
  310. t_IndexArray.AddTail(x);
  311. }
  312. }
  313. else
  314. {
  315. //find all clauses which can be evaluated now...
  316. if ((_wcsicmp(t_classname, t_clsA[x]) == 0) && (t_JoinedClasses.Lookup(t_clsB[x], dummyInt)))
  317. {
  318. t_IndexArray.AddTail(x);
  319. m_JoinOnArray.m_bDone[x] = TRUE;
  320. }
  321. else if ((_wcsicmp(t_classname, t_clsB[x]) == 0) && (t_JoinedClasses.Lookup(t_clsA[x], dummyInt)))
  322. {
  323. //want the clauses in the same order for simpler evaluation later...
  324. wchar_t *t_tmpStr = t_clsA[x];
  325. t_clsA[x] = t_clsB[x];
  326. t_clsB[x] = t_tmpStr;
  327. t_tmpStr = t_prpsA[x];
  328. t_prpsA[x] = t_prpsB[x];
  329. t_prpsB[x] = t_tmpStr;
  330. t_IndexArray.AddTail(x);
  331. m_JoinOnArray.m_bDone[x] = TRUE;
  332. }
  333. }
  334. }
  335. }
  336. if (t_column == m_SourceArray.GetSize() + 1)
  337. {
  338. retVal = FALSE;
  339. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  340. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  341. a_ErrorObject.SetMessage ( L"Failed to perform join." );
  342. }
  343. else
  344. {
  345. retVal = AddColumnToJoin(a_ErrorObject, t_JoinedClasses, t_ResultObjs, t_column, t_IndexArray);
  346. t_IndexArray.RemoveAll();
  347. }
  348. }
  349. if (retVal)
  350. {
  351. if (m_bIndicate)
  352. {
  353. POSITION t_pos = t_ResultObjs.GetHeadPosition();
  354. BOOL t_bIndicated = FALSE;
  355. while (t_pos)
  356. {
  357. IWbemClassObject *t_Obj = t_ResultObjs.GetNext(t_pos);
  358. if (t_Obj)
  359. {
  360. if (PostFilter(t_Obj))
  361. {
  362. if (a_bSingle && t_bIndicated)
  363. {
  364. retVal = FALSE;
  365. a_ErrorObject.SetStatus ( WBEM_PROV_E_TOOMANYRESULTSRETURNED ) ;
  366. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  367. a_ErrorObject.SetMessage ( L"Too many view instances can be created." ) ;
  368. break;
  369. }
  370. else
  371. {
  372. m_NotificationHandler->Indicate(1, &t_Obj);
  373. t_bIndicated = TRUE;
  374. }
  375. }
  376. }
  377. }
  378. }
  379. }
  380. t_ResultObjs.RemoveAll();
  381. }
  382. //clean up...
  383. for (x = 0; x < m_ObjSinkArray.GetSize(); x++)
  384. {
  385. if (m_ObjSinkArray[x] != NULL)
  386. {
  387. m_ObjSinkArray[x]->Release();
  388. }
  389. }
  390. m_ObjSinkArray.RemoveAll();
  391. return retVal;
  392. }
  393. BOOL WbemTaskObject::JoinItem(WbemProvErrorObject &a_ErrorObject,
  394. IWbemClassObject *a_Obj1, IWbemClassObject *a_vObj,
  395. IWbemClassObject *a_resObj, CList <int, int> &a_IndexArray,
  396. DWORD a_indx1)
  397. {
  398. BOOL retVal = TRUE;
  399. wchar_t** t_clsA = m_JoinOnArray.GetAClasses();
  400. wchar_t** t_clsB = m_JoinOnArray.GetBClasses();
  401. UINT* t_ops = m_JoinOnArray.GetOperators();
  402. wchar_t** t_prpsA = m_JoinOnArray.GetAProperties();
  403. wchar_t** t_prpsB = m_JoinOnArray.GetBProperties();
  404. VARIANT t_vA;
  405. VariantInit(&t_vA);
  406. CIMTYPE t_cA;
  407. POSITION t_pos = a_IndexArray.GetHeadPosition();
  408. while (t_pos && retVal)
  409. {
  410. int t_index = a_IndexArray.GetNext(t_pos);
  411. //get the propertyname in the view...
  412. int t_srcindxA = 0;
  413. int t_srcindxB = 0;
  414. if (m_ClassToIndexMap.Lookup(t_clsB[t_index], t_srcindxB) && m_ClassToIndexMap.Lookup(t_clsA[t_index], t_srcindxA))
  415. {
  416. //find t_prpsB[t_index] and get the view property name...
  417. POSITION t_propPos = m_PropertyMap.GetStartPosition();
  418. CStringW t_propName;
  419. while (t_propPos != NULL)
  420. {
  421. CPropertyQualifierItem *t_propProps;
  422. m_PropertyMap.GetNextAssoc(t_propPos, t_propName, t_propProps);
  423. if (!t_propProps->m_SrcPropertyNames[t_srcindxB].IsEmpty() &&
  424. !t_propProps->m_SrcPropertyNames[t_srcindxA].IsEmpty() &&
  425. (_wcsicmp(t_propProps->m_SrcPropertyNames[t_srcindxB], t_prpsB[t_index]) == 0) &&
  426. (_wcsicmp(t_propProps->m_SrcPropertyNames[t_srcindxA], t_prpsA[t_index]) == 0))
  427. {
  428. break;
  429. }
  430. else
  431. {
  432. t_propName.Empty();
  433. }
  434. }
  435. if (!t_propName.IsEmpty() && SUCCEEDED(a_Obj1->Get(t_prpsA[t_index], 0, &t_vA, &t_cA, NULL)) )
  436. {
  437. VARIANT t_vB;
  438. VariantInit(&t_vB);
  439. CIMTYPE t_cB;
  440. if ( SUCCEEDED(a_vObj->Get(t_propName, 0, &t_vB, &t_cB, NULL)) )
  441. {
  442. if (t_cA == t_cB)
  443. {
  444. if (t_ops[t_index] == CJoinOnQualifierArray::EQUALS_OPERATOR)
  445. {
  446. retVal = CompareSimplePropertyValues(&t_vA, &t_vB, t_cA);
  447. }
  448. else //NOT_EQUALS
  449. {
  450. retVal = !CompareSimplePropertyValues(&t_vA, &t_vB, t_cA);
  451. }
  452. }
  453. else
  454. {
  455. retVal = FALSE;
  456. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  457. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  458. a_ErrorObject.SetMessage ( L"Join properties have different CIM types." ) ;
  459. }
  460. }
  461. else
  462. {
  463. retVal = FALSE;
  464. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  465. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  466. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  467. }
  468. VariantClear(&t_vA);
  469. VariantClear(&t_vB);
  470. VariantInit(&t_vA);
  471. }
  472. else
  473. {
  474. retVal = FALSE;
  475. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  476. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  477. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  478. }
  479. }
  480. else
  481. {
  482. retVal = FALSE;
  483. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  484. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  485. a_ErrorObject.SetMessage ( L"Failed to find source property in view class." ) ;
  486. }
  487. }
  488. VariantClear(&t_vA);
  489. if (retVal)
  490. {
  491. //copy properties from sources to result
  492. POSITION t_propPos = m_PropertyMap.GetStartPosition();
  493. while ((t_propPos != NULL) && retVal)
  494. {
  495. CStringW t_propName;
  496. CPropertyQualifierItem *t_propProps;
  497. m_PropertyMap.GetNextAssoc(t_propPos, t_propName, t_propProps);
  498. if (!t_propProps->m_SrcPropertyNames[a_indx1].IsEmpty())
  499. {
  500. VARIANT t_v;
  501. VariantInit(&t_v);
  502. CIMTYPE t_c;
  503. if ( SUCCEEDED(a_Obj1->Get(t_propProps->m_SrcPropertyNames[a_indx1], 0, &t_v, &t_c, NULL)) )
  504. {
  505. if (((t_v.vt == VT_NULL) || (t_v.vt == VT_EMPTY)) && t_propProps->IsKey())
  506. {
  507. retVal = FALSE;
  508. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  509. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  510. a_ErrorObject.SetMessage ( L"View key value in source instance is NULL" );
  511. }
  512. else
  513. {
  514. if ( FAILED(a_resObj->Put(t_propName, 0, &t_v, t_c)) )
  515. {
  516. retVal = FALSE;
  517. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  518. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  519. a_ErrorObject.SetMessage ( L"Failed to put property" );
  520. }
  521. }
  522. VariantClear(&t_v);
  523. }
  524. else
  525. {
  526. retVal = FALSE;
  527. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  528. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  529. a_ErrorObject.SetMessage ( L"Failed to get property from Source." ) ;
  530. }
  531. }
  532. else
  533. {
  534. continue;
  535. }
  536. }
  537. }
  538. return retVal;
  539. }
  540. BOOL WbemTaskObject::JoinTwoItems(WbemProvErrorObject &a_ErrorObject,
  541. IWbemClassObject *a_Obj1, IWbemClassObject *a_Obj2,
  542. IWbemClassObject *a_resObj, CList <int, int> &a_IndexArray,
  543. DWORD a_indx1, DWORD a_indx2)
  544. {
  545. BOOL retVal = TRUE;
  546. wchar_t** t_clsA = m_JoinOnArray.GetAClasses();
  547. wchar_t** t_clsB = m_JoinOnArray.GetBClasses();
  548. UINT* t_ops = m_JoinOnArray.GetOperators();
  549. wchar_t** t_prpsA = m_JoinOnArray.GetAProperties();
  550. wchar_t** t_prpsB = m_JoinOnArray.GetBProperties();
  551. VARIANT t_vA;
  552. CIMTYPE t_cA;
  553. POSITION t_pos = a_IndexArray.GetHeadPosition();
  554. while (t_pos && retVal)
  555. {
  556. int t_index = a_IndexArray.GetNext(t_pos);
  557. if ( SUCCEEDED(a_Obj1->Get(t_prpsA[t_index], 0, &t_vA, &t_cA, NULL)) )
  558. {
  559. VARIANT t_vB;
  560. CIMTYPE t_cB;
  561. if ( SUCCEEDED(a_Obj2->Get(t_prpsB[t_index], 0, &t_vB, &t_cB, NULL)) )
  562. {
  563. if (t_cA == t_cB)
  564. {
  565. if (t_ops[t_index] == CJoinOnQualifierArray::EQUALS_OPERATOR)
  566. {
  567. retVal = CompareSimplePropertyValues(&t_vA, &t_vB, t_cA);
  568. }
  569. else //NOT_EQUALS
  570. {
  571. retVal = !CompareSimplePropertyValues(&t_vA, &t_vB, t_cA);
  572. }
  573. }
  574. else
  575. {
  576. retVal = FALSE;
  577. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  578. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  579. a_ErrorObject.SetMessage ( L"Join properties have different CIM types." ) ;
  580. }
  581. VariantClear(&t_vB);
  582. }
  583. else
  584. {
  585. retVal = FALSE;
  586. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  587. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  588. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  589. }
  590. VariantClear(&t_vA);
  591. }
  592. else
  593. {
  594. retVal = FALSE;
  595. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  596. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  597. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  598. }
  599. }
  600. if (retVal)
  601. {
  602. //copy properties from sources to result
  603. POSITION t_propPos = m_PropertyMap.GetStartPosition();
  604. while ((t_propPos != NULL) && retVal)
  605. {
  606. CStringW t_propName;
  607. CPropertyQualifierItem *t_propProps;
  608. m_PropertyMap.GetNextAssoc(t_propPos, t_propName, t_propProps);
  609. IWbemClassObject *t_src_Obj = NULL;
  610. DWORD t_index = 0;
  611. if (!t_propProps->m_SrcPropertyNames[a_indx1].IsEmpty())
  612. {
  613. t_src_Obj = a_Obj1;
  614. t_index = a_indx1;
  615. }
  616. else if (!t_propProps->m_SrcPropertyNames[a_indx2].IsEmpty())
  617. {
  618. t_src_Obj = a_Obj2;
  619. t_index = a_indx2;
  620. }
  621. else
  622. {
  623. continue;
  624. }
  625. VARIANT t_v;
  626. VariantInit(&t_v);
  627. CIMTYPE t_c;
  628. if ( SUCCEEDED(t_src_Obj->Get(t_propProps->m_SrcPropertyNames[t_index], 0, &t_v, &t_c, NULL)) )
  629. {
  630. if (((t_v.vt == VT_NULL) || (t_v.vt == VT_EMPTY)) && t_propProps->IsKey())
  631. {
  632. retVal = FALSE;
  633. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  634. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  635. a_ErrorObject.SetMessage ( L"View key value in source instance is NULL" );
  636. }
  637. else
  638. {
  639. if ( FAILED(a_resObj->Put(t_propName, 0, &t_v, t_c)) )
  640. {
  641. retVal = FALSE;
  642. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  643. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  644. a_ErrorObject.SetMessage ( L"Failed to put property" );
  645. }
  646. }
  647. VariantClear(&t_v);
  648. }
  649. else
  650. {
  651. retVal = FALSE;
  652. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  653. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  654. a_ErrorObject.SetMessage ( L"Failed to get property from Source." ) ;
  655. }
  656. }
  657. }
  658. return retVal;
  659. }
  660. BOOL WbemTaskObject::JoinTwoColumns(WbemProvErrorObject &a_ErrorObject,
  661. CMap<CStringW, LPCWSTR, int, int> &a_JoinedClasses,
  662. CList<IWbemClassObject*, IWbemClassObject*> &a_ResultObjs)
  663. {
  664. BOOL retVal = TRUE;
  665. wchar_t** t_clsA = m_JoinOnArray.GetAClasses();
  666. wchar_t** t_clsB = m_JoinOnArray.GetBClasses();
  667. wchar_t** t_prpsA = m_JoinOnArray.GetAProperties();
  668. wchar_t** t_prpsB = m_JoinOnArray.GetBProperties();
  669. UINT* t_ops = m_JoinOnArray.GetOperators();
  670. int t_indexA;
  671. int t_indexB;
  672. CList <int, int> t_IndexArray;
  673. t_IndexArray.AddTail(0);
  674. m_JoinOnArray.m_bDone[0] = TRUE;
  675. for (int x = 1; x < m_JoinOnArray.GetCount(); x++)
  676. {
  677. //find all clauses which can be evaluated now...
  678. if ((_wcsicmp(t_clsA[0], t_clsA[x]) == 0) && (_wcsicmp(t_clsB[0], t_clsB[x]) == 0))
  679. {
  680. t_IndexArray.AddTail(x);
  681. m_JoinOnArray.m_bDone[x] = TRUE;
  682. }
  683. else if ((_wcsicmp(t_clsB[0], t_clsA[x]) == 0) && (_wcsicmp(t_clsA[0], t_clsB[x]) == 0))
  684. {
  685. //want the clauses in the same order for simpler evaluation later...
  686. wchar_t *t_tmp = t_clsA[x];
  687. t_clsA[x] = t_clsB[x];
  688. t_clsB[x] = t_tmp;
  689. t_tmp = t_prpsA[x];
  690. t_prpsA[x] = t_prpsB[x];
  691. t_prpsB[x] = t_tmp;
  692. t_IndexArray.AddTail(x);
  693. m_JoinOnArray.m_bDone[x] = TRUE;
  694. }
  695. }
  696. a_JoinedClasses.SetAt(t_clsA[0], 0);
  697. a_JoinedClasses.SetAt(t_clsB[0], 0);
  698. m_ClassToIndexMap.Lookup(t_clsA[0], t_indexA);
  699. m_ClassToIndexMap.Lookup(t_clsB[0], t_indexB);
  700. for (int i = 0; retVal && (i < m_ObjSinkArray[t_indexA]->m_ObjArray.GetSize()); i++)
  701. {
  702. if (m_ObjSinkArray[t_indexA]->m_ObjArray[i])
  703. {
  704. for (int j = 0; retVal && (j < m_ObjSinkArray[t_indexB]->m_ObjArray.GetSize()); j++)
  705. {
  706. if (m_ObjSinkArray[t_indexB]->m_ObjArray[j])
  707. {
  708. IWbemClassObject* t_viewObj = NULL;
  709. if ( SUCCEEDED(m_ClassObject->SpawnInstance(0, &t_viewObj)) )
  710. {
  711. if (JoinTwoItems(a_ErrorObject, m_ObjSinkArray[t_indexA]->m_ObjArray[i]->GetWrappedObject(),
  712. m_ObjSinkArray[t_indexB]->m_ObjArray[j]->GetWrappedObject(),
  713. t_viewObj, t_IndexArray, t_indexA, t_indexB))
  714. {
  715. a_ResultObjs.AddTail(t_viewObj);
  716. }
  717. else
  718. {
  719. t_viewObj->Release();
  720. }
  721. }
  722. else
  723. {
  724. retVal = FALSE;
  725. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  726. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  727. a_ErrorObject.SetMessage ( L"An error occured when spawning an instance of the view class." );
  728. }
  729. }
  730. }
  731. m_ObjSinkArray[t_indexA]->m_ObjArray[i]->Release();
  732. m_ObjSinkArray[t_indexA]->m_ObjArray[i] = NULL;
  733. }
  734. }
  735. m_ObjSinkArray[t_indexB]->m_ObjArray.RemoveAll();
  736. return retVal;
  737. }
  738. BOOL WbemTaskObject::AddColumnToJoin(WbemProvErrorObject &a_ErrorObject,
  739. CMap<CStringW, LPCWSTR, int, int> &a_JoinedClasses,
  740. CList<IWbemClassObject*, IWbemClassObject*> &a_ResultObjs,
  741. DWORD a_Index, CList <int, int> &a_IndexArray)
  742. {
  743. BOOL retVal = TRUE;
  744. CList<IWbemClassObject*, IWbemClassObject*> t_AddedResultObjs;
  745. for (int i = 0; retVal && (i < m_ObjSinkArray[a_Index]->m_ObjArray.GetSize()); i++)
  746. {
  747. if (m_ObjSinkArray[a_Index]->m_ObjArray[i])
  748. {
  749. POSITION t_pos = a_ResultObjs.GetHeadPosition();
  750. while (retVal && t_pos)
  751. {
  752. IWbemClassObject *t_vSrc = a_ResultObjs.GetNext(t_pos);
  753. if (t_vSrc)
  754. {
  755. IWbemClassObject* t_viewObj = NULL;
  756. if ( SUCCEEDED(t_vSrc->Clone(&t_viewObj)) )
  757. {
  758. if (JoinItem(a_ErrorObject, m_ObjSinkArray[a_Index]->m_ObjArray[i]->GetWrappedObject(),
  759. t_vSrc, t_viewObj, a_IndexArray, a_Index))
  760. {
  761. t_AddedResultObjs.AddTail(t_viewObj);
  762. }
  763. else
  764. {
  765. t_viewObj->Release();
  766. }
  767. }
  768. else
  769. {
  770. retVal = FALSE;
  771. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  772. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  773. a_ErrorObject.SetMessage ( L"An error occured when spawning an instance of the view class." );
  774. }
  775. }
  776. }
  777. m_ObjSinkArray[a_Index]->m_ObjArray[i]->Release();
  778. m_ObjSinkArray[a_Index]->m_ObjArray[i] = NULL;
  779. }
  780. }
  781. //don't need partial join any longer
  782. a_ResultObjs.RemoveAll();
  783. //copy the new result set to the result list
  784. //filter if this is the last time here...
  785. if (retVal)
  786. {
  787. POSITION t_pos = t_AddedResultObjs.GetHeadPosition();
  788. while (t_pos)
  789. {
  790. IWbemClassObject *t_vobj = a_ResultObjs.GetNext(t_pos);
  791. if (t_vobj)
  792. {
  793. t_vobj->AddRef();
  794. a_ResultObjs.AddTail(t_vobj);
  795. }
  796. }
  797. }
  798. t_AddedResultObjs.RemoveAll();
  799. return retVal;
  800. }
  801. #else //VP_PERFORMANT_JOINS
  802. BOOL WbemTaskObject::CreateAndIndicateJoins(WbemProvErrorObject &a_ErrorObject, BOOL a_bSingle)
  803. {
  804. BOOL retVal = TRUE;
  805. UINT isize = 1;
  806. if (m_ObjSinkArray.GetSize() != m_SourceArray.GetSize())
  807. {
  808. retVal = FALSE;
  809. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  810. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  811. a_ErrorObject.SetMessage ( L"A source query failed or was not executed therefore a join could not be created." );
  812. }
  813. //calculate the size of the results
  814. for (UINT x = 0; x < m_ObjSinkArray.GetSize(); x++)
  815. {
  816. if ((m_ObjSinkArray[x] == NULL) || FAILED(m_ObjSinkArray[x]->GetResult()) || !m_ObjSinkArray[x]->m_ObjArray.GetSize())
  817. {
  818. retVal = FALSE;
  819. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  820. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  821. a_ErrorObject.SetMessage ( L"A source query failed or returned no instances." );
  822. break;
  823. }
  824. if ((0xFFFFFFFF/isize) >= m_ObjSinkArray[x]->m_ObjArray.GetSize())
  825. {
  826. isize = isize * m_ObjSinkArray[x]->m_ObjArray.GetSize();
  827. }
  828. else
  829. {
  830. retVal = FALSE;
  831. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  832. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  833. a_ErrorObject.SetMessage ( L"Too many possible combinations for join. Provider not capable." );
  834. }
  835. }
  836. if (retVal)
  837. {
  838. IWbemClassObject** objs = new IWbemClassObject*[m_ObjSinkArray.GetSize()];
  839. IWbemClassObject* res_obj = NULL;
  840. int num_res_objs = 0;
  841. for (UINT i = 0; i < isize; i++)
  842. {
  843. UINT t_iDenom = 1;
  844. for (x = 0; x < m_ObjSinkArray.GetSize(); x++)
  845. {
  846. UINT isz = m_ObjSinkArray[x]->m_ObjArray.GetSize();
  847. objs[x] = m_ObjSinkArray[x]->m_ObjArray[(i/t_iDenom) % isz];
  848. t_iDenom = t_iDenom * isz;
  849. }
  850. BOOL t_bRes = CreateAndIndicate(a_ErrorObject, objs, &res_obj);
  851. retVal = retVal && t_bRes;
  852. if (res_obj != NULL)
  853. {
  854. num_res_objs++;
  855. if (a_bSingle)
  856. {
  857. if (num_res_objs > 1)
  858. {
  859. res_obj->Release();
  860. retVal = FALSE;
  861. a_ErrorObject.SetStatus ( WBEM_PROV_E_TOOMANYRESULTSRETURNED ) ;
  862. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  863. a_ErrorObject.SetMessage ( L"Too many view instances can be created." ) ;
  864. break;
  865. }
  866. }
  867. else
  868. {
  869. if (m_bIndicate)
  870. {
  871. m_NotificationHandler->Indicate(1, &res_obj);
  872. res_obj->Release();
  873. res_obj = NULL;
  874. }
  875. }
  876. }
  877. }
  878. if (a_bSingle)
  879. {
  880. if (num_res_objs == 1)
  881. {
  882. if (m_bIndicate)
  883. {
  884. m_NotificationHandler->Indicate(1, &res_obj);
  885. }
  886. res_obj->Release();
  887. }
  888. }
  889. delete [] objs;
  890. }
  891. for (x = 0; x < m_ObjSinkArray.GetSize(); x++)
  892. {
  893. if (m_ObjSinkArray[x] != NULL)
  894. {
  895. m_ObjSinkArray[x]->Release();
  896. }
  897. }
  898. m_ObjSinkArray.RemoveAll();
  899. return retVal;
  900. }
  901. //for joins
  902. BOOL WbemTaskObject::CreateAndIndicate(WbemProvErrorObject &a_ErrorObject, IWbemClassObject ** pSrcs, IWbemClassObject **pOut)
  903. {
  904. BOOL retVal = TRUE;
  905. wchar_t** clsA = m_JoinOnArray.GetAClasses();
  906. wchar_t** clsB = m_JoinOnArray.GetBClasses();
  907. wchar_t** prpsA = m_JoinOnArray.GetAProperties();
  908. wchar_t** prpsB = m_JoinOnArray.GetBProperties();
  909. UINT* ops = m_JoinOnArray.GetOperators();
  910. for (int x = 0; retVal && (x < m_JoinOnArray.GetCount()); x++)
  911. {
  912. int iA;
  913. int iB;
  914. m_ClassToIndexMap.Lookup(clsA[x], iA);
  915. m_ClassToIndexMap.Lookup(clsB[x], iB);
  916. VARIANT vA;
  917. CIMTYPE cA;
  918. if ( SUCCEEDED(pSrcs[iA]->Get(prpsA[x], 0, &vA, &cA, NULL)) )
  919. {
  920. VARIANT vB;
  921. CIMTYPE cB;
  922. if ( SUCCEEDED(pSrcs[iB]->Get(prpsB[x], 0, &vB, &cB, NULL)) )
  923. {
  924. if (cA == cB)
  925. {
  926. if (ops[x] == CJoinOnQualifierArray::EQUALS_OPERATOR)
  927. {
  928. retVal = CompareSimplePropertyValues(&vA, &vB, cA);
  929. }
  930. else //NOT_EQUALS
  931. {
  932. retVal = !CompareSimplePropertyValues(&vA, &vB, cA);
  933. }
  934. }
  935. else
  936. {
  937. retVal = FALSE;
  938. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  939. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  940. a_ErrorObject.SetMessage ( L"Join properties have different CIM types." ) ;
  941. }
  942. VariantClear(&vB);
  943. }
  944. else
  945. {
  946. retVal = FALSE;
  947. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  948. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  949. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  950. }
  951. VariantClear(&vA);
  952. }
  953. else
  954. {
  955. retVal = FALSE;
  956. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  957. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  958. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  959. }
  960. }
  961. if (retVal)
  962. {
  963. BOOL bIndicate = TRUE;
  964. IWbemClassObject* viewObj = NULL;
  965. if ( SUCCEEDED(m_ClassObject->SpawnInstance(0, &viewObj)) )
  966. {
  967. POSITION propPos = m_PropertyMap.GetStartPosition();
  968. while ((propPos != NULL) && bIndicate)
  969. {
  970. CStringW propName;
  971. CPropertyQualifierItem* propProps;
  972. m_PropertyMap.GetNextAssoc(propPos, propName, propProps);
  973. VARIANT v;
  974. BOOL bSetProp = FALSE;
  975. CIMTYPE c;
  976. for (int x = 0; !bSetProp && (x < propProps->m_SrcPropertyNames.GetSize()); x++)
  977. {
  978. if (!propProps->m_SrcPropertyNames[x].IsEmpty())
  979. {
  980. bSetProp = TRUE;
  981. if ( SUCCEEDED(pSrcs[x]->Get(propProps->m_SrcPropertyNames[x], 0, &v, &c, NULL)) )
  982. {
  983. if (((v.vt == VT_NULL) || (v.vt == VT_EMPTY)) && propProps->IsKey())
  984. {
  985. if (retVal)
  986. {
  987. retVal = FALSE;
  988. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  989. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  990. a_ErrorObject.SetMessage ( L"View key value in source instance is NULL" );
  991. }
  992. bIndicate = FALSE;
  993. }
  994. else
  995. {
  996. if ( FAILED(viewObj->Put(propName, 0, &v, c)) )
  997. {
  998. if (retVal)
  999. {
  1000. retVal = FALSE;
  1001. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  1002. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  1003. a_ErrorObject.SetMessage ( L"Failed to put property" );
  1004. }
  1005. if (propProps->IsKey())
  1006. {
  1007. bIndicate = FALSE;
  1008. }
  1009. }
  1010. }
  1011. VariantClear(&v);
  1012. }
  1013. else
  1014. {
  1015. if (retVal)
  1016. {
  1017. retVal = FALSE;
  1018. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  1019. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  1020. a_ErrorObject.SetMessage ( L"Failed to get property from Source." ) ;
  1021. }
  1022. }
  1023. }
  1024. }
  1025. }
  1026. if (bIndicate)
  1027. {
  1028. retVal = PostFilter(viewObj);
  1029. if (retVal)
  1030. {
  1031. viewObj->AddRef();
  1032. *pOut = viewObj;
  1033. }
  1034. }
  1035. viewObj->Release();
  1036. }
  1037. else
  1038. {
  1039. retVal = FALSE;
  1040. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  1041. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  1042. a_ErrorObject.SetMessage ( L"WBEM API FAILURE:- Failed to spawn an instance of the view class." ) ;
  1043. }
  1044. }
  1045. return retVal;
  1046. }
  1047. #endif //VP_PERFORMANT_JOINS
  1048. BOOL WbemTaskObject::PostFilter(IWbemClassObject* a_pObj)
  1049. {
  1050. BOOL retVal = TRUE;
  1051. if ( (m_RPNPostFilter != NULL) && (m_RPNPostFilter->nNumTokens != 0) )
  1052. {
  1053. BOOL* t_bStack = new BOOL[m_RPNPostFilter->nNumTokens];
  1054. DWORD t_bCnt = 0;
  1055. for (int i = 0; retVal && (i < m_RPNPostFilter->nNumTokens); i++)
  1056. {
  1057. switch (m_RPNPostFilter->pArrayOfTokens[i].nTokenType)
  1058. {
  1059. case SQL_LEVEL_1_TOKEN::OP_EXPRESSION:
  1060. {
  1061. t_bStack[t_bCnt] = EvaluateToken(a_pObj, m_RPNPostFilter->pArrayOfTokens[i]);
  1062. t_bCnt++;
  1063. }
  1064. break;
  1065. case SQL_LEVEL_1_TOKEN::TOKEN_AND:
  1066. {
  1067. if (t_bCnt > 1)
  1068. {
  1069. t_bStack[t_bCnt - 2] = t_bStack[t_bCnt - 1] && t_bStack[t_bCnt - 2];
  1070. t_bCnt--;
  1071. }
  1072. else
  1073. {
  1074. retVal = FALSE;
  1075. }
  1076. }
  1077. break;
  1078. case SQL_LEVEL_1_TOKEN::TOKEN_OR:
  1079. {
  1080. if (t_bCnt > 1)
  1081. {
  1082. t_bStack[t_bCnt - 2] = t_bStack[t_bCnt - 1] || t_bStack[t_bCnt - 2];
  1083. t_bCnt--;
  1084. }
  1085. else
  1086. {
  1087. retVal = FALSE;
  1088. }
  1089. }
  1090. break;
  1091. case SQL_LEVEL_1_TOKEN::TOKEN_NOT:
  1092. {
  1093. if (t_bCnt > 0)
  1094. {
  1095. t_bStack[t_bCnt - 1] = !t_bStack[t_bCnt - 1];
  1096. }
  1097. }
  1098. break;
  1099. default:
  1100. {
  1101. }
  1102. break;
  1103. }
  1104. }
  1105. if (retVal)
  1106. {
  1107. retVal = t_bStack[t_bCnt - 1];
  1108. }
  1109. delete [] t_bStack;
  1110. }
  1111. return retVal;
  1112. }