Leaked source code of windows server 2003
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.

1288 lines
32 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. if ( FAILED ( m_ObjSinkArray[x]->GetResult() ) )
  249. {
  250. a_ErrorObject.SetWbemStatus ( ( WBEMSTATUS ) m_ObjSinkArray[x]->GetResult() ) ;
  251. }
  252. else
  253. {
  254. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  255. }
  256. a_ErrorObject.SetMessage ( L"A source query failed or returned no instances." );
  257. }
  258. retVal = FALSE;
  259. break;
  260. }
  261. }
  262. //perform the join of all results...
  263. if (retVal)
  264. {
  265. CMap<CStringW, LPCWSTR, int, int> t_JoinedClasses;
  266. CList<IWbemClassObject*, IWbemClassObject*> t_ResultObjs;
  267. retVal = JoinTwoColumns(a_ErrorObject, t_JoinedClasses, t_ResultObjs);
  268. wchar_t** t_clsA = m_JoinOnArray.GetAClasses();
  269. wchar_t** t_clsB = m_JoinOnArray.GetBClasses();
  270. wchar_t** t_prpsA = m_JoinOnArray.GetAProperties();
  271. wchar_t** t_prpsB = m_JoinOnArray.GetBProperties();
  272. while ( retVal && (t_JoinedClasses.GetCount() != m_SourceArray.GetSize()) )
  273. {
  274. DWORD t_column = m_SourceArray.GetSize() + 1;
  275. CList <int, int> t_IndexArray;
  276. wchar_t *t_classname = NULL;
  277. //find a column not already joined that can be joined now...
  278. for (x = 0; x < m_JoinOnArray.GetCount(); x++)
  279. {
  280. if (!m_JoinOnArray.m_bDone[x])
  281. {
  282. int dummyInt = 0;
  283. if (t_classname == NULL)
  284. {
  285. if (t_JoinedClasses.Lookup(t_clsA[x], dummyInt))
  286. {
  287. if (!m_ClassToIndexMap.Lookup(t_clsB[x], (int &)t_column))
  288. {
  289. retVal = FALSE;
  290. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  291. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  292. a_ErrorObject.SetMessage ( L"An unexpected error ocurred performing the join." );
  293. }
  294. t_classname = t_clsB[x];
  295. t_JoinedClasses.SetAt(t_classname, 0);
  296. m_JoinOnArray.m_bDone[x] = TRUE;
  297. t_IndexArray.AddTail(x);
  298. //want all clauses the same way around...
  299. t_clsB[x] = t_clsA[x];
  300. t_clsA[x] = t_classname;
  301. wchar_t *t_tmpStr = t_prpsA[x];
  302. t_prpsA[x] = t_prpsB[x];
  303. t_prpsB[x] = t_tmpStr;
  304. }
  305. else if (t_JoinedClasses.Lookup(t_clsB[x], dummyInt))
  306. {
  307. if (!m_ClassToIndexMap.Lookup(t_clsA[x], (int &)t_column))
  308. {
  309. retVal = FALSE;
  310. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  311. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  312. a_ErrorObject.SetMessage ( L"An unexpected error ocurred performing the join." );
  313. }
  314. t_classname = t_clsA[x];
  315. t_JoinedClasses.SetAt(t_classname, 0);
  316. m_JoinOnArray.m_bDone[x] = TRUE;
  317. t_IndexArray.AddTail(x);
  318. }
  319. }
  320. else
  321. {
  322. //find all clauses which can be evaluated now...
  323. if ((_wcsicmp(t_classname, t_clsA[x]) == 0) && (t_JoinedClasses.Lookup(t_clsB[x], dummyInt)))
  324. {
  325. t_IndexArray.AddTail(x);
  326. m_JoinOnArray.m_bDone[x] = TRUE;
  327. }
  328. else if ((_wcsicmp(t_classname, t_clsB[x]) == 0) && (t_JoinedClasses.Lookup(t_clsA[x], dummyInt)))
  329. {
  330. //want the clauses in the same order for simpler evaluation later...
  331. wchar_t *t_tmpStr = t_clsA[x];
  332. t_clsA[x] = t_clsB[x];
  333. t_clsB[x] = t_tmpStr;
  334. t_tmpStr = t_prpsA[x];
  335. t_prpsA[x] = t_prpsB[x];
  336. t_prpsB[x] = t_tmpStr;
  337. t_IndexArray.AddTail(x);
  338. m_JoinOnArray.m_bDone[x] = TRUE;
  339. }
  340. }
  341. }
  342. }
  343. if (t_column == m_SourceArray.GetSize() + 1)
  344. {
  345. retVal = FALSE;
  346. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  347. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  348. a_ErrorObject.SetMessage ( L"Failed to perform join." );
  349. }
  350. else
  351. {
  352. retVal = AddColumnToJoin(a_ErrorObject, t_JoinedClasses, t_ResultObjs, t_column, t_IndexArray);
  353. t_IndexArray.RemoveAll();
  354. }
  355. }
  356. if (retVal)
  357. {
  358. if (m_bIndicate)
  359. {
  360. POSITION t_pos = t_ResultObjs.GetHeadPosition();
  361. BOOL t_bIndicated = FALSE;
  362. while (t_pos)
  363. {
  364. IWbemClassObject *t_Obj = t_ResultObjs.GetNext(t_pos);
  365. if (t_Obj)
  366. {
  367. if (PostFilter(t_Obj))
  368. {
  369. if (a_bSingle && t_bIndicated)
  370. {
  371. retVal = FALSE;
  372. a_ErrorObject.SetStatus ( WBEM_PROV_E_TOOMANYRESULTSRETURNED ) ;
  373. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  374. a_ErrorObject.SetMessage ( L"Too many view instances can be created." ) ;
  375. break;
  376. }
  377. else
  378. {
  379. m_NotificationHandler->Indicate(1, &t_Obj);
  380. t_bIndicated = TRUE;
  381. }
  382. }
  383. }
  384. }
  385. }
  386. }
  387. t_ResultObjs.RemoveAll();
  388. }
  389. //clean up...
  390. for (x = 0; x < m_ObjSinkArray.GetSize(); x++)
  391. {
  392. if (m_ObjSinkArray[x] != NULL)
  393. {
  394. m_ObjSinkArray[x]->Release();
  395. }
  396. }
  397. m_ObjSinkArray.RemoveAll();
  398. return retVal;
  399. }
  400. BOOL WbemTaskObject::JoinItem(WbemProvErrorObject &a_ErrorObject,
  401. IWbemClassObject *a_Obj1, IWbemClassObject *a_vObj,
  402. IWbemClassObject *a_resObj, CList <int, int> &a_IndexArray,
  403. DWORD a_indx1)
  404. {
  405. BOOL retVal = TRUE;
  406. wchar_t** t_clsA = m_JoinOnArray.GetAClasses();
  407. wchar_t** t_clsB = m_JoinOnArray.GetBClasses();
  408. UINT* t_ops = m_JoinOnArray.GetOperators();
  409. wchar_t** t_prpsA = m_JoinOnArray.GetAProperties();
  410. wchar_t** t_prpsB = m_JoinOnArray.GetBProperties();
  411. VARIANT t_vA;
  412. VariantInit(&t_vA);
  413. CIMTYPE t_cA;
  414. POSITION t_pos = a_IndexArray.GetHeadPosition();
  415. while (t_pos && retVal)
  416. {
  417. int t_index = a_IndexArray.GetNext(t_pos);
  418. //get the propertyname in the view...
  419. int t_srcindxA = 0;
  420. int t_srcindxB = 0;
  421. if (m_ClassToIndexMap.Lookup(t_clsB[t_index], t_srcindxB) && m_ClassToIndexMap.Lookup(t_clsA[t_index], t_srcindxA))
  422. {
  423. //find t_prpsB[t_index] and get the view property name...
  424. POSITION t_propPos = m_PropertyMap.GetStartPosition();
  425. CStringW t_propName;
  426. while (t_propPos != NULL)
  427. {
  428. CPropertyQualifierItem *t_propProps;
  429. m_PropertyMap.GetNextAssoc(t_propPos, t_propName, t_propProps);
  430. if (!t_propProps->m_SrcPropertyNames[t_srcindxB].IsEmpty() &&
  431. !t_propProps->m_SrcPropertyNames[t_srcindxA].IsEmpty() &&
  432. (_wcsicmp(t_propProps->m_SrcPropertyNames[t_srcindxB], t_prpsB[t_index]) == 0) &&
  433. (_wcsicmp(t_propProps->m_SrcPropertyNames[t_srcindxA], t_prpsA[t_index]) == 0))
  434. {
  435. break;
  436. }
  437. else
  438. {
  439. t_propName.Empty();
  440. }
  441. }
  442. if (!t_propName.IsEmpty() && SUCCEEDED(a_Obj1->Get(t_prpsA[t_index], 0, &t_vA, &t_cA, NULL)) )
  443. {
  444. VARIANT t_vB;
  445. VariantInit(&t_vB);
  446. CIMTYPE t_cB;
  447. if ( SUCCEEDED(a_vObj->Get(t_propName, 0, &t_vB, &t_cB, NULL)) )
  448. {
  449. if (t_cA == t_cB)
  450. {
  451. if (t_ops[t_index] == CJoinOnQualifierArray::EQUALS_OPERATOR)
  452. {
  453. retVal = CompareSimplePropertyValues(&t_vA, &t_vB, t_cA);
  454. }
  455. else //NOT_EQUALS
  456. {
  457. retVal = !CompareSimplePropertyValues(&t_vA, &t_vB, t_cA);
  458. }
  459. }
  460. else
  461. {
  462. retVal = FALSE;
  463. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  464. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  465. a_ErrorObject.SetMessage ( L"Join properties have different CIM types." ) ;
  466. }
  467. }
  468. else
  469. {
  470. retVal = FALSE;
  471. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  472. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  473. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  474. }
  475. VariantClear(&t_vA);
  476. VariantClear(&t_vB);
  477. VariantInit(&t_vA);
  478. }
  479. else
  480. {
  481. retVal = FALSE;
  482. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  483. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  484. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  485. }
  486. }
  487. else
  488. {
  489. retVal = FALSE;
  490. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  491. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  492. a_ErrorObject.SetMessage ( L"Failed to find source property in view class." ) ;
  493. }
  494. }
  495. VariantClear(&t_vA);
  496. if (retVal)
  497. {
  498. //copy properties from sources to result
  499. POSITION t_propPos = m_PropertyMap.GetStartPosition();
  500. while ((t_propPos != NULL) && retVal)
  501. {
  502. CStringW t_propName;
  503. CPropertyQualifierItem *t_propProps;
  504. m_PropertyMap.GetNextAssoc(t_propPos, t_propName, t_propProps);
  505. if (!t_propProps->m_SrcPropertyNames[a_indx1].IsEmpty())
  506. {
  507. VARIANT t_v;
  508. VariantInit(&t_v);
  509. CIMTYPE t_c;
  510. if ( SUCCEEDED(a_Obj1->Get(t_propProps->m_SrcPropertyNames[a_indx1], 0, &t_v, &t_c, NULL)) )
  511. {
  512. if (((t_v.vt == VT_NULL) || (t_v.vt == VT_EMPTY)) && t_propProps->IsKey())
  513. {
  514. retVal = FALSE;
  515. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  516. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  517. a_ErrorObject.SetMessage ( L"View key value in source instance is NULL" );
  518. }
  519. else
  520. {
  521. if ( FAILED(a_resObj->Put(t_propName, 0, &t_v, t_c)) )
  522. {
  523. retVal = FALSE;
  524. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  525. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  526. a_ErrorObject.SetMessage ( L"Failed to put property" );
  527. }
  528. }
  529. VariantClear(&t_v);
  530. }
  531. else
  532. {
  533. retVal = FALSE;
  534. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  535. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  536. a_ErrorObject.SetMessage ( L"Failed to get property from Source." ) ;
  537. }
  538. }
  539. else
  540. {
  541. continue;
  542. }
  543. }
  544. }
  545. return retVal;
  546. }
  547. BOOL WbemTaskObject::JoinTwoItems(WbemProvErrorObject &a_ErrorObject,
  548. IWbemClassObject *a_Obj1, IWbemClassObject *a_Obj2,
  549. IWbemClassObject *a_resObj, CList <int, int> &a_IndexArray,
  550. DWORD a_indx1, DWORD a_indx2)
  551. {
  552. BOOL retVal = TRUE;
  553. wchar_t** t_clsA = m_JoinOnArray.GetAClasses();
  554. wchar_t** t_clsB = m_JoinOnArray.GetBClasses();
  555. UINT* t_ops = m_JoinOnArray.GetOperators();
  556. wchar_t** t_prpsA = m_JoinOnArray.GetAProperties();
  557. wchar_t** t_prpsB = m_JoinOnArray.GetBProperties();
  558. VARIANT t_vA;
  559. CIMTYPE t_cA;
  560. POSITION t_pos = a_IndexArray.GetHeadPosition();
  561. while (t_pos && retVal)
  562. {
  563. int t_index = a_IndexArray.GetNext(t_pos);
  564. if ( SUCCEEDED(a_Obj1->Get(t_prpsA[t_index], 0, &t_vA, &t_cA, NULL)) )
  565. {
  566. VARIANT t_vB;
  567. CIMTYPE t_cB;
  568. if ( SUCCEEDED(a_Obj2->Get(t_prpsB[t_index], 0, &t_vB, &t_cB, NULL)) )
  569. {
  570. if (t_cA == t_cB)
  571. {
  572. if (t_ops[t_index] == CJoinOnQualifierArray::EQUALS_OPERATOR)
  573. {
  574. retVal = CompareSimplePropertyValues(&t_vA, &t_vB, t_cA);
  575. }
  576. else //NOT_EQUALS
  577. {
  578. retVal = !CompareSimplePropertyValues(&t_vA, &t_vB, t_cA);
  579. }
  580. }
  581. else
  582. {
  583. retVal = FALSE;
  584. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  585. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  586. a_ErrorObject.SetMessage ( L"Join properties have different CIM types." ) ;
  587. }
  588. VariantClear(&t_vB);
  589. }
  590. else
  591. {
  592. retVal = FALSE;
  593. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  594. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  595. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  596. }
  597. VariantClear(&t_vA);
  598. }
  599. else
  600. {
  601. retVal = FALSE;
  602. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  603. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  604. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  605. }
  606. }
  607. if (retVal)
  608. {
  609. //copy properties from sources to result
  610. POSITION t_propPos = m_PropertyMap.GetStartPosition();
  611. while ((t_propPos != NULL) && retVal)
  612. {
  613. CStringW t_propName;
  614. CPropertyQualifierItem *t_propProps;
  615. m_PropertyMap.GetNextAssoc(t_propPos, t_propName, t_propProps);
  616. IWbemClassObject *t_src_Obj = NULL;
  617. DWORD t_index = 0;
  618. if (!t_propProps->m_SrcPropertyNames[a_indx1].IsEmpty())
  619. {
  620. t_src_Obj = a_Obj1;
  621. t_index = a_indx1;
  622. }
  623. else if (!t_propProps->m_SrcPropertyNames[a_indx2].IsEmpty())
  624. {
  625. t_src_Obj = a_Obj2;
  626. t_index = a_indx2;
  627. }
  628. else
  629. {
  630. continue;
  631. }
  632. VARIANT t_v;
  633. VariantInit(&t_v);
  634. CIMTYPE t_c;
  635. if ( SUCCEEDED(t_src_Obj->Get(t_propProps->m_SrcPropertyNames[t_index], 0, &t_v, &t_c, NULL)) )
  636. {
  637. if (((t_v.vt == VT_NULL) || (t_v.vt == VT_EMPTY)) && t_propProps->IsKey())
  638. {
  639. retVal = FALSE;
  640. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  641. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  642. a_ErrorObject.SetMessage ( L"View key value in source instance is NULL" );
  643. }
  644. else
  645. {
  646. if ( FAILED(a_resObj->Put(t_propName, 0, &t_v, t_c)) )
  647. {
  648. retVal = FALSE;
  649. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  650. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  651. a_ErrorObject.SetMessage ( L"Failed to put property" );
  652. }
  653. }
  654. VariantClear(&t_v);
  655. }
  656. else
  657. {
  658. retVal = FALSE;
  659. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  660. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  661. a_ErrorObject.SetMessage ( L"Failed to get property from Source." ) ;
  662. }
  663. }
  664. }
  665. return retVal;
  666. }
  667. BOOL WbemTaskObject::JoinTwoColumns(WbemProvErrorObject &a_ErrorObject,
  668. CMap<CStringW, LPCWSTR, int, int> &a_JoinedClasses,
  669. CList<IWbemClassObject*, IWbemClassObject*> &a_ResultObjs)
  670. {
  671. BOOL retVal = TRUE;
  672. wchar_t** t_clsA = m_JoinOnArray.GetAClasses();
  673. wchar_t** t_clsB = m_JoinOnArray.GetBClasses();
  674. wchar_t** t_prpsA = m_JoinOnArray.GetAProperties();
  675. wchar_t** t_prpsB = m_JoinOnArray.GetBProperties();
  676. UINT* t_ops = m_JoinOnArray.GetOperators();
  677. int t_indexA;
  678. int t_indexB;
  679. CList <int, int> t_IndexArray;
  680. t_IndexArray.AddTail(0);
  681. m_JoinOnArray.m_bDone[0] = TRUE;
  682. for (int x = 1; x < m_JoinOnArray.GetCount(); x++)
  683. {
  684. //find all clauses which can be evaluated now...
  685. if ((_wcsicmp(t_clsA[0], t_clsA[x]) == 0) && (_wcsicmp(t_clsB[0], t_clsB[x]) == 0))
  686. {
  687. t_IndexArray.AddTail(x);
  688. m_JoinOnArray.m_bDone[x] = TRUE;
  689. }
  690. else if ((_wcsicmp(t_clsB[0], t_clsA[x]) == 0) && (_wcsicmp(t_clsA[0], t_clsB[x]) == 0))
  691. {
  692. //want the clauses in the same order for simpler evaluation later...
  693. wchar_t *t_tmp = t_clsA[x];
  694. t_clsA[x] = t_clsB[x];
  695. t_clsB[x] = t_tmp;
  696. t_tmp = t_prpsA[x];
  697. t_prpsA[x] = t_prpsB[x];
  698. t_prpsB[x] = t_tmp;
  699. t_IndexArray.AddTail(x);
  700. m_JoinOnArray.m_bDone[x] = TRUE;
  701. }
  702. }
  703. a_JoinedClasses.SetAt(t_clsA[0], 0);
  704. a_JoinedClasses.SetAt(t_clsB[0], 0);
  705. m_ClassToIndexMap.Lookup(t_clsA[0], t_indexA);
  706. m_ClassToIndexMap.Lookup(t_clsB[0], t_indexB);
  707. for (int i = 0; retVal && (i < m_ObjSinkArray[t_indexA]->m_ObjArray.GetSize()); i++)
  708. {
  709. if (m_ObjSinkArray[t_indexA]->m_ObjArray[i])
  710. {
  711. for (int j = 0; retVal && (j < m_ObjSinkArray[t_indexB]->m_ObjArray.GetSize()); j++)
  712. {
  713. if (m_ObjSinkArray[t_indexB]->m_ObjArray[j])
  714. {
  715. IWbemClassObject* t_viewObj = NULL;
  716. if ( SUCCEEDED(m_ClassObject->SpawnInstance(0, &t_viewObj)) )
  717. {
  718. if (JoinTwoItems(a_ErrorObject, m_ObjSinkArray[t_indexA]->m_ObjArray[i]->GetWrappedObject(),
  719. m_ObjSinkArray[t_indexB]->m_ObjArray[j]->GetWrappedObject(),
  720. t_viewObj, t_IndexArray, t_indexA, t_indexB))
  721. {
  722. a_ResultObjs.AddTail(t_viewObj);
  723. }
  724. else
  725. {
  726. t_viewObj->Release();
  727. }
  728. }
  729. else
  730. {
  731. retVal = FALSE;
  732. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  733. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  734. a_ErrorObject.SetMessage ( L"An error occured when spawning an instance of the view class." );
  735. }
  736. }
  737. }
  738. m_ObjSinkArray[t_indexA]->m_ObjArray[i]->Release();
  739. m_ObjSinkArray[t_indexA]->m_ObjArray[i] = NULL;
  740. }
  741. }
  742. m_ObjSinkArray[t_indexB]->m_ObjArray.RemoveAll();
  743. return retVal;
  744. }
  745. BOOL WbemTaskObject::AddColumnToJoin(WbemProvErrorObject &a_ErrorObject,
  746. CMap<CStringW, LPCWSTR, int, int> &a_JoinedClasses,
  747. CList<IWbemClassObject*, IWbemClassObject*> &a_ResultObjs,
  748. DWORD a_Index, CList <int, int> &a_IndexArray)
  749. {
  750. BOOL retVal = TRUE;
  751. CList<IWbemClassObject*, IWbemClassObject*> t_AddedResultObjs;
  752. for (int i = 0; retVal && (i < m_ObjSinkArray[a_Index]->m_ObjArray.GetSize()); i++)
  753. {
  754. if (m_ObjSinkArray[a_Index]->m_ObjArray[i])
  755. {
  756. POSITION t_pos = a_ResultObjs.GetHeadPosition();
  757. while (retVal && t_pos)
  758. {
  759. IWbemClassObject *t_vSrc = a_ResultObjs.GetNext(t_pos);
  760. if (t_vSrc)
  761. {
  762. IWbemClassObject* t_viewObj = NULL;
  763. if ( SUCCEEDED(t_vSrc->Clone(&t_viewObj)) )
  764. {
  765. if (JoinItem(a_ErrorObject, m_ObjSinkArray[a_Index]->m_ObjArray[i]->GetWrappedObject(),
  766. t_vSrc, t_viewObj, a_IndexArray, a_Index))
  767. {
  768. t_AddedResultObjs.AddTail(t_viewObj);
  769. }
  770. else
  771. {
  772. t_viewObj->Release();
  773. }
  774. }
  775. else
  776. {
  777. retVal = FALSE;
  778. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  779. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  780. a_ErrorObject.SetMessage ( L"An error occured when spawning an instance of the view class." );
  781. }
  782. }
  783. }
  784. m_ObjSinkArray[a_Index]->m_ObjArray[i]->Release();
  785. m_ObjSinkArray[a_Index]->m_ObjArray[i] = NULL;
  786. }
  787. }
  788. //don't need partial join any longer
  789. a_ResultObjs.RemoveAll();
  790. //copy the new result set to the result list
  791. //filter if this is the last time here...
  792. if (retVal)
  793. {
  794. POSITION t_pos = t_AddedResultObjs.GetHeadPosition();
  795. while (t_pos)
  796. {
  797. IWbemClassObject *t_vobj = a_ResultObjs.GetNext(t_pos);
  798. if (t_vobj)
  799. {
  800. t_vobj->AddRef();
  801. a_ResultObjs.AddTail(t_vobj);
  802. }
  803. }
  804. }
  805. t_AddedResultObjs.RemoveAll();
  806. return retVal;
  807. }
  808. #else //VP_PERFORMANT_JOINS
  809. BOOL WbemTaskObject::CreateAndIndicateJoins(WbemProvErrorObject &a_ErrorObject, BOOL a_bSingle)
  810. {
  811. BOOL retVal = TRUE;
  812. UINT isize = 1;
  813. if (m_ObjSinkArray.GetSize() != m_SourceArray.GetSize())
  814. {
  815. retVal = FALSE;
  816. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  817. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  818. a_ErrorObject.SetMessage ( L"A source query failed or was not executed therefore a join could not be created." );
  819. }
  820. //calculate the size of the results
  821. for (UINT x = 0; x < m_ObjSinkArray.GetSize(); x++)
  822. {
  823. if ((m_ObjSinkArray[x] == NULL) || FAILED(m_ObjSinkArray[x]->GetResult()) || !m_ObjSinkArray[x]->m_ObjArray.GetSize())
  824. {
  825. retVal = FALSE;
  826. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  827. if ( FAILED ( m_ObjSinkArray[x]->GetResult() ) )
  828. {
  829. a_ErrorObject.SetWbemStatus ( ( WBEMSTATUS ) m_ObjSinkArray[x]->GetResult() ) ;
  830. }
  831. else
  832. {
  833. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  834. }
  835. a_ErrorObject.SetMessage ( L"A source query failed or returned no instances." );
  836. break;
  837. }
  838. if ((0xFFFFFFFF/isize) >= m_ObjSinkArray[x]->m_ObjArray.GetSize())
  839. {
  840. isize = isize * m_ObjSinkArray[x]->m_ObjArray.GetSize();
  841. }
  842. else
  843. {
  844. retVal = FALSE;
  845. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  846. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  847. a_ErrorObject.SetMessage ( L"Too many possible combinations for join. Provider not capable." );
  848. }
  849. }
  850. if (retVal)
  851. {
  852. IWbemClassObject** objs = new IWbemClassObject*[m_ObjSinkArray.GetSize()];
  853. IWbemClassObject* res_obj = NULL;
  854. int num_res_objs = 0;
  855. for (UINT i = 0; i < isize; i++)
  856. {
  857. UINT t_iDenom = 1;
  858. for (x = 0; x < m_ObjSinkArray.GetSize(); x++)
  859. {
  860. UINT isz = m_ObjSinkArray[x]->m_ObjArray.GetSize();
  861. objs[x] = m_ObjSinkArray[x]->m_ObjArray[(i/t_iDenom) % isz];
  862. t_iDenom = t_iDenom * isz;
  863. }
  864. BOOL t_bRes = CreateAndIndicate(a_ErrorObject, objs, &res_obj);
  865. retVal = retVal && t_bRes;
  866. if (res_obj != NULL)
  867. {
  868. num_res_objs++;
  869. if (a_bSingle)
  870. {
  871. if (num_res_objs > 1)
  872. {
  873. res_obj->Release();
  874. retVal = FALSE;
  875. a_ErrorObject.SetStatus ( WBEM_PROV_E_TOOMANYRESULTSRETURNED ) ;
  876. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  877. a_ErrorObject.SetMessage ( L"Too many view instances can be created." ) ;
  878. break;
  879. }
  880. }
  881. else
  882. {
  883. if (m_bIndicate)
  884. {
  885. m_NotificationHandler->Indicate(1, &res_obj);
  886. res_obj->Release();
  887. res_obj = NULL;
  888. }
  889. }
  890. }
  891. }
  892. if (a_bSingle)
  893. {
  894. if (num_res_objs == 1)
  895. {
  896. if (m_bIndicate)
  897. {
  898. m_NotificationHandler->Indicate(1, &res_obj);
  899. }
  900. res_obj->Release();
  901. }
  902. }
  903. delete [] objs;
  904. }
  905. for (x = 0; x < m_ObjSinkArray.GetSize(); x++)
  906. {
  907. if (m_ObjSinkArray[x] != NULL)
  908. {
  909. m_ObjSinkArray[x]->Release();
  910. }
  911. }
  912. m_ObjSinkArray.RemoveAll();
  913. return retVal;
  914. }
  915. //for joins
  916. BOOL WbemTaskObject::CreateAndIndicate(WbemProvErrorObject &a_ErrorObject, IWbemClassObject ** pSrcs, IWbemClassObject **pOut)
  917. {
  918. BOOL retVal = TRUE;
  919. wchar_t** clsA = m_JoinOnArray.GetAClasses();
  920. wchar_t** clsB = m_JoinOnArray.GetBClasses();
  921. wchar_t** prpsA = m_JoinOnArray.GetAProperties();
  922. wchar_t** prpsB = m_JoinOnArray.GetBProperties();
  923. UINT* ops = m_JoinOnArray.GetOperators();
  924. for (int x = 0; retVal && (x < m_JoinOnArray.GetCount()); x++)
  925. {
  926. int iA;
  927. int iB;
  928. m_ClassToIndexMap.Lookup(clsA[x], iA);
  929. m_ClassToIndexMap.Lookup(clsB[x], iB);
  930. VARIANT vA;
  931. CIMTYPE cA;
  932. if ( SUCCEEDED(pSrcs[iA]->Get(prpsA[x], 0, &vA, &cA, NULL)) )
  933. {
  934. VARIANT vB;
  935. CIMTYPE cB;
  936. if ( SUCCEEDED(pSrcs[iB]->Get(prpsB[x], 0, &vB, &cB, NULL)) )
  937. {
  938. if (cA == cB)
  939. {
  940. if (ops[x] == CJoinOnQualifierArray::EQUALS_OPERATOR)
  941. {
  942. retVal = CompareSimplePropertyValues(&vA, &vB, cA);
  943. }
  944. else //NOT_EQUALS
  945. {
  946. retVal = !CompareSimplePropertyValues(&vA, &vB, cA);
  947. }
  948. }
  949. else
  950. {
  951. retVal = FALSE;
  952. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  953. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  954. a_ErrorObject.SetMessage ( L"Join properties have different CIM types." ) ;
  955. }
  956. VariantClear(&vB);
  957. }
  958. else
  959. {
  960. retVal = FALSE;
  961. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  962. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  963. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  964. }
  965. VariantClear(&vA);
  966. }
  967. else
  968. {
  969. retVal = FALSE;
  970. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  971. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  972. a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ;
  973. }
  974. }
  975. if (retVal)
  976. {
  977. BOOL bIndicate = TRUE;
  978. IWbemClassObject* viewObj = NULL;
  979. if ( SUCCEEDED(m_ClassObject->SpawnInstance(0, &viewObj)) )
  980. {
  981. POSITION propPos = m_PropertyMap.GetStartPosition();
  982. while ((propPos != NULL) && bIndicate)
  983. {
  984. CStringW propName;
  985. CPropertyQualifierItem* propProps;
  986. m_PropertyMap.GetNextAssoc(propPos, propName, propProps);
  987. VARIANT v;
  988. BOOL bSetProp = FALSE;
  989. CIMTYPE c;
  990. for (int x = 0; !bSetProp && (x < propProps->m_SrcPropertyNames.GetSize()); x++)
  991. {
  992. if (!propProps->m_SrcPropertyNames[x].IsEmpty())
  993. {
  994. bSetProp = TRUE;
  995. if ( SUCCEEDED(pSrcs[x]->Get(propProps->m_SrcPropertyNames[x], 0, &v, &c, NULL)) )
  996. {
  997. if (((v.vt == VT_NULL) || (v.vt == VT_EMPTY)) && propProps->IsKey())
  998. {
  999. if (retVal)
  1000. {
  1001. retVal = FALSE;
  1002. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  1003. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  1004. a_ErrorObject.SetMessage ( L"View key value in source instance is NULL" );
  1005. }
  1006. bIndicate = FALSE;
  1007. }
  1008. else
  1009. {
  1010. if ( FAILED(viewObj->Put(propName, 0, &v, c)) )
  1011. {
  1012. if (retVal)
  1013. {
  1014. retVal = FALSE;
  1015. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  1016. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  1017. a_ErrorObject.SetMessage ( L"Failed to put property" );
  1018. }
  1019. if (propProps->IsKey())
  1020. {
  1021. bIndicate = FALSE;
  1022. }
  1023. }
  1024. }
  1025. VariantClear(&v);
  1026. }
  1027. else
  1028. {
  1029. if (retVal)
  1030. {
  1031. retVal = FALSE;
  1032. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  1033. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  1034. a_ErrorObject.SetMessage ( L"Failed to get property from Source." ) ;
  1035. }
  1036. }
  1037. }
  1038. }
  1039. }
  1040. if (bIndicate)
  1041. {
  1042. retVal = PostFilter(viewObj);
  1043. if (retVal)
  1044. {
  1045. viewObj->AddRef();
  1046. *pOut = viewObj;
  1047. }
  1048. }
  1049. viewObj->Release();
  1050. }
  1051. else
  1052. {
  1053. retVal = FALSE;
  1054. a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
  1055. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  1056. a_ErrorObject.SetMessage ( L"WBEM API FAILURE:- Failed to spawn an instance of the view class." ) ;
  1057. }
  1058. }
  1059. return retVal;
  1060. }
  1061. #endif //VP_PERFORMANT_JOINS
  1062. BOOL WbemTaskObject::PostFilter(IWbemClassObject* a_pObj)
  1063. {
  1064. BOOL retVal = TRUE;
  1065. if ( (m_RPNPostFilter != NULL) && (m_RPNPostFilter->nNumTokens != 0) )
  1066. {
  1067. BOOL* t_bStack = new BOOL[m_RPNPostFilter->nNumTokens];
  1068. DWORD t_bCnt = 0;
  1069. for (int i = 0; retVal && (i < m_RPNPostFilter->nNumTokens); i++)
  1070. {
  1071. switch (m_RPNPostFilter->pArrayOfTokens[i].nTokenType)
  1072. {
  1073. case SQL_LEVEL_1_TOKEN::OP_EXPRESSION:
  1074. {
  1075. t_bStack[t_bCnt] = EvaluateToken(a_pObj, m_RPNPostFilter->pArrayOfTokens[i]);
  1076. t_bCnt++;
  1077. }
  1078. break;
  1079. case SQL_LEVEL_1_TOKEN::TOKEN_AND:
  1080. {
  1081. if (t_bCnt > 1)
  1082. {
  1083. t_bStack[t_bCnt - 2] = t_bStack[t_bCnt - 1] && t_bStack[t_bCnt - 2];
  1084. t_bCnt--;
  1085. }
  1086. else
  1087. {
  1088. retVal = FALSE;
  1089. }
  1090. }
  1091. break;
  1092. case SQL_LEVEL_1_TOKEN::TOKEN_OR:
  1093. {
  1094. if (t_bCnt > 1)
  1095. {
  1096. t_bStack[t_bCnt - 2] = t_bStack[t_bCnt - 1] || t_bStack[t_bCnt - 2];
  1097. t_bCnt--;
  1098. }
  1099. else
  1100. {
  1101. retVal = FALSE;
  1102. }
  1103. }
  1104. break;
  1105. case SQL_LEVEL_1_TOKEN::TOKEN_NOT:
  1106. {
  1107. if (t_bCnt > 0)
  1108. {
  1109. t_bStack[t_bCnt - 1] = !t_bStack[t_bCnt - 1];
  1110. }
  1111. }
  1112. break;
  1113. default:
  1114. {
  1115. }
  1116. break;
  1117. }
  1118. }
  1119. if (retVal)
  1120. {
  1121. retVal = t_bStack[t_bCnt - 1];
  1122. }
  1123. delete [] t_bStack;
  1124. }
  1125. return retVal;
  1126. }