|
|
//***************************************************************************
//
// VPTASKSJ.CPP
//
// Module: WBEM VIEW PROVIDER
//
// Purpose: Contains the join methods for taskobject implementation
//
// Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "precomp.h"
#include <provexpt.h>
#include <provcoll.h>
#include <provtempl.h>
#include <provmt.h>
#include <typeinfo.h>
#include <process.h>
#include <objbase.h>
#include <objidl.h>
#include <stdio.h>
#include <wbemidl.h>
#include <provcont.h>
#include <provevt.h>
#include <provthrd.h>
#include <provlog.h>
#include <cominit.h>
#include <dsgetdc.h>
#include <lmcons.h>
#include <lmapibuf.h>
#include <instpath.h>
#include <genlex.h>
#include <sql_1.h>
#include <objpath.h>
#include <vpdefs.h>
#include <vpcfac.h>
#include <vpquals.h>
#include <vpserv.h>
#include <vptasks.h>
#include <wbemtime.h>
BOOL CompareSimplePropertyValues(VARIANT* v1, VARIANT* v2, CIMTYPE ct) { BOOL retVal = FALSE;
if (v1->vt == v2->vt) { switch (ct) { case CIM_BOOLEAN: { if (VT_BOOL == v1->vt) { if (v1->boolVal == v2->boolVal) { retVal = TRUE; } } } break;
case CIM_UINT8: { if (VT_UI1 == v1->vt) { if (v1->bVal == v2->bVal) { retVal = TRUE; } } } break;
case CIM_SINT16: case CIM_CHAR16: case CIM_SINT8: { if (VT_I2 == v1->vt) { if (v1->iVal == v2->iVal) { retVal = TRUE; } } } break;
case CIM_UINT32: case CIM_SINT32: case CIM_UINT16: { if (VT_I4 == v1->vt) { if (v1->lVal == v2->lVal) { retVal = TRUE; } } } break;
case CIM_REFERENCE: //TO DO:
//references should be normalised for equality checks.
//should do this once CIMOM does...
case CIM_STRING: case CIM_SINT64: case CIM_UINT64: { if (VT_BSTR == v1->vt) { if (0 == _wcsicmp(v1->bstrVal,v2->bstrVal)) { retVal = TRUE; } } } break;
case CIM_DATETIME: { if (VT_BSTR == v1->vt) { WBEMTime t1(v1->bstrVal); WBEMTime t2(v2->bstrVal);
if (t1 == t2) { retVal = TRUE; } } } break;
default: { //unsupported by this function
} } }
return retVal; }
//Validate:
//1) All classes mentioned in join exist.
//2) All properties mentioned in join map to view class properties
//3) All classes mentioned in sources are mentioned in join
//4) Any != operator is not applied to two properties which map to the same view property
//5) All clauses have different classes being checked
BOOL WbemTaskObject::ValidateJoin() { //3) check all sources mentioned in join
//this check with (1) will do the trick
if (m_JoinOnArray.m_AllClasses.GetCount() != m_SourceArray.GetSize()) { return FALSE; }
//1) check all join classes exist
POSITION pos = m_JoinOnArray.m_AllClasses.GetStartPosition();
while (pos) { int val; CStringW tmpStr; m_JoinOnArray.m_AllClasses.GetNextAssoc(pos, tmpStr, val);
if (!m_ClassToIndexMap.Lookup(tmpStr, val)) { return FALSE; } }
wchar_t** classA = m_JoinOnArray.GetAClasses(); wchar_t** propsA = m_JoinOnArray.GetAProperties(); wchar_t** classB = m_JoinOnArray.GetBClasses(); wchar_t** propsB = m_JoinOnArray.GetBProperties(); UINT* ops = m_JoinOnArray.GetOperators();
//(2), (4) and (5) validations
//=============================
for (int x = 0; x < m_JoinOnArray.GetCount(); x++) { if (_wcsicmp(classA[x], classB[x]) == 0) { return FALSE; }
int indexA;
if (m_ClassToIndexMap.Lookup(classA[x], indexA)) { int indexB;
if (m_ClassToIndexMap.Lookup(classB[x], indexB)) { POSITION pos = m_PropertyMap.GetStartPosition(); CStringW propA; CStringW propB;
while (pos) { CStringW key; CPropertyQualifierItem* pItem; m_PropertyMap.GetNextAssoc(pos, key, pItem);
if (pItem->m_SrcPropertyNames[indexA].CompareNoCase(propsA[x]) == 0) { propA = key;
if (!propB.IsEmpty()) { break; } } if (pItem->m_SrcPropertyNames[indexB].CompareNoCase(propsB[x]) == 0) { propB = key;
if (!propA.IsEmpty()) { break; } } }
//check both properties exist (2)
if (propA.IsEmpty() || propB.IsEmpty()) { return FALSE; }
//validate expression (4)
if (ops[x] == CJoinOnQualifierArray::NOT_EQUALS_OPERATOR && (propA.CompareNoCase(propB) == 0)) { return FALSE; } } else { return FALSE; } } else { return FALSE; } }
return TRUE; }
#ifdef VP_PERFORMANT_JOINS
//should not compile with compiler flag set til I'm ready
BOOL WbemTaskObject::CreateAndIndicateJoinsPerf(WbemProvErrorObject &a_ErrorObject, BOOL a_bSingle) { BOOL retVal = TRUE;
//check all queries were asked...
if (m_ObjSinkArray.GetSize() != m_SourceArray.GetSize()) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"A source query failed or was not executed therefore a join could not be created." ); }
//check we got results from all queries...
for (UINT x = 0; x < m_ObjSinkArray.GetSize(); x++) { if ((m_ObjSinkArray[x] == NULL) || FAILED(m_ObjSinkArray[x]->GetResult()) || !m_ObjSinkArray[x]->m_ObjArray.GetSize()) { if (!a_bSingle) { a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
if ( FAILED ( m_ObjSinkArray[x]->GetResult() ) ) { a_ErrorObject.SetWbemStatus ( ( WBEMSTATUS ) m_ObjSinkArray[x]->GetResult() ) ; } else { a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; }
a_ErrorObject.SetMessage ( L"A source query failed or returned no instances." ); }
retVal = FALSE; break; } }
//perform the join of all results...
if (retVal) { CMap<CStringW, LPCWSTR, int, int> t_JoinedClasses; CList<IWbemClassObject*, IWbemClassObject*> t_ResultObjs; retVal = JoinTwoColumns(a_ErrorObject, t_JoinedClasses, t_ResultObjs); wchar_t** t_clsA = m_JoinOnArray.GetAClasses(); wchar_t** t_clsB = m_JoinOnArray.GetBClasses(); wchar_t** t_prpsA = m_JoinOnArray.GetAProperties(); wchar_t** t_prpsB = m_JoinOnArray.GetBProperties();
while ( retVal && (t_JoinedClasses.GetCount() != m_SourceArray.GetSize()) ) { DWORD t_column = m_SourceArray.GetSize() + 1; CList <int, int> t_IndexArray; wchar_t *t_classname = NULL;
//find a column not already joined that can be joined now...
for (x = 0; x < m_JoinOnArray.GetCount(); x++) { if (!m_JoinOnArray.m_bDone[x]) { int dummyInt = 0;
if (t_classname == NULL) { if (t_JoinedClasses.Lookup(t_clsA[x], dummyInt)) { if (!m_ClassToIndexMap.Lookup(t_clsB[x], (int &)t_column)) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"An unexpected error ocurred performing the join." ); }
t_classname = t_clsB[x]; t_JoinedClasses.SetAt(t_classname, 0); m_JoinOnArray.m_bDone[x] = TRUE; t_IndexArray.AddTail(x);
//want all clauses the same way around...
t_clsB[x] = t_clsA[x]; t_clsA[x] = t_classname; wchar_t *t_tmpStr = t_prpsA[x]; t_prpsA[x] = t_prpsB[x]; t_prpsB[x] = t_tmpStr; } else if (t_JoinedClasses.Lookup(t_clsB[x], dummyInt)) { if (!m_ClassToIndexMap.Lookup(t_clsA[x], (int &)t_column)) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"An unexpected error ocurred performing the join." ); }
t_classname = t_clsA[x]; t_JoinedClasses.SetAt(t_classname, 0); m_JoinOnArray.m_bDone[x] = TRUE; t_IndexArray.AddTail(x); } } else { //find all clauses which can be evaluated now...
if ((_wcsicmp(t_classname, t_clsA[x]) == 0) && (t_JoinedClasses.Lookup(t_clsB[x], dummyInt))) { t_IndexArray.AddTail(x); m_JoinOnArray.m_bDone[x] = TRUE; } else if ((_wcsicmp(t_classname, t_clsB[x]) == 0) && (t_JoinedClasses.Lookup(t_clsA[x], dummyInt))) { //want the clauses in the same order for simpler evaluation later...
wchar_t *t_tmpStr = t_clsA[x]; t_clsA[x] = t_clsB[x]; t_clsB[x] = t_tmpStr; t_tmpStr = t_prpsA[x]; t_prpsA[x] = t_prpsB[x]; t_prpsB[x] = t_tmpStr; t_IndexArray.AddTail(x); m_JoinOnArray.m_bDone[x] = TRUE; } } } }
if (t_column == m_SourceArray.GetSize() + 1) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to perform join." ); } else { retVal = AddColumnToJoin(a_ErrorObject, t_JoinedClasses, t_ResultObjs, t_column, t_IndexArray); t_IndexArray.RemoveAll(); } }
if (retVal) { if (m_bIndicate) { POSITION t_pos = t_ResultObjs.GetHeadPosition(); BOOL t_bIndicated = FALSE;
while (t_pos) { IWbemClassObject *t_Obj = t_ResultObjs.GetNext(t_pos);
if (t_Obj) { if (PostFilter(t_Obj)) { if (a_bSingle && t_bIndicated) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_TOOMANYRESULTSRETURNED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Too many view instances can be created." ) ; break; } else { m_NotificationHandler->Indicate(1, &t_Obj); t_bIndicated = TRUE; } } } } } }
t_ResultObjs.RemoveAll(); }
//clean up...
for (x = 0; x < m_ObjSinkArray.GetSize(); x++) { if (m_ObjSinkArray[x] != NULL) { m_ObjSinkArray[x]->Release(); } }
m_ObjSinkArray.RemoveAll();
return retVal; }
BOOL WbemTaskObject::JoinItem(WbemProvErrorObject &a_ErrorObject, IWbemClassObject *a_Obj1, IWbemClassObject *a_vObj, IWbemClassObject *a_resObj, CList <int, int> &a_IndexArray, DWORD a_indx1) { BOOL retVal = TRUE; wchar_t** t_clsA = m_JoinOnArray.GetAClasses(); wchar_t** t_clsB = m_JoinOnArray.GetBClasses(); UINT* t_ops = m_JoinOnArray.GetOperators(); wchar_t** t_prpsA = m_JoinOnArray.GetAProperties(); wchar_t** t_prpsB = m_JoinOnArray.GetBProperties(); VARIANT t_vA; VariantInit(&t_vA); CIMTYPE t_cA; POSITION t_pos = a_IndexArray.GetHeadPosition();
while (t_pos && retVal) { int t_index = a_IndexArray.GetNext(t_pos);
//get the propertyname in the view...
int t_srcindxA = 0; int t_srcindxB = 0; if (m_ClassToIndexMap.Lookup(t_clsB[t_index], t_srcindxB) && m_ClassToIndexMap.Lookup(t_clsA[t_index], t_srcindxA)) { //find t_prpsB[t_index] and get the view property name...
POSITION t_propPos = m_PropertyMap.GetStartPosition(); CStringW t_propName;
while (t_propPos != NULL) { CPropertyQualifierItem *t_propProps; m_PropertyMap.GetNextAssoc(t_propPos, t_propName, t_propProps);
if (!t_propProps->m_SrcPropertyNames[t_srcindxB].IsEmpty() && !t_propProps->m_SrcPropertyNames[t_srcindxA].IsEmpty() && (_wcsicmp(t_propProps->m_SrcPropertyNames[t_srcindxB], t_prpsB[t_index]) == 0) && (_wcsicmp(t_propProps->m_SrcPropertyNames[t_srcindxA], t_prpsA[t_index]) == 0)) { break; } else { t_propName.Empty(); } }
if (!t_propName.IsEmpty() && SUCCEEDED(a_Obj1->Get(t_prpsA[t_index], 0, &t_vA, &t_cA, NULL)) ) { VARIANT t_vB; VariantInit(&t_vB); CIMTYPE t_cB;
if ( SUCCEEDED(a_vObj->Get(t_propName, 0, &t_vB, &t_cB, NULL)) ) { if (t_cA == t_cB) { if (t_ops[t_index] == CJoinOnQualifierArray::EQUALS_OPERATOR) { retVal = CompareSimplePropertyValues(&t_vA, &t_vB, t_cA); } else //NOT_EQUALS
{ retVal = !CompareSimplePropertyValues(&t_vA, &t_vB, t_cA); } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Join properties have different CIM types." ) ; } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ; }
VariantClear(&t_vA); VariantClear(&t_vB); VariantInit(&t_vA); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ; } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to find source property in view class." ) ; } }
VariantClear(&t_vA);
if (retVal) { //copy properties from sources to result
POSITION t_propPos = m_PropertyMap.GetStartPosition();
while ((t_propPos != NULL) && retVal) { CStringW t_propName; CPropertyQualifierItem *t_propProps; m_PropertyMap.GetNextAssoc(t_propPos, t_propName, t_propProps); if (!t_propProps->m_SrcPropertyNames[a_indx1].IsEmpty()) { VARIANT t_v; VariantInit(&t_v); CIMTYPE t_c;
if ( SUCCEEDED(a_Obj1->Get(t_propProps->m_SrcPropertyNames[a_indx1], 0, &t_v, &t_c, NULL)) ) { if (((t_v.vt == VT_NULL) || (t_v.vt == VT_EMPTY)) && t_propProps->IsKey()) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"View key value in source instance is NULL" ); } else { if ( FAILED(a_resObj->Put(t_propName, 0, &t_v, t_c)) ) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to put property" ); } }
VariantClear(&t_v); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get property from Source." ) ; } } else { continue; } } }
return retVal; }
BOOL WbemTaskObject::JoinTwoItems(WbemProvErrorObject &a_ErrorObject, IWbemClassObject *a_Obj1, IWbemClassObject *a_Obj2, IWbemClassObject *a_resObj, CList <int, int> &a_IndexArray, DWORD a_indx1, DWORD a_indx2) { BOOL retVal = TRUE; wchar_t** t_clsA = m_JoinOnArray.GetAClasses(); wchar_t** t_clsB = m_JoinOnArray.GetBClasses(); UINT* t_ops = m_JoinOnArray.GetOperators(); wchar_t** t_prpsA = m_JoinOnArray.GetAProperties(); wchar_t** t_prpsB = m_JoinOnArray.GetBProperties(); VARIANT t_vA; CIMTYPE t_cA; POSITION t_pos = a_IndexArray.GetHeadPosition();
while (t_pos && retVal) { int t_index = a_IndexArray.GetNext(t_pos);
if ( SUCCEEDED(a_Obj1->Get(t_prpsA[t_index], 0, &t_vA, &t_cA, NULL)) ) { VARIANT t_vB; CIMTYPE t_cB;
if ( SUCCEEDED(a_Obj2->Get(t_prpsB[t_index], 0, &t_vB, &t_cB, NULL)) ) { if (t_cA == t_cB) { if (t_ops[t_index] == CJoinOnQualifierArray::EQUALS_OPERATOR) { retVal = CompareSimplePropertyValues(&t_vA, &t_vB, t_cA); } else //NOT_EQUALS
{ retVal = !CompareSimplePropertyValues(&t_vA, &t_vB, t_cA); } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Join properties have different CIM types." ) ; }
VariantClear(&t_vB); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ; }
VariantClear(&t_vA); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ; } }
if (retVal) { //copy properties from sources to result
POSITION t_propPos = m_PropertyMap.GetStartPosition();
while ((t_propPos != NULL) && retVal) { CStringW t_propName; CPropertyQualifierItem *t_propProps; m_PropertyMap.GetNextAssoc(t_propPos, t_propName, t_propProps); IWbemClassObject *t_src_Obj = NULL; DWORD t_index = 0; if (!t_propProps->m_SrcPropertyNames[a_indx1].IsEmpty()) { t_src_Obj = a_Obj1; t_index = a_indx1; } else if (!t_propProps->m_SrcPropertyNames[a_indx2].IsEmpty()) { t_src_Obj = a_Obj2; t_index = a_indx2; } else { continue; }
VARIANT t_v; VariantInit(&t_v); CIMTYPE t_c;
if ( SUCCEEDED(t_src_Obj->Get(t_propProps->m_SrcPropertyNames[t_index], 0, &t_v, &t_c, NULL)) ) { if (((t_v.vt == VT_NULL) || (t_v.vt == VT_EMPTY)) && t_propProps->IsKey()) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"View key value in source instance is NULL" ); } else { if ( FAILED(a_resObj->Put(t_propName, 0, &t_v, t_c)) ) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to put property" ); } }
VariantClear(&t_v); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get property from Source." ) ; } } }
return retVal; }
BOOL WbemTaskObject::JoinTwoColumns(WbemProvErrorObject &a_ErrorObject, CMap<CStringW, LPCWSTR, int, int> &a_JoinedClasses, CList<IWbemClassObject*, IWbemClassObject*> &a_ResultObjs) { BOOL retVal = TRUE; wchar_t** t_clsA = m_JoinOnArray.GetAClasses(); wchar_t** t_clsB = m_JoinOnArray.GetBClasses(); wchar_t** t_prpsA = m_JoinOnArray.GetAProperties(); wchar_t** t_prpsB = m_JoinOnArray.GetBProperties(); UINT* t_ops = m_JoinOnArray.GetOperators(); int t_indexA; int t_indexB; CList <int, int> t_IndexArray; t_IndexArray.AddTail(0); m_JoinOnArray.m_bDone[0] = TRUE;
for (int x = 1; x < m_JoinOnArray.GetCount(); x++) { //find all clauses which can be evaluated now...
if ((_wcsicmp(t_clsA[0], t_clsA[x]) == 0) && (_wcsicmp(t_clsB[0], t_clsB[x]) == 0)) { t_IndexArray.AddTail(x); m_JoinOnArray.m_bDone[x] = TRUE; } else if ((_wcsicmp(t_clsB[0], t_clsA[x]) == 0) && (_wcsicmp(t_clsA[0], t_clsB[x]) == 0)) { //want the clauses in the same order for simpler evaluation later...
wchar_t *t_tmp = t_clsA[x]; t_clsA[x] = t_clsB[x]; t_clsB[x] = t_tmp; t_tmp = t_prpsA[x]; t_prpsA[x] = t_prpsB[x]; t_prpsB[x] = t_tmp; t_IndexArray.AddTail(x); m_JoinOnArray.m_bDone[x] = TRUE; } }
a_JoinedClasses.SetAt(t_clsA[0], 0); a_JoinedClasses.SetAt(t_clsB[0], 0); m_ClassToIndexMap.Lookup(t_clsA[0], t_indexA); m_ClassToIndexMap.Lookup(t_clsB[0], t_indexB);
for (int i = 0; retVal && (i < m_ObjSinkArray[t_indexA]->m_ObjArray.GetSize()); i++) { if (m_ObjSinkArray[t_indexA]->m_ObjArray[i]) { for (int j = 0; retVal && (j < m_ObjSinkArray[t_indexB]->m_ObjArray.GetSize()); j++) { if (m_ObjSinkArray[t_indexB]->m_ObjArray[j]) { IWbemClassObject* t_viewObj = NULL; if ( SUCCEEDED(m_ClassObject->SpawnInstance(0, &t_viewObj)) ) { if (JoinTwoItems(a_ErrorObject, m_ObjSinkArray[t_indexA]->m_ObjArray[i]->GetWrappedObject(), m_ObjSinkArray[t_indexB]->m_ObjArray[j]->GetWrappedObject(), t_viewObj, t_IndexArray, t_indexA, t_indexB)) { a_ResultObjs.AddTail(t_viewObj); } else { t_viewObj->Release(); } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"An error occured when spawning an instance of the view class." ); } } }
m_ObjSinkArray[t_indexA]->m_ObjArray[i]->Release(); m_ObjSinkArray[t_indexA]->m_ObjArray[i] = NULL; } }
m_ObjSinkArray[t_indexB]->m_ObjArray.RemoveAll();
return retVal; }
BOOL WbemTaskObject::AddColumnToJoin(WbemProvErrorObject &a_ErrorObject, CMap<CStringW, LPCWSTR, int, int> &a_JoinedClasses, CList<IWbemClassObject*, IWbemClassObject*> &a_ResultObjs, DWORD a_Index, CList <int, int> &a_IndexArray) { BOOL retVal = TRUE; CList<IWbemClassObject*, IWbemClassObject*> t_AddedResultObjs;
for (int i = 0; retVal && (i < m_ObjSinkArray[a_Index]->m_ObjArray.GetSize()); i++) { if (m_ObjSinkArray[a_Index]->m_ObjArray[i]) { POSITION t_pos = a_ResultObjs.GetHeadPosition();
while (retVal && t_pos) { IWbemClassObject *t_vSrc = a_ResultObjs.GetNext(t_pos);
if (t_vSrc) { IWbemClassObject* t_viewObj = NULL; if ( SUCCEEDED(t_vSrc->Clone(&t_viewObj)) ) { if (JoinItem(a_ErrorObject, m_ObjSinkArray[a_Index]->m_ObjArray[i]->GetWrappedObject(), t_vSrc, t_viewObj, a_IndexArray, a_Index)) { t_AddedResultObjs.AddTail(t_viewObj); } else { t_viewObj->Release(); } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"An error occured when spawning an instance of the view class." ); } } }
m_ObjSinkArray[a_Index]->m_ObjArray[i]->Release(); m_ObjSinkArray[a_Index]->m_ObjArray[i] = NULL; } }
//don't need partial join any longer
a_ResultObjs.RemoveAll();
//copy the new result set to the result list
//filter if this is the last time here...
if (retVal) { POSITION t_pos = t_AddedResultObjs.GetHeadPosition();
while (t_pos) { IWbemClassObject *t_vobj = a_ResultObjs.GetNext(t_pos);
if (t_vobj) { t_vobj->AddRef(); a_ResultObjs.AddTail(t_vobj); } } }
t_AddedResultObjs.RemoveAll(); return retVal; }
#else //VP_PERFORMANT_JOINS
BOOL WbemTaskObject::CreateAndIndicateJoins(WbemProvErrorObject &a_ErrorObject, BOOL a_bSingle) { BOOL retVal = TRUE; UINT isize = 1;
if (m_ObjSinkArray.GetSize() != m_SourceArray.GetSize()) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"A source query failed or was not executed therefore a join could not be created." ); }
//calculate the size of the results
for (UINT x = 0; x < m_ObjSinkArray.GetSize(); x++) { if ((m_ObjSinkArray[x] == NULL) || FAILED(m_ObjSinkArray[x]->GetResult()) || !m_ObjSinkArray[x]->m_ObjArray.GetSize()) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
if ( FAILED ( m_ObjSinkArray[x]->GetResult() ) ) { a_ErrorObject.SetWbemStatus ( ( WBEMSTATUS ) m_ObjSinkArray[x]->GetResult() ) ; } else { a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; }
a_ErrorObject.SetMessage ( L"A source query failed or returned no instances." ); break; }
if ((0xFFFFFFFF/isize) >= m_ObjSinkArray[x]->m_ObjArray.GetSize()) { isize = isize * m_ObjSinkArray[x]->m_ObjArray.GetSize(); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Too many possible combinations for join. Provider not capable." ); } }
if (retVal) { IWbemClassObject** objs = new IWbemClassObject*[m_ObjSinkArray.GetSize()]; IWbemClassObject* res_obj = NULL; int num_res_objs = 0;
for (UINT i = 0; i < isize; i++) { UINT t_iDenom = 1;
for (x = 0; x < m_ObjSinkArray.GetSize(); x++) { UINT isz = m_ObjSinkArray[x]->m_ObjArray.GetSize(); objs[x] = m_ObjSinkArray[x]->m_ObjArray[(i/t_iDenom) % isz]; t_iDenom = t_iDenom * isz; }
BOOL t_bRes = CreateAndIndicate(a_ErrorObject, objs, &res_obj); retVal = retVal && t_bRes;
if (res_obj != NULL) { num_res_objs++;
if (a_bSingle) { if (num_res_objs > 1) { res_obj->Release(); retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_TOOMANYRESULTSRETURNED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Too many view instances can be created." ) ; break; } } else { if (m_bIndicate) { m_NotificationHandler->Indicate(1, &res_obj); res_obj->Release(); res_obj = NULL; } } } }
if (a_bSingle) { if (num_res_objs == 1) { if (m_bIndicate) { m_NotificationHandler->Indicate(1, &res_obj); }
res_obj->Release(); } }
delete [] objs; }
for (x = 0; x < m_ObjSinkArray.GetSize(); x++) { if (m_ObjSinkArray[x] != NULL) { m_ObjSinkArray[x]->Release(); } }
m_ObjSinkArray.RemoveAll();
return retVal; }
//for joins
BOOL WbemTaskObject::CreateAndIndicate(WbemProvErrorObject &a_ErrorObject, IWbemClassObject ** pSrcs, IWbemClassObject **pOut) { BOOL retVal = TRUE; wchar_t** clsA = m_JoinOnArray.GetAClasses(); wchar_t** clsB = m_JoinOnArray.GetBClasses(); wchar_t** prpsA = m_JoinOnArray.GetAProperties(); wchar_t** prpsB = m_JoinOnArray.GetBProperties(); UINT* ops = m_JoinOnArray.GetOperators();
for (int x = 0; retVal && (x < m_JoinOnArray.GetCount()); x++) { int iA; int iB;
m_ClassToIndexMap.Lookup(clsA[x], iA); m_ClassToIndexMap.Lookup(clsB[x], iB);
VARIANT vA; CIMTYPE cA;
if ( SUCCEEDED(pSrcs[iA]->Get(prpsA[x], 0, &vA, &cA, NULL)) ) { VARIANT vB; CIMTYPE cB;
if ( SUCCEEDED(pSrcs[iB]->Get(prpsB[x], 0, &vB, &cB, NULL)) ) { if (cA == cB) { if (ops[x] == CJoinOnQualifierArray::EQUALS_OPERATOR) { retVal = CompareSimplePropertyValues(&vA, &vB, cA); } else //NOT_EQUALS
{ retVal = !CompareSimplePropertyValues(&vA, &vB, cA); } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Join properties have different CIM types." ) ; }
VariantClear(&vB); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ; }
VariantClear(&vA); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get join property from Source." ) ; } }
if (retVal) { BOOL bIndicate = TRUE; IWbemClassObject* viewObj = NULL; if ( SUCCEEDED(m_ClassObject->SpawnInstance(0, &viewObj)) ) { POSITION propPos = m_PropertyMap.GetStartPosition();
while ((propPos != NULL) && bIndicate) { CStringW propName; CPropertyQualifierItem* propProps; m_PropertyMap.GetNextAssoc(propPos, propName, propProps); VARIANT v; BOOL bSetProp = FALSE; CIMTYPE c; for (int x = 0; !bSetProp && (x < propProps->m_SrcPropertyNames.GetSize()); x++) { if (!propProps->m_SrcPropertyNames[x].IsEmpty()) { bSetProp = TRUE;
if ( SUCCEEDED(pSrcs[x]->Get(propProps->m_SrcPropertyNames[x], 0, &v, &c, NULL)) ) { if (((v.vt == VT_NULL) || (v.vt == VT_EMPTY)) && propProps->IsKey()) { if (retVal) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"View key value in source instance is NULL" ); }
bIndicate = FALSE; } else { if ( FAILED(viewObj->Put(propName, 0, &v, c)) ) { if (retVal) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to put property" ); }
if (propProps->IsKey()) { bIndicate = FALSE; } } }
VariantClear(&v); } else { if (retVal) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to get property from Source." ) ; } } } } }
if (bIndicate) { retVal = PostFilter(viewObj);
if (retVal) { viewObj->AddRef(); *pOut = viewObj; } }
viewObj->Release(); } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"WBEM API FAILURE:- Failed to spawn an instance of the view class." ) ; } }
return retVal; }
#endif //VP_PERFORMANT_JOINS
BOOL WbemTaskObject::PostFilter(IWbemClassObject* a_pObj) { BOOL retVal = TRUE;
if ( (m_RPNPostFilter != NULL) && (m_RPNPostFilter->nNumTokens != 0) ) { BOOL* t_bStack = new BOOL[m_RPNPostFilter->nNumTokens]; DWORD t_bCnt = 0;
for (int i = 0; retVal && (i < m_RPNPostFilter->nNumTokens); i++) { switch (m_RPNPostFilter->pArrayOfTokens[i].nTokenType) { case SQL_LEVEL_1_TOKEN::OP_EXPRESSION: { t_bStack[t_bCnt] = EvaluateToken(a_pObj, m_RPNPostFilter->pArrayOfTokens[i]); t_bCnt++; } break;
case SQL_LEVEL_1_TOKEN::TOKEN_AND: { if (t_bCnt > 1) { t_bStack[t_bCnt - 2] = t_bStack[t_bCnt - 1] && t_bStack[t_bCnt - 2]; t_bCnt--; } else { retVal = FALSE; } } break;
case SQL_LEVEL_1_TOKEN::TOKEN_OR: { if (t_bCnt > 1) { t_bStack[t_bCnt - 2] = t_bStack[t_bCnt - 1] || t_bStack[t_bCnt - 2]; t_bCnt--; } else { retVal = FALSE; } } break;
case SQL_LEVEL_1_TOKEN::TOKEN_NOT: { if (t_bCnt > 0) { t_bStack[t_bCnt - 1] = !t_bStack[t_bCnt - 1]; } } break;
default: { } break; } }
if (retVal) { retVal = t_bStack[t_bCnt - 1]; }
delete [] t_bStack; }
return retVal; }
|