//*************************************************************************** // // VPGET.CPP // // Module: WBEM VIEW PROVIDER // // Purpose: Contains the ExecQuery implementation // // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved // //*************************************************************************** #include "precomp.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //for association work-around struct MY_SQL_LEVEL_1_TOKEN { BOOL m_bSpecial; SQL_LEVEL_1_TOKEN m_Tok; MY_SQL_LEVEL_1_TOKEN() { m_bSpecial = FALSE; } //assignment operators MY_SQL_LEVEL_1_TOKEN& operator=(SQL_LEVEL_1_TOKEN &Src) { m_bSpecial = FALSE; this->m_Tok = Src; return *this; } MY_SQL_LEVEL_1_TOKEN& operator=(MY_SQL_LEVEL_1_TOKEN &Src) { *this = Src.m_Tok; m_bSpecial = Src.m_bSpecial; return *this; } //copy constructors match the operators MY_SQL_LEVEL_1_TOKEN(MY_SQL_LEVEL_1_TOKEN &Src) { *this = Src; } MY_SQL_LEVEL_1_TOKEN(SQL_LEVEL_1_TOKEN &Src) { *this = Src; } }; ExecQueryTaskObject::ExecQueryTaskObject(CViewProvServ *a_Provider , BSTR a_QueryFormat, BSTR a_Query, ULONG a_Flag, IWbemObjectSink *a_NotificationHandler, IWbemContext *pCtx ) : WbemTaskObject(a_Provider, a_NotificationHandler, a_Flag, pCtx), m_Query(NULL), m_QueryFormat(NULL), m_RPNExpression(NULL) { m_Query = UnicodeStringDuplicate(a_Query); m_QueryFormat = UnicodeStringDuplicate(a_QueryFormat); } ExecQueryTaskObject::~ExecQueryTaskObject () { BOOL t_Status = TRUE; IWbemClassObject *t_NotifyStatus = NULL ; if (WBEM_NO_ERROR != m_ErrorObject.GetWbemStatus ()) { t_Status = GetExtendedNotifyStatusObject ( &t_NotifyStatus ) ; } if ( t_Status ) { m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , t_NotifyStatus ) ; if (t_NotifyStatus) { t_NotifyStatus->Release () ; } } else { m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , NULL ) ; } if (m_Query != NULL) { delete [] m_Query; } if (m_QueryFormat != NULL) { delete [] m_QueryFormat; } if (m_RPNExpression != NULL) { delete m_RPNExpression; } if (m_StatusHandle != NULL) { CloseHandle(m_StatusHandle); } } BOOL ExecQueryTaskObject::PerformQuery(WbemProvErrorObject &a_ErrorObject) { BOOL retVal = FALSE; m_StatusHandle = CreateEvent(NULL, TRUE, FALSE, NULL); retVal = PerformEnumQueries(a_ErrorObject); if (retVal) { BOOL bWait = TRUE; while (bWait) { DWORD dwWait = WbemWaitForSingleObject(m_StatusHandle, VP_QUERY_TIMEOUT); switch (dwWait) { case WAIT_OBJECT_0: { if (ResetEvent(m_StatusHandle)) { m_ResultReceived = FALSE; retVal = PerformSelectQueries(a_ErrorObject, bWait); if (retVal) { if (bWait) { while (bWait) { dwWait = WbemWaitForSingleObject(m_StatusHandle, VP_QUERY_TIMEOUT); switch (dwWait) { case WAIT_OBJECT_0 : { retVal = ProcessResults(a_ErrorObject); bWait = FALSE; } break; case WAIT_TIMEOUT: { BOOL bCleanup = TRUE; if (m_ArrayLock.Lock()) { if (m_ResultReceived) { m_ResultReceived = FALSE; bCleanup = FALSE; } m_ArrayLock.Unlock(); } if (bCleanup) { CleanUpObjSinks(TRUE); a_ErrorObject.SetStatus ( WBEM_PROV_E_FAILED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Wait on a sychronization object failed, or query timed out" ) ; retVal = FALSE; bWait = FALSE; } } break; default: { //Cancel outstanding requests and delete object sinks... //====================================================== CleanUpObjSinks(TRUE); a_ErrorObject.SetStatus ( WBEM_PROV_E_FAILED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Wait on a sychronization object failed" ) ; retVal = FALSE; bWait = FALSE; } } } } else { retVal = ProcessResults(a_ErrorObject); } } else { ProcessResults(a_ErrorObject); } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to perform source query(ies), a WIN32 API failed" ) ; ProcessResults(a_ErrorObject); } bWait = FALSE; } break; case WAIT_TIMEOUT: { BOOL bCleanup = TRUE; if (m_ArrayLock.Lock()) { if (m_ResultReceived) { m_ResultReceived = FALSE; bCleanup = FALSE; } m_ArrayLock.Unlock(); } if (bCleanup) { CleanUpObjSinks(TRUE); a_ErrorObject.SetStatus ( WBEM_PROV_E_FAILED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Wait on a sychronization object failed, or query timed out" ) ; retVal = FALSE; bWait = FALSE; } } break; default: { //Cancel outstanding requests and delete object sinks... //====================================================== CleanUpObjSinks(TRUE); a_ErrorObject.SetStatus ( WBEM_PROV_E_FAILED ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Wait on a sychronization object failed" ) ; retVal = FALSE; bWait = FALSE; } } } } else { //no outstanding requests, just delete object sinks... //==================================================== CleanUpObjSinks(); } return retVal; } //The following function does 'simple' analysis of the current //query and modifies the source queries accordingly... //============================================================ void ExecQueryTaskObject::ModifySourceQueriesForUserQuery() { MY_SQL_LEVEL_1_TOKEN* pExtraToks = new MY_SQL_LEVEL_1_TOKEN[m_RPNExpression->nNumTokens + 1]; for (int x = 0; x < m_NSpaceArray.GetSize(); x++) { DWORD dwToks = 0; BOOL bOptimize = TRUE; for (int i = 0; bOptimize && (i < m_RPNExpression->nNumTokens); i++) { switch (m_RPNExpression->pArrayOfTokens[i].nTokenType) { case SQL_LEVEL_1_TOKEN::TOKEN_AND: { pExtraToks[dwToks++].m_Tok.nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_AND; } break; case SQL_LEVEL_1_TOKEN::TOKEN_OR: { pExtraToks[dwToks++].m_Tok.nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_OR; } break; case SQL_LEVEL_1_TOKEN::TOKEN_NOT: { pExtraToks[dwToks++].m_Tok.nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_NOT; } break; case SQL_LEVEL_1_TOKEN::OP_EXPRESSION: { CPropertyQualifierItem* propItem; if (m_PropertyMap.Lookup(m_RPNExpression->pArrayOfTokens[i].pPropertyName, propItem)) { if (!propItem->m_SrcPropertyNames[x].IsEmpty()) { //TransposeReference if necessary //================================= MY_SQL_LEVEL_1_TOKEN tmpToken = m_RPNExpression->pArrayOfTokens[i]; BOOL bCont = TRUE; if (m_bAssoc && (propItem->GetCimType() == CIM_REFERENCE)) { bCont = TransposeReference(propItem, m_RPNExpression->pArrayOfTokens[i].vConstValue, &(tmpToken.m_Tok.vConstValue), FALSE, NULL); if (bCont) { //mark the token as special //for the association work-around tmpToken.m_bSpecial = TRUE; } } if (bCont) { pExtraToks[dwToks] = tmpToken; SysFreeString(pExtraToks[dwToks].m_Tok.pPropertyName); pExtraToks[dwToks++].m_Tok.pPropertyName = propItem->m_SrcPropertyNames[x].AllocSysString(); } else { //can't "simply" optimize this query! dwToks = 0; bOptimize = FALSE; } } else { //can't "simply" optimize this query! dwToks = 0; bOptimize = FALSE; } } else { //can't "simply" optimize this query! dwToks = 0; bOptimize = FALSE; } } break; default: { } } } if (dwToks != 0) { if (m_SourceArray[x]->GetRPNExpression()->nNumTokens > 0) { pExtraToks[dwToks++].m_Tok.nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_AND; } for (i = 0; i < dwToks; i++) { m_SourceArray[x]->GetRPNExpression()->AddToken(pExtraToks[i].m_Tok); if (pExtraToks[i].m_bSpecial) { //add the extra tokens if neccessary //for the association work-around wchar_t *t_pChar = pExtraToks[i].m_Tok.vConstValue.bstrVal; //must be \\server\namespace and not \\.\namespace or relpath if ( (*t_pChar == L'\\') && (*(t_pChar+1) == L'\\') && (*(t_pChar+2) != L'.') ) { //add the dotted version SQL_LEVEL_1_TOKEN t_Tok = pExtraToks[i].m_Tok; t_pChar = t_Tok.vConstValue.bstrVal + 2; while (*t_pChar != L'\\') { t_pChar++; } --t_pChar; *t_pChar = L'.'; --t_pChar; *t_pChar = L'\\'; --t_pChar; *t_pChar = L'\\'; BSTR t_strtmp = SysAllocString(t_pChar); VariantClear(&(t_Tok.vConstValue)); VariantInit(&(t_Tok.vConstValue)); t_Tok.vConstValue.vt = VT_BSTR; t_Tok.vConstValue.bstrVal = t_strtmp; m_SourceArray[x]->GetRPNExpression()->AddToken(t_Tok); //add an Or token SQL_LEVEL_1_TOKEN t_OrTok; t_OrTok.nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_OR; m_SourceArray[x]->GetRPNExpression()->AddToken(t_OrTok); //add the relpath version t_pChar = t_Tok.vConstValue.bstrVal + 4; while (*t_pChar != L':') { t_pChar++; } //exclude the ':' t_pChar++; t_strtmp = SysAllocString(t_pChar); VariantClear(&(t_Tok.vConstValue)); VariantInit(&(t_Tok.vConstValue)); t_Tok.vConstValue.vt = VT_BSTR; t_Tok.vConstValue.bstrVal = t_strtmp; m_SourceArray[x]->GetRPNExpression()->AddToken(t_Tok); //add the last OR m_SourceArray[x]->GetRPNExpression()->AddToken(t_OrTok); } } } } } delete [] pExtraToks; } //This function does 'simple' analysis of the join and modifies the //unexecuted source queries accordingly for the results received so far... //========================================================================= void ExecQueryTaskObject::ModifySourceQueriesWithEnumResults() { 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(); int iEnum; //the index of the enumerated class int iMod; //the index of the source query to be modified for (int x = 0; x < m_JoinOnArray.GetCount(); x++) { BOOL bIsAEnum = m_EnumerateClasses.Lookup(classA[x], iEnum); BOOL bIsBEnum = m_EnumerateClasses.Lookup(classB[x], iEnum); wchar_t* propEnum; wchar_t* propMod; if ( (bIsAEnum && !bIsBEnum) || (!bIsAEnum && bIsBEnum) ) { if (bIsAEnum) { if (!m_ClassToIndexMap.Lookup(classA[x], iEnum)) { //an error forget this case! continue; } else { if (!m_ClassToIndexMap.Lookup(classB[x], iMod)) { //an error forget this case! continue; } else { propEnum = propsA[x]; propMod = propsB[x]; } } } else { if (!m_ClassToIndexMap.Lookup(classB[x], iEnum)) { //an error forget this case! continue; } else { if (!m_ClassToIndexMap.Lookup(classA[x], iMod)) { //an error forget this case! continue; } else { propEnum = propsB[x]; propMod = propsA[x]; } } } //don't transpose references as //they are already in source format. int m = 0; SQL_LEVEL_1_TOKEN opToken; opToken.nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_OR; SQL_LEVEL_1_TOKEN token; token.nTokenType = SQL_LEVEL_1_TOKEN::OP_EXPRESSION; token.pPropertyName = SysAllocString(propMod); if (ops[x] == CJoinOnQualifierArray::NOT_EQUALS_OPERATOR) { token.nOperator = SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL; } else if (ops[x] == CJoinOnQualifierArray::EQUALS_OPERATOR) { token.nOperator = SQL_LEVEL_1_TOKEN::OP_EQUAL; } BOOL bAddAnd = m_SourceArray[iMod]->GetRPNExpression()->nNumTokens > 0; for (int n = 0; n < m_ObjSinkArray[iEnum]->m_ObjArray.GetSize(); n++) { VariantInit(&token.vConstValue); IWbemClassObject* pObj = m_ObjSinkArray[iEnum]->m_ObjArray[n]->GetWrappedObject(); if ( SUCCEEDED(pObj->Get(propEnum, 0, &token.vConstValue, NULL, NULL)) ) { m_SourceArray[iMod]->GetRPNExpression()->AddToken(token); m++; if (m > 1) { m_SourceArray[iMod]->GetRPNExpression()->AddToken(opToken); } } VariantClear(&token.vConstValue); } if ((bAddAnd) && (m != 0)) { opToken.nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_AND; m_SourceArray[iMod]->GetRPNExpression()->AddToken(opToken); } } } } BOOL ExecQueryTaskObject::PerformSelectQueries(WbemProvErrorObject &a_ErrorObject, BOOL &bWait) { bWait = FALSE; BOOL bStatusSet = FALSE; if (!m_JoinOnArray.IsValid() || m_EnumerateClasses.IsEmpty()) { return TRUE; } ModifySourceQueriesWithEnumResults(); //reset number of queries asked and answered m_iQueriesAsked = 1; m_iQueriesAnswered = 0; for (int x = 0; x < m_NSpaceArray.GetSize(); x++) { int dummyInt; if (!m_EnumerateClasses.Lookup(m_SourceArray[x]->GetClassName(), dummyInt)) { CStringW queryStr = GetStringFromRPN(m_SourceArray[x]->GetRPNExpression(), 0, NULL); CWbemServerWrap** nsPtrs = m_NSpaceArray[x]->GetServerPtrs(); if (queryStr.GetLength() > 0) { for (int m = 0; m < m_NSpaceArray[x]->GetCount(); m++) { if (nsPtrs[m] != NULL) { CViewProvObjectSink* pSnk = new CViewProvObjectSink(m_ObjSinkArray[x], nsPtrs[m], m); pSnk->AddRef(); BSTR queryBStr = queryStr.AllocSysString(); BSTR queryLBStr = SysAllocString(WBEM_QUERY_LANGUAGE_SQL1); IWbemObjectSink* pQuerySink = pSnk; IWbemContext * t_pCtx = m_Ctx; if (nsPtrs[m]->IsRemote()) { #if 0 #if _NT_TARGET_VERSION < 500 pQuerySink = pSnk->Associate(); #endif #endif t_pCtx = NULL; //don't use context for remote cimoms } IWbemServices *ptmpServ = nsPtrs[m]->GetServerOrProxy(); if (ptmpServ) { if ( pQuerySink ) { HRESULT t_hr = ptmpServ->ExecQueryAsync(queryLBStr, queryBStr, 0, t_pCtx, pQuerySink); if ( FAILED(t_hr) && (HRESULT_FACILITY(t_hr) != FACILITY_ITF) && nsPtrs[m]->IsRemote()) { if ( SUCCEEDED(UpdateConnection(&(nsPtrs[m]), &ptmpServ)) ) { if (ptmpServ) { t_hr = ptmpServ->ExecQueryAsync(queryLBStr, queryBStr, 0, t_pCtx, pQuerySink); } } } if (SUCCEEDED(t_hr)) { if (m_ArrayLock.Lock()) { m_iQueriesAsked++; m_ArrayLock.Unlock(); } else { pSnk->DisAssociate(); } } else { pSnk->DisAssociate(); } } else { pSnk->DisAssociate(); } if (ptmpServ) { nsPtrs[m]->ReturnServerOrProxy(ptmpServ); } } else { pSnk->DisAssociate(); } SysFreeString(queryLBStr); SysFreeString(queryBStr); pSnk->Release(); } else { a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_NAMESPACE ) ; a_ErrorObject.SetWbemStatus ( ( WBEMSTATUS ) m_NSpaceArray[x]->GetServerCreationError () ) ; a_ErrorObject.SetMessage ( L"Failed to send query, invalid or inaccessible namespace" ) ; bStatusSet = TRUE; } } } } } if (m_ArrayLock.Lock()) { m_iQueriesAsked--; if (m_iQueriesAsked != m_iQueriesAnswered) { //just in case this was triggerred while we had yet to ask some queries ResetEvent(m_StatusHandle); } else { //just in case this wasn't triggerred while we were asking queries SetEvent(m_StatusHandle); } m_ArrayLock.Unlock(); } if (m_iQueriesAsked == 0) { if ( ! bStatusSet ) { a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to perform source query(ies), invalid source namespace(s)" ) ; } return FALSE; } else { bWait = TRUE; } return TRUE; } BOOL ExecQueryTaskObject::PerformEnumQueries(WbemProvErrorObject &a_ErrorObject) { m_iQueriesAsked++; ModifySourceQueriesForUserQuery(); m_ObjSinkArray.SetSize(0, m_NSpaceArray.GetSize()); BOOL bStatusSet = FALSE; for (int x = 0; x < m_NSpaceArray.GetSize(); x++) { BOOL bDone = FALSE; int dummyInt; CObjectSinkResults * objSnk = new CObjectSinkResults(this, x); objSnk->AddRef(); m_ObjSinkArray.SetAtGrow(x, objSnk); if (!m_JoinOnArray.IsValid() || m_EnumerateClasses.IsEmpty() || m_EnumerateClasses.Lookup(m_SourceArray[x]->GetClassName(), dummyInt) ) { CStringW queryStr = GetStringFromRPN(m_SourceArray[x]->GetRPNExpression(), 0, NULL); if (queryStr.GetLength() > 0) { CWbemServerWrap** nsPtrs = m_NSpaceArray[x]->GetServerPtrs(); for (int m = 0; m < m_NSpaceArray[x]->GetCount(); m++) { if (nsPtrs[m] != NULL) { CViewProvObjectSink* pSnk = new CViewProvObjectSink(objSnk, nsPtrs[m], m); pSnk->AddRef(); BSTR queryBStr = queryStr.AllocSysString(); BSTR queryLBStr = SysAllocString(WBEM_QUERY_LANGUAGE_SQL1); IWbemObjectSink* pQuerySink = pSnk; IWbemContext * t_pCtx = m_Ctx; if (nsPtrs[m]->IsRemote()) { #if 0 #if _NT_TARGET_VERSION < 500 pQuerySink = pSnk->Associate(); #endif #endif t_pCtx = NULL; //don't use context for remote cimoms } IWbemServices *ptmpServ = nsPtrs[m]->GetServerOrProxy(); if (ptmpServ) { if ( pQuerySink ) { HRESULT t_hr = ptmpServ->ExecQueryAsync(queryLBStr, queryBStr, 0, t_pCtx, pQuerySink); if ( FAILED(t_hr) && (HRESULT_FACILITY(t_hr) != FACILITY_ITF) && nsPtrs[m]->IsRemote()) { if ( SUCCEEDED(UpdateConnection(&(nsPtrs[m]), &ptmpServ)) ) { if (ptmpServ) { t_hr = ptmpServ->ExecQueryAsync(queryLBStr, queryBStr, 0, t_pCtx, pQuerySink); } } } if (SUCCEEDED(t_hr)) { if (m_ArrayLock.Lock()) { m_iQueriesAsked++; m_ArrayLock.Unlock(); } else { pSnk->DisAssociate(); } } else { pSnk->DisAssociate(); } } else { pSnk->DisAssociate(); } if (ptmpServ) { nsPtrs[m]->ReturnServerOrProxy(ptmpServ); } } else { pSnk->DisAssociate(); } pSnk->Release(); SysFreeString(queryBStr); SysFreeString(queryLBStr); } else { a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_NAMESPACE ) ; a_ErrorObject.SetWbemStatus ( ( WBEMSTATUS ) m_NSpaceArray[x]->GetServerCreationError () ) ; a_ErrorObject.SetMessage ( L"Failed to send query, invalid or inaccessible namespace" ) ; bStatusSet = TRUE; } } } } } if (m_ArrayLock.Lock()) { m_iQueriesAsked--; if (m_iQueriesAsked != m_iQueriesAnswered) { //just in case this was triggerred while we had yet to ask some queries ResetEvent(m_StatusHandle); } else { //just in case this wasn't triggerred while we were asking queries SetEvent(m_StatusHandle); } m_ArrayLock.Unlock(); } if (m_iQueriesAsked == 0) { if ( ! bStatusSet ) { a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Failed to perform source query(ies), invalid source namespace(s)" ) ; } return FALSE; } return TRUE; } BOOL ExecQueryTaskObject::ProcessResults(WbemProvErrorObject &a_ErrorObject) { BOOL retVal = TRUE; int indexCnt = 0; for (int x = 0; retVal && (x < m_ObjSinkArray.GetSize()); x++) { if (m_ObjSinkArray[x]->IsSet()) { if (SUCCEEDED(m_ObjSinkArray[x]->GetResult())) { DWORD dwCount = m_ObjSinkArray[x]->m_ObjArray.GetSize(); if (0 < dwCount) { indexCnt++; } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ; a_ErrorObject.SetWbemStatus ( ( WBEMSTATUS ) m_ObjSinkArray[x]->GetResult() ) ; a_ErrorObject.SetMessage ( L"Object path and Class qualifiers resulted in a failed query." ) ; } } else { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ; a_ErrorObject.SetMessage ( L"Invalid source namespace path OR object path and Class qualifiers resulted in a failed query." ) ; } } if (0 == indexCnt) { if (retVal) { retVal = FALSE; a_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_FOUND ) ; a_ErrorObject.SetWbemStatus ( WBEM_E_NOT_FOUND ) ; a_ErrorObject.SetMessage ( L"No source objects found to support view object path." ) ; } CleanUpObjSinks(); } else { if (m_JoinOnArray.IsValid()) { #ifdef VP_PERFORMANT_JOINS BOOL t_bRes = CreateAndIndicateJoinsPerf(a_ErrorObject, m_bSingleton); #else BOOL t_bRes = CreateAndIndicateJoins(a_ErrorObject, m_bSingleton); #endif retVal = retVal && t_bRes; } else //union or association { if ((m_bSingleton) && (indexCnt > 1)) { 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." ) ; CleanUpObjSinks(); } else { BOOL t_bRes = CreateAndIndicateUnions(a_ErrorObject, -1); retVal = retVal && t_bRes; } } } return retVal; } BOOL ExecQueryTaskObject :: ExecQuery () { BOOL t_Status ; DebugOut2( CViewProvServ::sm_debugLog->WriteFileAndLine ( _T(__FILE__),__LINE__, _T("ExecQueryTaskObject :: ExecQuery\r\n") ) ; ) if ( _wcsicmp ( m_QueryFormat , WBEM_QUERY_LANGUAGE_SQL1 ) == 0 ) { CTextLexSource querySource(m_Query); SQL1_Parser sqlParser(&querySource) ; t_Status = ! sqlParser.Parse ( & m_RPNExpression ) ; if ( t_Status ) { t_Status = SetClass(m_RPNExpression->bsClassName) ; if ( t_Status ) { t_Status = ParseAndProcessClassQualifiers(m_ErrorObject); if (t_Status) { t_Status = PerformQuery(m_ErrorObject); } } else { t_Status = FALSE ; m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ; m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_CLASS ) ; m_ErrorObject.SetMessage ( L"Unknown Class" ) ; DebugOut2( CViewProvServ::sm_debugLog->WriteFileAndLine ( _T(__FILE__),__LINE__, _T("ExecQueryTaskObject :: ExecQuery:Unknown Class\r\n") ) ; ) } } else { t_Status = FALSE ; m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_QUERY ) ; m_ErrorObject.SetWbemStatus ( WBEM_E_PROVIDER_NOT_CAPABLE ) ; m_ErrorObject.SetMessage ( L"WQL query was invalid for this provider" ) ; DebugOut2( CViewProvServ::sm_debugLog->WriteFileAndLine ( _T(__FILE__),__LINE__, _T("ExecQueryTaskObject :: ExecQuery:WQL query was invalid for this provider\r\n") ) ; ) } } else { t_Status = FALSE ; m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_QUERY_TYPE ) ; m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_QUERY_TYPE ) ; m_ErrorObject.SetMessage ( L"Query Language not supported" ) ; DebugOut2( CViewProvServ::sm_debugLog->WriteFileAndLine ( _T(__FILE__),__LINE__, _T("ExecQueryTaskObject :: ExecQuery:Query Language not supported\r\n") ) ; ) } DebugOut2( CViewProvServ::sm_debugLog->WriteFileAndLine ( _T(__FILE__),__LINE__, _T("ExecQueryTaskObject :: ExecQuery:Returning %lx\r\n"), t_Status ) ; ) return t_Status ; }