2025-04-27 07:49:33 -04:00

1841 lines
62 KiB
C++

//***************************************************************************
//
// (c) 1999-2001 by Microsoft Corp. All Rights Reserved.
//
// eseitrtr.cpp
//
// cvadai 19-Mar-99 Created as prototype for Quasar.
//
//***************************************************************************
#define _ESEIT_CPP_
#pragma warning( disable : 4786 ) // identifier was truncated to 'number' characters in the
#pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
#include "precomp.h"
#include <std.h>
#include <smrtptr.h>
#include <repdrvr.h>
#include <eseitrtr.h>
#include <eseutils.h>
#include <eseobjs.h>
#include <reputils.h>
#include <wbemint.h>
#include <repcache.h>
#include <like.h>
#include <datepart.h>
typedef std::map <DWORD, DWORD> Properties;
//***************************************************************************
//
// CWmiESEIterator::CWmiESEIterator
//
//***************************************************************************
CWmiESEIterator::CWmiESEIterator()
{
m_pSession = NULL;
m_uRefCount = 0;
m_pConn = NULL;
m_pToks = NULL;
m_bFirst = TRUE;
m_bEnum = FALSE;
m_bWQL = FALSE;
m_iStartPos = 0;
m_iLastPos = 0;
m_bClasses = FALSE;
}
//***************************************************************************
//
// CWmiESEIterator::~CWmiESEIterator
//
//***************************************************************************
CWmiESEIterator::~CWmiESEIterator()
{
Cancel(0);
if (m_pSession)
m_pSession->Release();
delete m_pToks;
}
//***************************************************************************
//
// CWmiESEIterator::QueryInterface
//
//***************************************************************************
HRESULT STDMETHODCALLTYPE CWmiESEIterator::QueryInterface
(REFIID riid,
void __RPC_FAR *__RPC_FAR *ppvObject)
{
*ppvObject = 0;
if (IID_IUnknown==riid || IID_IWmiDbIterator==riid )
{
*ppvObject = (IWmiDbIterator *)this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//***************************************************************************
//
// CWmiESEIterator::AddRef
//
//***************************************************************************
ULONG STDMETHODCALLTYPE CWmiESEIterator::AddRef()
{
InterlockedIncrement((LONG *) &m_uRefCount);
return m_uRefCount;
}
//***************************************************************************
//
// CWmiESEIterator::Release
//
//***************************************************************************
ULONG STDMETHODCALLTYPE CWmiESEIterator::Release()
{
ULONG uNewCount = InterlockedDecrement((LONG *) &m_uRefCount);
if (0 != uNewCount)
return uNewCount;
delete this;
return WBEM_S_NO_ERROR;
}
//***************************************************************************
//
// CWmiESEIterator::Cancel
//
//***************************************************************************
HRESULT STDMETHODCALLTYPE CWmiESEIterator::Cancel(
/* [in] */ DWORD dwFlags)
{
HRESULT hr = WBEM_S_NO_ERROR;
if (m_pConn)
{
if (m_pSession->m_pController)
((CWmiDbController *)m_pSession->m_pController)->ConnCache.ReleaseConnection(m_pConn, hr);
m_pConn = NULL;
}
if (m_pSession)
((CWmiDbSession *)m_pSession)->UnlockDynasties();
return hr;
}
//***************************************************************************
//
// CWmiESEIterator::NextBatch
//
//***************************************************************************
HRESULT STDMETHODCALLTYPE CWmiESEIterator::NextBatch(
/* [in] */ DWORD dwNumRequested,
/* [in] */ DWORD dwTimeOutSeconds,
/* [in] */ DWORD dwFlags,
/* [in] */ DWORD dwRequestedHandleType,
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwNumReturned,
/* [iid_is][length_is][size_is][out] */ LPVOID __RPC_FAR *ppObjects)
{
HRESULT hr = WBEM_S_NO_ERROR, hrRet = WBEM_S_NO_ERROR;
bool bImmediate = !(dwRequestedHandleType & WMIDB_HANDLE_TYPE_SUBSCOPED);
hr = TestDriverStatus();
if (FAILED(hr))
return hr;
if (!dwNumRequested || !ppObjects)
return WBEM_E_INVALID_PARAMETER;
if (dwRequestedHandleType == WMIDB_HANDLE_TYPE_INVALID &&
riid == IID_IWmiDbHandle)
return WBEM_E_INVALID_PARAMETER;
if (dwFlags & WMIDB_FLAG_LOOKAHEAD ||
(riid != IID_IWmiDbHandle &&
riid != IID_IWbemClassObject &&
riid != IID__IWmiObject))
/// UuidCompare(pIIDRequestedInterface, &IID_IWmiDbHandle, NULL) ||
// UuidCompare(pIIDRequestedInterface, &IID_IWbemClassObject, NULL))
return WBEM_E_NOT_SUPPORTED;
// Read the current row, compare it against m_pToks
// Continue until we run out of rows, or meet the requested number.
LPWSTR lpKey = NULL;
try
{
SQL_ID dObjectId = 0, dClassId = 0, dScopeId = 0;
int iNumRetrieved = 0;
hr = GetFirstMatch(dObjectId, dClassId, dScopeId, &lpKey);
while (SUCCEEDED(hr) )
{
CDeleteMe <wchar_t> d (lpKey);
hr = ((CWmiDbSession *)m_pSession)->VerifyObjectSecurity(NULL, dObjectId, dClassId, dScopeId, 0, WBEM_ENABLE);
if (SUCCEEDED(hr))
{
if (FAILED(hr = TestDriverStatus()))
break;
if (riid == IID_IWmiDbHandle)
{
CWmiDbHandle *pTemp = new CWmiDbHandle;
if (pTemp)
{
((CWmiDbSession *)m_pSession)->AddRef_Lock();
DWORD dwVersion = 0;
// Obtain a lock for this object
// =============================
hr = ((CWmiDbController *)m_pSession->m_pController)->LockCache.AddLock(bImmediate, dObjectId, dwRequestedHandleType, pTemp,
dScopeId, dClassId, &((CWmiDbController *)m_pSession->m_pController)->SchemaCache, false,
0, 0, &dwVersion);
if (FAILED(hr))
{
delete pTemp;
// If they failed to get a handle, what do we do?
// Ignore it and continue, I guess.
hrRet = WBEM_S_PARTIAL_RESULTS;
ppObjects[iNumRetrieved] = NULL;
}
else
{
pTemp->m_pSession = m_pSession;
pTemp->AddRef();
((CWmiDbController *)m_pSession->m_pController)->AddHandle();
pTemp->m_dwVersion = dwVersion;
pTemp->m_dwHandleType = dwRequestedHandleType;
pTemp->m_dClassId = dClassId;
pTemp->m_dObjectId = dObjectId;
if (pTemp->m_dClassId == MAPPEDNSCLASSID)
pTemp->m_bDefault = FALSE;
if (dwFlags & WBEM_FLAG_USE_SECURITY_DESCRIPTOR)
pTemp->m_bSecDesc = TRUE;
pTemp->m_dScopeId = dScopeId;
ppObjects[iNumRetrieved] = pTemp;
}
iNumRetrieved++;
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
else if (riid == IID_IWbemClassObject ||
riid == IID__IWmiObject)
{
IWbemClassObject *pTemp = NULL;
DWORD dwVer = 0;
if (m_dwOpenTable == OPENTABLE_CLASSMAP)
{
// If this is a class, we need to populate it on
// a different connection, so we don't lose our
// pointer into the db.
CSQLConnection *pConn = NULL;
if (((CWmiDbSession *)m_pSession)->m_pController)
{
hr = ((CWmiDbController *)((CWmiDbSession *)m_pSession)->m_pController)->ConnCache.GetConnection(&pConn, FALSE, FALSE);
if (SUCCEEDED(hr))
{
hr = ((CWmiDbSession *)m_pSession)->GetObjectData(pConn, dObjectId, dClassId, dScopeId,
0, dwVer, &pTemp, TRUE, lpKey, dwFlags & WBEM_FLAG_USE_SECURITY_DESCRIPTOR);
if (((CWmiDbSession *)m_pSession)->m_pController)
((CWmiDbController *)((CWmiDbSession *)m_pSession)->m_pController)->ConnCache.ReleaseConnection(pConn, hr, FALSE);
}
}
}
else if (m_dwOpenTable == OPENTABLE_INDEXREF)
{
CSQLConnection *pConn = NULL;
if (((CWmiDbSession *)m_pSession)->m_pController)
{
hr = ((CWmiDbController *)((CWmiDbSession *)m_pSession)->m_pController)->ConnCache.GetConnection(&pConn, FALSE, FALSE);
if (SUCCEEDED(hr))
{
m_pSession->LoadClassInfo(pConn, dClassId, FALSE);
hr = ((CWmiDbSession *)m_pSession)->GetObjectData(pConn, dObjectId, dClassId, dScopeId,
0, dwVer, &pTemp, TRUE, lpKey, dwFlags & WBEM_FLAG_USE_SECURITY_DESCRIPTOR);
if (((CWmiDbSession *)m_pSession)->m_pController)
((CWmiDbController *)((CWmiDbSession *)m_pSession)->m_pController)->ConnCache.ReleaseConnection(pConn, hr, FALSE);
}
}
}
else
{
hr = ((CWmiDbSession *)m_pSession)->GetObjectData(m_pConn, dObjectId, dClassId, dScopeId,
0, dwVer, &pTemp, TRUE, lpKey, dwFlags & WBEM_FLAG_USE_SECURITY_DESCRIPTOR);
}
ppObjects[iNumRetrieved] = pTemp;
if (FAILED(hr))
hrRet = WBEM_S_PARTIAL_RESULTS;
else
iNumRetrieved++;
}
}
else
hrRet = WBEM_S_PARTIAL_RESULTS;
hr = TestDriverStatus();
if (SUCCEEDED(hr))
{
if (m_pSession && ((CWmiDbSession *)m_pSession)->m_pController)
((CWmiDbController *)m_pSession->m_pController)->IncrementHitCount(false);
}
else
break;
if (iNumRetrieved == dwNumRequested)
break;
hr = GetNextMatch(dObjectId, dClassId, dScopeId, &lpKey);
}
if (pdwNumReturned)
*pdwNumReturned = iNumRetrieved;
// Null out m_pStatus if there are no more results!!!
if ((hr == WBEM_S_NO_MORE_DATA || !iNumRetrieved) &&
hr != WBEM_E_SHUTTING_DOWN)
{
hrRet = WBEM_S_NO_MORE_DATA;
Cancel(0);
}
}
catch (...)
{
hr = WBEM_E_CRITICAL_ERROR;
}
return hrRet;
}
//***************************************************************************
//
// CWmiESEIterator::GetFirstMatch
//
//***************************************************************************
HRESULT CWmiESEIterator::GetFirstMatch(SQL_ID &dObjectId, SQL_ID &dClassId, SQL_ID &dScopeId,
LPWSTR * lpKey)
{
HRESULT hr = 0;
// Loop through the table we have chosen to
// scan on, and see if any objects match.
hr = GetNextMatch(dObjectId, dClassId, dScopeId, lpKey, m_bFirst);
m_bFirst = FALSE;
return hr;
}
//***************************************************************************
//
// CWmiESEIterator::GetNextMatch
//
//***************************************************************************
HRESULT CWmiESEIterator::GetNextMatch(SQL_ID &dObjectId, SQL_ID &dClassId,
SQL_ID &dScopeId, LPWSTR * lpKey, BOOL bFirst)
{
HRESULT hr = 0;
OBJECTMAP oj;
CLASSMAP cd;
CONTAINEROBJ co;
INDEXDATA id;
REFERENCEPROPERTIES pm;
DWORD dwType = 0;
if (lpKey)
*lpKey = NULL;
switch(m_dwOpenTable)
{
case OPENTABLE_CLASSMAP:
if (!bFirst)
hr = GetNext_ClassMap(m_pConn, cd);
else
hr = GetClassMapData(m_pConn, ((CESEConnection *)m_pConn)->GetSessionID(), m_tableid, cd);
while (SUCCEEDED(hr))
{
hr = TestDriverStatus();
if (FAILED(hr))
break;
hr = GetFirst_ObjectMap(m_pConn, cd.dClassId, oj);
if (oj.dObjectId != dObjectId && oj.iObjectState != 2)
{
if (ObjectMatches(oj.dObjectId, oj.dClassId, oj.dObjectScopeId))
{
dObjectId = oj.dObjectId;
dClassId = oj.dClassId;
dScopeId = oj.dObjectScopeId;
if (lpKey)
{
if (oj.sObjectKey)
{
LPWSTR lpNew = new wchar_t[wcslen(oj.sObjectKey)+1];
if (lpNew)
{
wcscpy(lpNew, oj.sObjectKey);
*lpKey = lpNew;
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
}
oj.Clear();
break;
}
}
oj.Clear();
hr = GetNext_ClassMap(m_pConn, cd);
}
cd.Clear();
break;
case OPENTABLE_OBJECTMAP:
// If here, the query is too complex to evaluate
// through indices. Scan on each participating
// class.
if (!bFirst)
hr = GetNext_ObjectMap(m_pConn, oj);
else
{
hr = GetObjectMapData(m_pConn, ((CESEConnection *)m_pConn)->GetSessionID(), m_tableid, oj);
}
while (TRUE)
{
while (SUCCEEDED(hr) )
{
hr = TestDriverStatus();
if (FAILED(hr))
break;
if (m_bClasses)
{
if (oj.dClassId != 1)
{
hr = GetNext_ObjectMap(m_pConn, oj);
continue;
}
}
if (oj.dObjectId != dObjectId && oj.iObjectState != 2)
{
if (ObjectMatches(oj.dObjectId, oj.dClassId, oj.dObjectScopeId))
{
dObjectId = oj.dObjectId;
dClassId = oj.dClassId;
dScopeId = oj.dObjectScopeId;
if (lpKey)
{
if (oj.sObjectKey)
{
LPWSTR lpNew = new wchar_t[wcslen(oj.sObjectKey)+1];
if (lpNew)
{
wcscpy(lpNew, oj.sObjectKey);
*lpKey = lpNew;
}
else
hr = WBEM_E_OUT_OF_MEMORY;
}
}
oj.Clear();
break;
}
}
hr = GetNext_ObjectMap(m_pConn, oj);
}
if (!m_bEnum && hr == WBEM_E_NOT_FOUND)
{
// See if there is other class criteria
// We expect each derived class to be
// listed as separate tokens.
DWORD dwNumToks = m_pToks->GetNumTokens();
BOOL bEnd = TRUE;
for (int i = m_iLastPos+1; i < dwNumToks; i++)
{
ESEToken *pTok = m_pToks->GetToken(i);
if (pTok->tokentype == ESE_EXPR_TYPE_EXPR)
{
ESEWQLToken *pTok2 = (ESEWQLToken *)pTok;
if (pTok2->Value.valuetype == ESE_VALUE_TYPE_SYSPROP)
{
if (pTok2->dClassId)
{
hr = GetFirst_ObjectMapByClass(m_pConn, pTok2->dClassId, oj);
if (SUCCEEDED(hr))
{
m_iLastPos = i;
bEnd = FALSE;
break;
}
}
}
}
}
if (bEnd)
break;
}
else
break;
}
break;
case OPENTABLE_INDEXNUMERIC:
case OPENTABLE_INDEXSTRING:
case OPENTABLE_INDEXREAL:
case OPENTABLE_INDEXREF:
// If here, we should have ANDed criteria
// only, or an A AND (B OR C) construct.
// That means we only have to scan once.
if (m_dwOpenTable == OPENTABLE_INDEXNUMERIC)
dwType = SQL_POS_INDEXNUMERIC;
else if (m_dwOpenTable == OPENTABLE_INDEXSTRING)
dwType = SQL_POS_INDEXSTRING;
else if (m_dwOpenTable == OPENTABLE_INDEXREAL)
dwType = SQL_POS_INDEXREAL;
else if (m_dwOpenTable == OPENTABLE_INDEXREF)
dwType = SQL_POS_INDEXREF;
if (m_tableid)
{
if (!bFirst)
hr = GetNext_IndexData(m_pConn, m_tableid, dwType, id);
else
hr = GetIndexData(m_pConn, ((CESEConnection *)m_pConn)->GetSessionID(),
m_tableid, dwType, id);
while (SUCCEEDED(hr))
{
hr = TestDriverStatus();
if (FAILED(hr))
break;
if (id.dObjectId != dObjectId)
{
hr = GetFirst_ObjectMap(m_pConn, id.dObjectId, oj);
if ((oj.iObjectState != 2) && ObjectMatches(id.dObjectId, oj.dClassId, oj.dObjectScopeId, &id,
NULL, &dObjectId, &dClassId, &dScopeId))
{
oj.Clear();
break;
}
oj.Clear();
}
hr = GetNext_IndexData(m_pConn, m_tableid, dwType, id);
}
}
else
hr = WBEM_E_INVALID_QUERY;
break;
case OPENTABLE_CONTAINEROBJS:
if (!bFirst)
hr = GetNext_ContainerObjs(m_pConn, co);
else
hr = GetContainerObjsData(m_pConn, ((CESEConnection *)m_pConn)->GetSessionID(), m_tableid, co);
while (SUCCEEDED(hr))
{
hr = TestDriverStatus();
if (FAILED(hr))
break;
if (co.dContaineeId != dObjectId)
{
hr = GetFirst_ObjectMap(m_pConn, co.dContaineeId, oj);
if ((oj.iObjectState != 2) && ObjectMatches(co.dContaineeId, oj.dClassId, oj.dObjectScopeId))
{
dObjectId = oj.dObjectId;
dClassId = oj.dClassId;
dScopeId = oj.dObjectScopeId;
oj.Clear();
break;
}
oj.Clear();
}
hr = GetNext_ContainerObjs(m_pConn, co);
}
break;
case OPENTABLE_REFPROPS:
if (!bFirst)
hr = GetNext_ReferenceProperties(m_pConn, pm);
else
hr = GetReferencePropertiesData(m_pConn, ((CESEConnection *)m_pConn)->GetSessionID(), m_tableid, pm);
while (SUCCEEDED(hr))
{
hr = TestDriverStatus();
if (FAILED(hr))
break;
if (pm.dClassId != dObjectId)
{
hr = GetFirst_ObjectMap(m_pConn, pm.dClassId, oj);
if (oj.iObjectState != 2 && ObjectMatches(oj.dObjectId, oj.dClassId, oj.dObjectScopeId, NULL,
&pm, &dObjectId, &dClassId, &dScopeId))
{
oj.Clear();
break;
}
oj.Clear();
}
hr = GetNext_ReferenceProperties(m_pConn, pm);
}
break;
default:
hr = WBEM_E_NOT_FOUND;
}
return hr;
}
//***************************************************************************
//
// CWmiESEIterator::SysMatch
//
//***************************************************************************
BOOL CWmiESEIterator::SysMatch (SQL_ID dObjectId, SQL_ID dClassId, SQL_ID dScopeId, ESEToken *pToken)
{
BOOL bRet = FALSE;
HRESULT hr = WBEM_S_NO_ERROR;
ESEWQLToken *pTok = (ESEWQLToken *)pToken;
_bstr_t sName;
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetPropertyInfo
(pTok->dPropertyId, &sName);
if (SUCCEEDED(hr))
{
if (!_wcsicmp(sName, L"__Class"))
{
SQL_ID dClass = 0;
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetClassID
(pTok->Value.sValue, dScopeId, dClass);
if (SUCCEEDED(hr))
{
// Compare if class or instance.
if (dClassId == 1)
bRet = (dClass == dObjectId);
else
bRet = (dClass == dClassId);
}
}
else if (!_wcsicmp(sName, L"__SuperClass"))
{
CLASSMAP cd;
SQL_ID dParent = 1, dClass = 1;
if (wcslen(pTok->Value.sValue))
{
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetClassID
(pTok->Value.sValue, dScopeId, dClass);
if (FAILED(hr))
{
if (m_dwOpenTable != OPENTABLE_CLASSMAP)
{
hr = GetFirst_ClassMapByName(m_pConn, pTok->Value.sValue, cd);
dClass = cd.dClassId;
cd.Clear();
}
else
hr = WBEM_E_NOT_FOUND; // If this was going to match, it would be in the cache...
}
}
if (dClassId == 1)
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetParentId(
dObjectId, dParent);
else
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetParentId(
dClassId, dParent);
if (FAILED(hr))
{
if (dClassId == 1)
{
if (m_dwOpenTable == OPENTABLE_CLASSMAP)
hr = GetClassMapData(m_pConn, ((CESEConnection *)m_pConn)->GetSessionID(), m_tableid, cd);
else
hr = GetFirst_ClassMap(m_pConn, dObjectId, cd);
}
else
hr = GetFirst_ClassMap(m_pConn, dClassId, cd);
dParent = cd.dSuperClassId;
cd.Clear();
}
bRet = (SUCCEEDED(hr) && (dParent == dClass));
}
else if (!_wcsicmp(sName, L"__Derivation"))
{
SQL_ID dClass = 0;
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetClassID
(pTok->Value.sValue, dScopeId, dClass);
if (SUCCEEDED(hr))
{
if (dClassId == 1)
{
if (dObjectId == dClass)
bRet = TRUE;
else
bRet = (BOOL)((CWmiDbController *)m_pSession->m_pController)->
SchemaCache.IsDerivedClass(dClass, dObjectId);
}
else
{
if (dClass == dClassId)
bRet = TRUE;
else
bRet = (BOOL)((CWmiDbController *)m_pSession->m_pController)->
SchemaCache.IsDerivedClass(dClass, dClassId);
}
}
}
else if (!_wcsicmp(sName, L"__Dynasty"))
{
SQL_ID dClass = 0;
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetClassID
(pTok->Value.sValue, dScopeId, dClass);
if (SUCCEEDED(hr))
{
if (dClassId == 1)
bRet = (BOOL)((CWmiDbController *)m_pSession->m_pController)->
SchemaCache.IsDerivedClass(dClass, dObjectId);
else
bRet = (BOOL)((CWmiDbController *)m_pSession->m_pController)->
SchemaCache.IsDerivedClass(dClass, dClassId);
if (bRet)
{
SQL_ID dParent = 0;
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetParentId(
dClass, dParent);
if (SUCCEEDED(hr) && dParent == 1)
bRet = TRUE;
}
}
}
else if (!_wcsicmp(sName, L"__Genus"))
{
if (pTok->Value.dValue == 1)
bRet = (dClassId == 1);
else
bRet = (dClassId != 1);
}
else if (!_wcsicmp(sName, L"__Server"))
{
bRet = (!_wcsicmp(pTok->Value.sValue, m_pSession->m_sMachineName));
}
else if (!_wcsicmp(sName, L"__Namespace"))
{
bRet = (!_wcsnicmp(pTok->Value.sValue, m_pSession->m_sNamespacePath, wcslen(m_pSession->m_sNamespacePath)));
if (bRet)
{
_bstr_t sName;
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetNamespaceName(dScopeId, &sName);
if (SUCCEEDED(hr))
{
WCHAR *pTemp2 = (LPWSTR)pTok->Value.sValue;
pTemp2 += (wcslen(m_pSession->m_sNamespacePath)+1);
bRet = (!_wcsicmp(sName, pTemp2));
}
}
}
else if (!_wcsicmp(sName, L"__Property_Count"))
{
Properties props;
DWORD dwNumProps = 0;
if (dClassId == 1)
{
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetPropertyList(dObjectId, props, &dwNumProps);
if (SUCCEEDED(hr))
{
bRet = (dwNumProps == pTok->Value.dValue);
}
}
else
{
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetPropertyList(dClassId, props, &dwNumProps);
if (SUCCEEDED(hr))
{
bRet = (dwNumProps == pTok->Value.dValue);
}
}
}
else if (!_wcsicmp(sName, L"__Path"))
{
bRet = TRUE; // post-filter, since we don't know our true path.
}
else if (!_wcsicmp(sName, L"__RelPath"))
{
OBJECTMAP oj;
hr = GetObjectMapData(m_pConn, ((CESEConnection *)m_pConn)->GetSessionID(), m_tableid, oj);
if (SUCCEEDED(hr))
{
WCHAR *pPtr = (LPWSTR)oj.sObjectPath;
WCHAR *pLast = NULL;
while (pPtr && *pPtr)
{
if (*pPtr == L':')
pLast = pPtr;
pPtr++;
}
if (pLast)
pLast++;
else
pLast = (LPWSTR)pTok->Value.sValue;
if (pLast)
bRet = (!_wcsicmp(pTok->Value.sValue, pLast));
else
bRet = FALSE;
}
oj.Clear();
}
else
{
bRet = FALSE; // Others not supported.
}
}
// We only support equal and not equal for system properties.
if (SUCCEEDED(hr) && pTok->optype == WQL_TOK_NE)
bRet = !bRet;
return bRet;
}
//***************************************************************************
//
// Match helper functions
//
//***************************************************************************
BOOL MatchNumeric (SQL_ID dLeft, SQL_ID dRight, DWORD dwOp, SQL_ID dThird=0)
{
BOOL bRet = FALSE;
switch(dwOp)
{
case WQL_TOK_BETWEEN:
bRet = (dLeft >= dRight);
if (bRet)
bRet = (dRight >= dThird);
break;
case WQL_TOK_EQ:
bRet = (dLeft == dRight);
break;
case WQL_TOK_GT:
bRet = (dLeft > dRight);
break;
case WQL_TOK_GE:
bRet = (dLeft >= dRight);
break;
case WQL_TOK_LT:
bRet = (dLeft < dRight);
break;
case WQL_TOK_LE:
bRet = (dLeft <= dRight);
break;
case WQL_TOK_NE:
bRet = (dLeft != dRight);
break;
}
return bRet;
}
BOOL MatchString (LPWSTR lpLeft, LPWSTR lpRight, DWORD dwOp, LPWSTR lpThird=0)
{
BOOL bRet = FALSE;
if (!lpLeft || !lpRight)
return FALSE;
switch(dwOp)
{
case WQL_TOK_BETWEEN:
bRet = (_wcsicmp(lpRight, lpLeft) >= 0) ? TRUE: FALSE;
if (bRet)
bRet = (_wcsicmp(lpRight, lpThird) >= 0)? TRUE: FALSE;
break;
case WQL_TOK_LIKE:
{
CLike c (lpRight);
bRet = c.Match(lpLeft);
}
break;
case WQL_TOK_NOT_LIKE:
{
CLike c (lpRight);
bRet = !(c.Match(lpLeft));
}
break;
case WQL_TOK_EQ:
bRet = (!_wcsicmp(lpLeft, lpRight));
break;
case WQL_TOK_GT:
bRet = (_wcsicmp(lpLeft, lpRight) > 0 ? TRUE: FALSE);
break;
case WQL_TOK_GE:
bRet = (_wcsicmp(lpLeft, lpRight) >= 0 ? TRUE: FALSE);
break;
case WQL_TOK_LT:
bRet = (_wcsicmp(lpLeft, lpRight) < 0 ? TRUE: FALSE);
break;
case WQL_TOK_LE:
bRet = (_wcsicmp(lpLeft, lpRight) <= 0 ? TRUE: FALSE);
break;
case WQL_TOK_NE:
bRet = (_wcsicmp(lpLeft, lpRight));
break;
}
return bRet;
}
BOOL MatchDouble (double dLeft, double dRight, DWORD dwOp, double dThird=0)
{
BOOL bRet = FALSE;
switch(dwOp)
{
case WQL_TOK_BETWEEN:
bRet = (dRight >= dLeft);
if (bRet)
bRet = (dLeft >= dThird);
break;
case WQL_TOK_EQ:
bRet = (dLeft == dRight);
break;
case WQL_TOK_GT:
bRet = (dLeft > dRight);
break;
case WQL_TOK_GE:
bRet = (dLeft >= dRight);
break;
case WQL_TOK_LT:
bRet = (dLeft < dRight);
break;
case WQL_TOK_LE:
bRet = (dLeft <= dRight);
break;
case WQL_TOK_NE:
bRet = (dLeft != dRight);
break;
}
return bRet;
}
SQL_ID GetDatePart(DWORD dwFunc, LPWSTR lpValue)
{
int dValue = 0;
HRESULT hr = 0;
CDatePart dp;
dp.SetDate(lpValue);
switch(dwFunc)
{
case ESE_FUNCTION_DATEPART_MONTH:
hr = dp.GetPart(DATEPART_MONTH, &dValue);
break;
case ESE_FUNCTION_DATEPART_YEAR:
hr = dp.GetPart(DATEPART_YEAR, &dValue);
break;
case ESE_FUNCTION_DATEPART_DAY:
hr = dp.GetPart(DATEPART_DAY, &dValue);
break;
case ESE_FUNCTION_DATEPART_HOUR:
hr = dp.GetPart(DATEPART_HOUR, &dValue);
break;
case ESE_FUNCTION_DATEPART_MINUTE:
hr = dp.GetPart(DATEPART_MINUTE, &dValue);
break;
case ESE_FUNCTION_DATEPART_SECOND:
hr = dp.GetPart(DATEPART_SECOND, &dValue);
break;
case ESE_FUNCTION_DATEPART_MILLISECOND:
hr = dp.GetPart(DATEPART_MILLISECOND, &dValue);
break;
default:
break;
}
if (FAILED(hr))
dValue = -1;
return dValue;
}
//***************************************************************************
//
// CWmiESEIterator::PropMatch
//
//***************************************************************************
BOOL CWmiESEIterator::PropMatch(CLASSDATA cd, CLASSDATA cd2, ESEWQLToken *pToken)
{
BOOL bRet = FALSE;
SQL_ID dValue = 0, dCompValue = 0;
if (pToken->Value.dwFunc ||
pToken->CompValue.dwFunc)
{
if (cd.sPropertyStringValue)
dValue = GetDatePart(pToken->Value.dwFunc, cd.sPropertyStringValue);
if (cd2.sPropertyStringValue)
dCompValue = GetDatePart(pToken->CompValue.dwFunc, cd2.sPropertyStringValue);
}
switch(pToken->Value.valuetype)
{
case ESE_VALUE_TYPE_SQL_ID:
if (!dValue)
dValue = cd.dPropertyNumericValue;
if (!dCompValue)
dCompValue = cd2.dPropertyNumericValue;
bRet = MatchNumeric(dValue, dCompValue,
pToken->optype, 0);
break;
case ESE_VALUE_TYPE_STRING:
bRet = MatchString(cd.sPropertyStringValue, cd2.sPropertyStringValue,
pToken->optype, 0);
break;
case ESE_VALUE_TYPE_REAL:
bRet = MatchDouble(cd.rPropertyRealValue, cd2.rPropertyRealValue,
pToken->optype, 0);
break;
default:
bRet = FALSE;
break;
}
return bRet;
}
//***************************************************************************
//
// CWmiESEIterator::Match
//
//***************************************************************************
BOOL CWmiESEIterator::Match (CLASSDATA cd, ESEToken *pTok)
{
BOOL bRet = FALSE;
ESEWQLToken *pToken = (ESEWQLToken *)pTok;
if (pToken->tokentype == ESE_EXPR_TYPE_EXPR)
{
if (pToken->optype == WQL_TOK_ISNULL)
{
if (cd.iFlags & ESE_FLAG_NULL)
bRet = TRUE;
}
else if (pToken->optype == WQL_TOK_NOT_NULL)
{
if (!(cd.iFlags & ESE_FLAG_NULL))
bRet = TRUE;
}
else
{
SQL_ID dValue = 0, dCompValue = 0;
if (pToken->Value.dwFunc ||
pToken->CompValue.dwFunc)
{
if (cd.sPropertyStringValue)
{
dValue = GetDatePart(pToken->Value.dwFunc, cd.sPropertyStringValue);
dCompValue = GetDatePart(pToken->CompValue.dwFunc, cd.sPropertyStringValue);
}
else
return FALSE;
}
switch(pToken->Value.valuetype)
{
case ESE_VALUE_TYPE_SQL_ID:
if (!dValue)
dValue = cd.dPropertyNumericValue;
bRet = MatchNumeric(dValue, pToken->Value.dValue,
pToken->optype, dCompValue);
break;
case ESE_VALUE_TYPE_STRING:
bRet = MatchString(cd.sPropertyStringValue, pToken->Value.sValue,
pToken->optype, pToken->CompValue.sValue);
break;
case ESE_VALUE_TYPE_REAL:
bRet = MatchDouble(cd.rPropertyRealValue, pToken->Value.rValue,
pToken->optype, pToken->CompValue.rValue);
break;
case ESE_VALUE_TYPE_REF:
switch(pToken->optype)
{
case WQL_TOK_ISA:
bRet = cd.dRefClassId == pToken->Value.dValue;
if (!bRet)
{
bRet = (((CWmiDbSession *)m_pSession)->GetSchemaCache()->IsDerivedClass
(pToken->Value.dValue, cd.dRefClassId));
}
break;
}
break;
case ESE_VALUE_TYPE_SYSPROP:
bRet = TRUE; // we already evaluated this.
break;
}
}
}
return bRet;
}
//***************************************************************************
//
// CWmiESEIterator::ObjectMatches
//
//***************************************************************************
BOOL CWmiESEIterator::ObjectMatches (SQL_ID dObjectId, SQL_ID dClassId,
SQL_ID dScopeId, INDEXDATA *pData,
REFERENCEPROPERTIES *pPData,SQL_ID *pObjectId,
SQL_ID *pClassId,SQL_ID *pScopeId)
{
SQL_ID d1 = dObjectId, d2 = dClassId, d3 = dScopeId;
BOOL bRet = FALSE;
if (m_pToks->GetNumTokens())
{
TEMPQLTYPE tok = ESE_TEMPQL_TYPE_NONE;
if (m_bWQL)
bRet = ObjectMatchesWQL(d1, d2, d3);
else
{
if (dClassId == 1)
bRet = ObjectMatchesClass(d1, d2, d3, pPData);
else
bRet = ObjectMatchesRef(d1, d2, d3, pData);
}
if (bRet)
{
if (pObjectId)
*pObjectId = d1;
if (pClassId)
*pClassId = d2;
if (pScopeId)
*pScopeId = d3;
}
}
else
bRet = TRUE;
return bRet;
}
//***************************************************************************
//
// CWmiESEIterator::ObjectMatchesClass
//
//***************************************************************************
BOOL CWmiESEIterator::ObjectMatchesClass (SQL_ID &dObjectId, SQL_ID &dClassId, SQL_ID &dScopeId, REFERENCEPROPERTIES*pm)
{
BOOL bRet = FALSE;
// The class with this ID contains a reference to our target class.
// * Does the scope match?
// * Do the other properties match?
// * What is the actual endpoint (assoc or ref?)
// => Dealing with a class, we need to look at PropertyMap, as well as
// ClassData for qualifiers!
// NOTE: This is expected to be post-filtered anyway, so we will only
// perform rudimentary matching.
int iNumTokens = m_pToks->GetNumTokens();
TEMPQLTYPE qltype = m_pToks->GetToken(0)->qltype;
OBJECTMAP oj;
HRESULT hr = 0;
SQL_ID dTargetId;
_bstr_t sName;
BOOL bAssoc = FALSE;
for (int i = m_iStartPos; i < iNumTokens; i++)
{
ESEToken *pTok = m_pToks->GetToken(i);
if (!(pTok->qltype == ESE_TEMPQL_TYPE_REF ||
pTok->qltype == ESE_TEMPQL_TYPE_ASSOC))
{
continue;
}
if (pTok->qltype == ESE_TEMPQL_TYPE_ASSOC)
bAssoc = TRUE;
qltype = pTok->qltype;
bRet = FALSE;
if (pTok->tokentype == ESE_EXPR_TYPE_EXPR)
{
ESETempQLToken *pTok2 = (ESETempQLToken *)pTok;
switch (pTok2->token)
{
case TEMPQL_TOKEN_TARGETID:
dTargetId = pTok2->dValue;
if (pm->dRefClassId == dTargetId)
bRet = TRUE;
break;
case TEMPQL_TOKEN_RESULTCLASS:
if (qltype == ESE_TEMPQL_TYPE_REF)
{
// Is this class ID derived from the one
// in question?
if (dObjectId == pTok2->dValue)
bRet = TRUE;
else if (((CWmiDbSession *)m_pSession)->GetSchemaCache()->IsDerivedClass
(pTok2->dValue, dObjectId))
bRet = TRUE;
}
else
{
// We can't move the pointer
// on PropertyMap, or we will mess up our cursor.
bRet = TRUE; // postfilter
}
break;
case TEMPQL_TOKEN_ROLE:
// Is the current property ID named the token in question?
{
_bstr_t sVal;
((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetPropertyInfo(pm->iPropertyId, &sVal);
if (!_wcsicmp(sVal, pTok2->sValue))
bRet = TRUE;
}
break;
case TEMPQL_TOKEN_RESULTROLE:
// We can't move the pointer
// on PropertyMap, or we will mess up our cursor.
bRet = TRUE; // postfilter
break;
case TEMPQL_TOKEN_ASSOCQUALIFIER:
case TEMPQL_TOKEN_REQQUALIFIER:
if (qltype == ESE_TEMPQL_TYPE_REF ||
pTok2->token == TEMPQL_TOKEN_ASSOCQUALIFIER)
{
// Does this association instance have this qualifier?
CLASSDATA cd;
hr = GetFirst_ClassData(m_pConn, dObjectId, cd);
while (SUCCEEDED(hr))
{
if (pTok2->dValue == cd.iPropertyId)
{
bRet = TRUE;
cd.Clear();
break;
}
hr = GetNext_ClassData(m_pConn, cd);
}
}
else
{
// We can't move the pointer
// on PropertyMap, or we will mess up our cursor.
bRet = TRUE; // postfilter
}
break;
case TEMPQL_TOKEN_ASSOCCLASS:
// Is this association instance derived from this class?
if (dObjectId == pTok2->dValue)
bRet = TRUE;
else if (((CWmiDbSession *)m_pSession)->GetSchemaCache()->IsDerivedClass
(pTok2->dValue, dObjectId))
bRet = TRUE;
break;
default:
break;
}
}
if (!bRet)
break;
}
// FIXME: If the return object is an association,
// we need to retrieve the other object.
return bRet;
}
//***************************************************************************
//
// CWmiESEIterator::ObjectMatchesWQL
//
//***************************************************************************
BOOL CWmiESEIterator::ObjectMatchesWQL (SQL_ID dObjectId, SQL_ID dClassId, SQL_ID dScopeId)
{
BOOL bRet = FALSE;
// Traverse the set of tokens to
// see if this object matches.
// Since we do *NOT* want to
// modify the position of the current
// index, we will retrieve
// the data from the ClassData table,
// and see if it matches in toto.
int i = 0;
int iNumToks = m_pToks->GetNumTokens();
int * results = new int [iNumToks];
if (!results)
return FALSE;
CDeleteMe <int> d (results);
for (i = m_iStartPos; i < iNumToks; i++)
{
ESEWQLToken *pTok = (ESEWQLToken *)m_pToks->GetToken(i);
if (pTok->tokentype == ESE_EXPR_TYPE_EXPR &&
pTok->optype != WQL_TOK_ISNULL &&
pTok->Value.valuetype != ESE_VALUE_TYPE_SYSPROP)
results[i] = 0;
else
results[i] = -1;
}
int iNumSysToks = 0, iNumOther = 0;
// Prematch on system criteria.
BOOL bScopeMatch = FALSE, bClassMatch = FALSE;
BOOL bScopeCrit = FALSE, bClassCrit = FALSE;
for (i = m_iStartPos; i < iNumToks; i++)
{
ESEToken *pTok2 = m_pToks->GetToken(i);
if (!pTok2->qltype && pTok2->tokentype == ESE_EXPR_TYPE_EXPR)
{
ESEWQLToken *pTok = (ESEWQLToken *)pTok2;
if (pTok->Value.valuetype == ESE_VALUE_TYPE_SYSPROP)
{
// Make sure class and scope ID match
// If there are multiple scopes and classes,
// these are ORed together.
if (!dScopeId && (dClassId == 1))
bScopeMatch = TRUE;
if (pTok->dScopeId)
{
bScopeCrit = TRUE;
if (dScopeId == pTok->dScopeId)
bScopeMatch = TRUE;
}
if (pTok->dClassId)
{
bClassCrit = TRUE;
results[i] = TRUE;
if (dClassId == pTok->dClassId)
bClassMatch = TRUE;
}
iNumSysToks++;
}
else if (pTok->tokentype == ESE_EXPR_TYPE_EXPR)
iNumOther++;
}
}
if (!((bScopeMatch || !bScopeCrit) ))
bRet = FALSE;
else
{
if (iNumSysToks)
bRet = TRUE;
if (iNumOther)
{
BOOL bPropToProp = FALSE;
CLASSDATA cd;
HRESULT hr = 0;
hr = GetFirst_ClassData(m_pConn, dObjectId, cd);
while (SUCCEEDED(hr))
{
// See if this property matches any
// line of criteria.
for (i = m_iStartPos; i < iNumToks; i++)
{
ESEToken *pTok2 = m_pToks->GetToken(i);
if (!pTok2->qltype && pTok2->tokentype == ESE_EXPR_TYPE_EXPR)
{
ESEWQLToken *pTok = (ESEWQLToken *)pTok2;
if (!pTok->bSysProp)
{
if (pTok->dPropertyId == cd.iPropertyId)
{
if (!pTok->dCompPropertyId)
{
results[i] = Match(cd, pTok);
cd.Clear();
}
else
bPropToProp = TRUE;
}
}
}
}
hr = GetNext_ClassData(m_pConn, cd);
}
if (hr == WBEM_E_NOT_FOUND)
hr = WBEM_S_NO_ERROR;
if (SUCCEEDED(hr))
{
// Fishing around for specific property values
// is pretty expensive, so we do this last.
// We could optimize this by caching each CLASSDATA
// as we hit it the first time.
if (bPropToProp)
{
for (i = m_iStartPos; i < iNumToks; i++)
{
if (m_pToks->GetToken(i)->tokentype == ESE_EXPR_TYPE_EXPR)
{
ESEWQLToken *pTok = (ESEWQLToken *)m_pToks->GetToken(i);
if (pTok->dCompPropertyId)
{
CLASSDATA cd2;
hr = GetFirst_ClassData(m_pConn, dObjectId, cd, pTok->dPropertyId);
if (SUCCEEDED(hr))
{
hr = GetFirst_ClassData(m_pConn, dObjectId, cd2, pTok->dCompPropertyId);
if (SUCCEEDED(hr))
{
results[i] = PropMatch (cd, cd2, pTok);
cd2.Clear();
}
else
results[i] = FALSE;
cd.Clear();
}
else
results[i] = FALSE;
}
}
}
hr = WBEM_S_NO_ERROR;
}
}
if (SUCCEEDED(hr))
{
// Check for System properties
for (i = m_iStartPos; i < iNumToks; i++)
{
if (m_pToks->GetToken(i)->tokentype == ESE_EXPR_TYPE_EXPR)
{
if (((ESEWQLToken *)m_pToks->GetToken(i))->bSysProp == TRUE)
{
results[i] = SysMatch(dObjectId, dClassId, dScopeId, m_pToks->GetToken(i));
}
// Post-filter ISA stuff.
if ((((ESEWQLToken *)m_pToks->GetToken(i))->optype) == WQL_TOK_ISA)
results[i] = TRUE;
}
}
}
if (SUCCEEDED(hr))
{
// Go through the array and make sure
// we have the results we expected.
for (i = m_iStartPos; i < iNumToks; i++)
{
ESEToken *pTok = m_pToks->GetToken(i);
switch(pTok->tokentype)
{
case ESE_EXPR_TYPE_AND:
if (results[i-1] && results[i-2])
bRet = TRUE;
else
bRet = FALSE;
results[i] = bRet;
break;
case ESE_EXPR_TYPE_OR:
if (results[i-1] || results[i-2])
bRet = TRUE;
else
bRet = FALSE;
results[i] = bRet;
break;
case ESE_EXPR_TYPE_NOT:
if (bRet)
bRet = FALSE;
else
bRet = TRUE;
results[i] = bRet;
break;
case ESE_EXPR_TYPE_EXPR:
bRet = results[i];
break;
}
}
}
}
else
{
if (bClassCrit && !bClassMatch)
bRet = FALSE;
}
}
return bRet;
}
//***************************************************************************
//
// CWmiESEIterator::ObjectMatchesRef
//
//***************************************************************************
BOOL CWmiESEIterator::ObjectMatchesRef (SQL_ID &dObjectId, SQL_ID &dClassId,
SQL_ID &dScopeId, INDEXDATA *pData)
{
BOOL bRet = TRUE;
int iNumTokens = m_pToks->GetNumTokens();
TEMPQLTYPE qltype = m_pToks->GetToken(0)->qltype;
OBJECTMAP oj;
HRESULT hr = 0;
SQL_ID dTargetId;
_bstr_t sName;
BOOL bAssoc = FALSE;
for (int i = m_iStartPos; i < iNumTokens; i++)
{
ESEToken *pTok = m_pToks->GetToken(i);
if (!(pTok->qltype == ESE_TEMPQL_TYPE_REF ||
pTok->qltype == ESE_TEMPQL_TYPE_ASSOC))
{
continue;
}
if (pTok->qltype == ESE_TEMPQL_TYPE_ASSOC)
bAssoc = TRUE;
qltype = pTok->qltype;
bRet = FALSE;
if (pTok->tokentype == ESE_EXPR_TYPE_EXPR)
{
ESETempQLToken *pTok2 = (ESETempQLToken *)pTok;
switch (pTok2->token)
{
case TEMPQL_TOKEN_TARGETID:
dTargetId = pTok2->dValue;
if (pData)
{
if (pData->dValue == pTok2->dValue)
bRet = TRUE;
}
break;
case TEMPQL_TOKEN_RESULTCLASS:
if (qltype == ESE_TEMPQL_TYPE_REF)
{
// Is this class ID derived from the one
// in question?
if (dClassId == pTok2->dValue)
bRet = TRUE;
else if (((CWmiDbSession *)m_pSession)->GetSchemaCache()->IsDerivedClass
(pTok2->dValue, dClassId))
bRet = TRUE;
}
else
{
// Check the other endpoint of the association
// Get the other endpoint from CLASSDATA
CLASSDATA cd;
hr = GetFirst_ClassData(m_pConn, dObjectId, cd);
while (SUCCEEDED(hr))
{
if (cd.dRefId!= dTargetId)
{
hr = GetFirst_ObjectMap(m_pConn, cd.dRefId, oj);
if (SUCCEEDED(hr))
{
if (oj.dClassId == pTok2->dValue)
bRet = TRUE;
else if (((CWmiDbSession *)m_pSession)->GetSchemaCache()->IsDerivedClass
(pTok2->dValue, oj.dClassId))
bRet = TRUE;
cd.Clear();
oj.Clear();
break;
}
oj.Clear();
}
hr = GetNext_ClassData(m_pConn, cd);
}
}
break;
case TEMPQL_TOKEN_ROLE:
// Is the current property ID named the token in question?
if (pData)
{
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetPropertyInfo
(pData->iPropertyId, &sName);
if (SUCCEEDED(hr))
{
if (!_wcsicmp(sName, pTok2->sValue))
bRet = TRUE;
}
}
break;
case TEMPQL_TOKEN_RESULTROLE:
// Is the property ID of the endpoint named the token in question?
{
CLASSDATA cd;
hr = GetFirst_ClassData(m_pConn, dObjectId, cd);
while (SUCCEEDED(hr))
{
if (cd.dRefId != dTargetId)
{
hr = ((CWmiDbSession *)m_pSession)->GetSchemaCache()->GetPropertyInfo
(cd.iPropertyId, &sName);
if (SUCCEEDED(hr))
{
if (!_wcsicmp(sName, pTok2->sValue))
bRet = TRUE;
cd.Clear();
break;
}
}
hr = GetNext_ClassData(m_pConn, cd);
}
}
break;
case TEMPQL_TOKEN_ASSOCQUALIFIER:
case TEMPQL_TOKEN_REQQUALIFIER:
if (qltype == ESE_TEMPQL_TYPE_REF ||
pTok2->token == TEMPQL_TOKEN_ASSOCQUALIFIER)
{
// Does this association instance have this qualifier?
CLASSDATA cd;
hr = GetFirst_ClassData(m_pConn, dObjectId, cd);
while (SUCCEEDED(hr))
{
if (pTok2->dValue == cd.iPropertyId)
{
bRet = TRUE;
cd.Clear();
break;
}
hr = GetNext_ClassData(m_pConn, cd);
}
if (!bRet)
{
hr = GetFirst_ClassData(m_pConn, dClassId, cd);
while (SUCCEEDED(hr))
{
if (pTok2->dValue == cd.iPropertyId)
{
bRet = TRUE;
cd.Clear();
break;
}
hr = GetNext_ClassData(m_pConn, cd);
}
}
}
else
{
// Does the endpoint contain this qualifier?
CLASSDATA cd;
hr = GetFirst_ClassData (m_pConn, dObjectId, cd);
while (SUCCEEDED(hr))
{
if (cd.dRefId != dTargetId)
{
CLASSDATA cd2;
hr = GetFirst_ClassData(m_pConn, cd.dRefId, cd2);
while (SUCCEEDED(hr))
{
if (pTok2->dValue == cd2.iPropertyId)
{
bRet = TRUE;
cd2.Clear();
break;
}
hr = GetNext_ClassData(m_pConn, cd2);
}
if (!bRet)
{
hr = GetFirst_ClassData(m_pConn, cd.dRefClassId, cd2);
while (SUCCEEDED(hr))
{
if (pTok2->dValue == cd2.iPropertyId)
{
bRet = TRUE;
cd2.Clear();
break;
}
hr = GetNext_ClassData(m_pConn, cd2);
}
}
cd.Clear();
break;
}
hr = GetNext_ClassData(m_pConn, cd);
}
}
break;
case TEMPQL_TOKEN_ASSOCCLASS:
// Is this association instance derived from this class?
if (dClassId == pTok2->dValue)
bRet = TRUE;
else if (((CWmiDbSession *)m_pSession)->GetSchemaCache()->IsDerivedClass
(pTok2->dValue, dClassId))
bRet = TRUE;
break;
default:
break;
}
}
if (!bRet)
break;
}
if (bRet && bAssoc)
{
CLASSDATA cd;
hr = GetFirst_ClassData (m_pConn, dObjectId, cd);
while (SUCCEEDED(hr))
{
if (cd.dRefId != dTargetId)
{
hr = GetFirst_ObjectMap(m_pConn, cd.dRefId, oj);
if (SUCCEEDED(hr))
{
dObjectId = oj.dObjectId;
dClassId = oj.dClassId;
dScopeId = oj.dObjectScopeId;
oj.Clear();
break;
}
oj.Clear();
}
hr = GetNext_ClassData(m_pConn, cd);
}
cd.Clear();
}
return bRet;
}
//***************************************************************************
//
// CWmiESEIterator::TestDriverStatus
//
//***************************************************************************
HRESULT CWmiESEIterator::TestDriverStatus ()
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!m_pSession ||
!(m_pSession->m_pController) ||
((CWmiDbController *)m_pSession->m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
{
Cancel(0);
hr = WBEM_E_SHUTTING_DOWN;
}
return hr;
}