//*************************************************************************** // // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved // // FRQueryEx.cpp // // Purpose: Extended query support functions // //*************************************************************************** #include "precomp.h" #include #include #include #include #include #include "multiplat.h" CFrameworkQueryEx::CFrameworkQueryEx() { } CFrameworkQueryEx::~CFrameworkQueryEx() { } // See comments in header BOOL CFrameworkQueryEx::Is3TokenOR(LPCWSTR wszProp1, LPCWSTR wszProp2, VARIANT &vVar1, VARIANT &vVar2) { BOOL bRet = FALSE; if ((m_pLevel1RPNExpression != NULL) && (m_pLevel1RPNExpression->nNumTokens == 3) && (m_pLevel1RPNExpression->pArrayOfTokens[2].nTokenType == SQL_LEVEL_1_TOKEN::TOKEN_OR) && (m_pLevel1RPNExpression->pArrayOfTokens[0].nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION) && (m_pLevel1RPNExpression->pArrayOfTokens[1].nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION) && (m_pLevel1RPNExpression->pArrayOfTokens[0].nOperator == SQL_LEVEL_1_TOKEN::OP_EQUAL) && (m_pLevel1RPNExpression->pArrayOfTokens[1].nOperator == SQL_LEVEL_1_TOKEN::OP_EQUAL) ) { if ( (_wcsicmp(m_pLevel1RPNExpression->pArrayOfTokens[0].pPropertyName, wszProp1) == 0) && (_wcsicmp(m_pLevel1RPNExpression->pArrayOfTokens[1].pPropertyName, wszProp2) == 0)) { VariantClear(&vVar1); VariantClear(&vVar2); if (FAILED(VariantCopy(&vVar1, &m_pLevel1RPNExpression->pArrayOfTokens[0].vConstValue)) || FAILED(VariantCopy(&vVar2, &m_pLevel1RPNExpression->pArrayOfTokens[1].vConstValue)) ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } bRet = TRUE; } else if ( (_wcsicmp(m_pLevel1RPNExpression->pArrayOfTokens[0].pPropertyName, wszProp2) == 0) && (_wcsicmp(m_pLevel1RPNExpression->pArrayOfTokens[1].pPropertyName, wszProp1) == 0)) { VariantClear(&vVar1); VariantClear(&vVar2); if (FAILED(VariantCopy(&vVar1, &m_pLevel1RPNExpression->pArrayOfTokens[1].vConstValue)) || FAILED(VariantCopy(&vVar2, &m_pLevel1RPNExpression->pArrayOfTokens[0].vConstValue)) ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } bRet = TRUE; } } return bRet; } // See comments in header BOOL CFrameworkQueryEx::IsNTokenAnd(CHStringArray &sarr, CHPtrArray &sPtrArr) { BOOL bRet = FALSE; if (m_pLevel1RPNExpression != NULL) { // Walk all the tokens for (DWORD x = 0; x < m_pLevel1RPNExpression->nNumTokens; x++) { // If this is an expression token, and the expression is of type '=' if ((m_pLevel1RPNExpression->pArrayOfTokens[x].nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION) && (m_pLevel1RPNExpression->pArrayOfTokens[x].nOperator == SQL_LEVEL_1_TOKEN::OP_EQUAL)) { // convert the property name to upper case. This facilitates checking // to see if it is already in the list. _wcsupr(m_pLevel1RPNExpression->pArrayOfTokens[x].pPropertyName); // Check to see if we have already seen this property. if (IsInList(sarr, m_pLevel1RPNExpression->pArrayOfTokens[x].pPropertyName) == -1) { // Add the name to the list sarr.Add(m_pLevel1RPNExpression->pArrayOfTokens[x].pPropertyName); // Create a new variant for the value and add it to the list LPVOID pValue = new variant_t(m_pLevel1RPNExpression->pArrayOfTokens[x].vConstValue); try { sPtrArr.Add(pValue); } catch ( ... ) { delete pValue; sarr.RemoveAll(); DWORD dwSize = sPtrArr.GetSize(); for (x = 0; x < dwSize; x++) { delete sPtrArr[x]; } sPtrArr.RemoveAll(); throw ; } bRet = TRUE; } else { // Already in list bRet = FALSE; break; } } // It wasn't an expression token, if it's not AND, we've failed. else if (m_pLevel1RPNExpression->pArrayOfTokens[x].nTokenType != SQL_LEVEL_1_TOKEN::TOKEN_AND) { bRet = FALSE; break; } } // If this didn't work, let's clean the CHPtrArray and CHStringArray if (!bRet) { sarr.RemoveAll(); DWORD dwSize = sPtrArr.GetSize(); for (x = 0; x < dwSize; x++) { delete sPtrArr[x]; } sPtrArr.RemoveAll(); } } return bRet; } // see comments in header HRESULT CFrameworkQueryEx::GetValuesForProp(LPCWSTR wszPropName, std::vector& vectorValues) { HRESULT hr = WBEM_S_NO_ERROR; if (m_pLevel1RPNExpression != NULL) { hr = CQueryAnalyser::GetValuesForProp(m_pLevel1RPNExpression, wszPropName, vectorValues); if (SUCCEEDED(hr)) { // Remove duplicates for (int x = 1; x < vectorValues.size(); x++) { for (int y = 0; y < x; y++) { if (vectorValues[y] == vectorValues[x]) { vectorValues.erase(vectorValues.begin() + x); x--; } } } } else { vectorValues.clear(); if (hr == WBEMESS_E_REGISTRATION_TOO_BROAD) { hr = WBEM_S_NO_ERROR; } } } else { ASSERT_BREAK(FALSE); vectorValues.clear(); hr = WBEM_E_FAILED; } return hr; } // see comments in header HRESULT CFrameworkQueryEx::GetValuesForProp(LPCWSTR wszPropName, std::vector<_variant_t>& vectorValues) { HRESULT hr = WBEM_S_NO_ERROR; if (wszPropName && (m_pLevel1RPNExpression != NULL)) { hr = CQueryAnalyser::GetValuesForProp(m_pLevel1RPNExpression, wszPropName, vectorValues); if (SUCCEEDED(hr)) { // If this is a reference property, we need to normalize the names to a common form // so the removal of duplicates works correctly. if (IsReference(wszPropName)) { // Get the current computer name CHString sOutPath, sComputerName; DWORD dwBufferLength = MAX_COMPUTERNAME_LENGTH + 1; FRGetComputerName(sComputerName.GetBuffer( dwBufferLength ), &dwBufferLength); sComputerName.ReleaseBuffer(); if (sComputerName.IsEmpty()) { sComputerName = L"DEFAULT"; } DWORD dwRet = e_OK; // Normalize the path names. Try leaving the property names alone for (int x = 0; x < vectorValues.size(); x++) { // If we failed to parse the path, or if the namespace isn't our namespace, delete // the entry. if ( (V_VT(&vectorValues[x]) == VT_BSTR) && (dwRet = NormalizePath(V_BSTR(&vectorValues[x]), sComputerName, GetNamespace(), 0, sOutPath)) == e_OK) { vectorValues[x] = sOutPath; } else if (dwRet == e_NullName) { break; } else { vectorValues.erase(vectorValues.begin() + x); x--; } } // If the key property names of any of the values were null, we have to set them all // to null. if (dwRet == e_NullName) { for (int x = 0; x < vectorValues.size(); x++) { // If we failed to parse the path, or if the namespace isn't our namespace, delete // the entry. if ( (V_VT(&vectorValues[x]) == VT_BSTR) && (dwRet = NormalizePath(V_BSTR(&vectorValues[x]), sComputerName, GetNamespace(), NORMALIZE_NULL, sOutPath)) == e_OK) { vectorValues[x] = sOutPath; } else { vectorValues.erase(vectorValues.begin() + x); x--; } } } } // Remove duplicates for (int x = 1; x < vectorValues.size(); x++) { for (int y = 0; y < x; y++) { if (vectorValues[y] == vectorValues[x]) { vectorValues.erase(vectorValues.begin() + x); x--; } } } } else { vectorValues.clear(); if (hr == WBEMESS_E_REGISTRATION_TOO_BROAD) { hr = WBEM_S_NO_ERROR; } } } else { ASSERT_BREAK(FALSE); vectorValues.clear(); hr = WBEM_E_FAILED; } return hr; } // See comments in header void CFrameworkQueryEx::GetPropertyBitMask(const CHPtrArray &Properties, LPVOID pBits) { if (AllPropertiesAreRequired()) { SetAllBits(pBits, Properties.GetSize()); } else { ZeroAllBits(pBits, Properties.GetSize()); CHString sProperty; for (DWORD x=0; x < Properties.GetSize(); x++) { sProperty = (WCHAR *)Properties[x]; sProperty.MakeUpper(); if (IsInList(m_csaPropertiesRequired, sProperty) != -1) { SetBit(pBits, x); } } } } HRESULT CFrameworkQueryEx::InitEx( const BSTR bstrQueryFormat, const BSTR bstrQuery, long lFlags, CHString &sNamespace ) { HRESULT hr = WBEM_S_NO_ERROR; // parse the query using the parsing interface IWbemQueryPtr pQueryInterface(CLSID_WbemQuery); hr = pQueryInterface->Parse(bstrQueryFormat, bstrQuery, 0); if (SUCCEEDED(hr)) { ULONG uFeatureCount = WMIQ_LF_LAST; ULONG uFeatures[WMIQ_LF_LAST]; hr = pQueryInterface->TestLanguageFeatures(0, &uFeatureCount, uFeatures); if (SUCCEEDED(hr)) { if (uFeatures[0] == WMIQ_LF1_BASIC_SELECT) { // if this is a nova compatible select statement hr = Init(bstrQueryFormat, bstrQuery, lFlags, sNamespace); } else if (uFeatures[0] == WMIQ_LF18_ASSOCIATONS) // add others? { // Save the detailed query m_sQueryEx = bstrQuery; // create select statement from class name SWbemAssocQueryInf aqfBuff; hr = pQueryInterface->GetQueryInfo(WMIQ_ANALYSIS_ASSOC_QUERY, WMIQ_ASSOCQ_ASSOCIATORS, sizeof(aqfBuff), &aqfBuff); if (SUCCEEDED(hr)) { CHString sQuery; // I don't know how to tell if this is an associators or a reference if (true) { sQuery.Format(L"Select * from %s", aqfBuff.m_pszAssocClass); } // Store the more basic query hr = Init(bstrQueryFormat, bstrQuery, lFlags, sNamespace); } } else { hr = WBEM_E_INVALID_QUERY; } } } return hr; } bool CFrameworkQueryEx::IsExtended() { return !m_sQueryEx.IsEmpty(); }