|
|
/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
ASSRULE.CPP
Abstract:
History:
--*/
#include "assrule.h"
#include <stdio.h>
#define CLASSNAME_ASSOCIATION_RULE L"AssociationRule"
#define PROPNAME_ASSOCIATION_CLASS L"AssociationClass"
#define PROPNAME_RULE_IMMUTABLE L"RuleIsImmutable"
#define PROPNAME_PROPNAME_1 L"PropertyName1"
#define PROPNAME_QUERY_1 L"PropertyQuery1"
#define PROPNAME_IMMUTABLE_1 L"Property1IsImmutable"
#define PROPNAME_PROPNAME_2 L"PropertyName2"
#define PROPNAME_QUERY_2 L"PropertyQuery2"
#define PROPNAME_IMMUTABLE_2 L"Property2IsImmutable"
#define EXTRA_GET_PARAMS ,NULL, NULL
#define EXTRA_PUT_PARAMS ,0
CEndpointCache::CEndpointCache() : m_strQuery(NULL), m_pEnum(NULL) { }
void CEndpointCache::Create(BSTR strQuery, BOOL bCache) { m_strQuery = SysAllocString(strQuery); m_bCache = bCache; }
CEndpointCache::~CEndpointCache() { SysFreeString(m_strQuery); if(m_pEnum) m_pEnum->Release(); }
HRESULT CEndpointCache::GetInstanceEnum(IWbemServices* pNamespace, IEnumWbemClassObject** ppEnum) { if(m_pEnum) { *ppEnum = m_pEnum; m_pEnum->AddRef(); return S_OK; }
HRESULT hres = pNamespace->ExecQuery(L"WQL", m_strQuery, 0, ppEnum, NULL); if(FAILED(hres)) return hres;
if(m_bCache) { m_pEnum = *ppEnum; m_pEnum->AddRef(); } return hres; }
CAssocRule::CAssocRule() : m_strAssocClass(NULL), m_strProp1(NULL), m_strProp2(NULL), m_pClass(NULL), m_nRef(0), m_bMayCacheResult(FALSE), m_bResultCached(FALSE) { }
CAssocRule::~CAssocRule() { SysFreeString(m_strAssocClass); SysFreeString(m_strProp1); SysFreeString(m_strProp2);
if(m_pClass) m_pClass->Release(); }
void CAssocRule::AddRef() { m_nRef++; }
void CAssocRule::Release() { if(--m_nRef == 0) { delete this; } }
HRESULT CAssocRule::LoadFromObject(IWbemClassObject* pRule, BOOL bLongTerm) { HRESULT hres;
VARIANT v; VariantInit(&v);
// Read association name
// =====================
hres = pRule->Get(PROPNAME_ASSOCIATION_CLASS, 0, &v EXTRA_GET_PARAMS); if(FAILED(hres) || V_VT(&v) == VT_NULL) { return WBEM_E_FAILED; } m_strAssocClass = SysAllocString(V_BSTR(&v)); VariantClear(&v);
// Read property names
// ===================
hres = pRule->Get(PROPNAME_PROPNAME_1, 0, &v EXTRA_GET_PARAMS); if(FAILED(hres) || V_VT(&v) == VT_NULL) { return WBEM_E_FAILED; } m_strProp1 = SysAllocString(V_BSTR(&v)); VariantClear(&v);
hres = pRule->Get(PROPNAME_PROPNAME_2, 0, &v EXTRA_GET_PARAMS); if(FAILED(hres) || V_VT(&v) == VT_NULL) { return WBEM_E_FAILED; } m_strProp2 = SysAllocString(V_BSTR(&v)); VariantClear(&v);
m_bMayCacheResult = bLongTerm;
// Read property rule (1)
// ======================
VARIANT vImmutable; VariantInit(&vImmutable);
hres = pRule->Get(PROPNAME_QUERY_1, 0, &v EXTRA_GET_PARAMS); if(FAILED(hres) || V_VT(&v) == VT_NULL) { return WBEM_E_FAILED; }
hres = pRule->Get(PROPNAME_IMMUTABLE_1, 0, &vImmutable EXTRA_GET_PARAMS); if(FAILED(hres) || V_VT(&vImmutable) == VT_NULL) { return WBEM_E_FAILED; }
m_Cache1.Create(V_BSTR(&v), V_BOOL(&vImmutable)); VariantClear(&v); if(!V_BOOL(&vImmutable)) m_bMayCacheResult = FALSE;
// Read property rule (2)
// ======================
hres = pRule->Get(PROPNAME_QUERY_2, 0, &v EXTRA_GET_PARAMS); if(FAILED(hres) || V_VT(&v) == VT_NULL) { return WBEM_E_FAILED; }
hres = pRule->Get(PROPNAME_IMMUTABLE_2, 0, &vImmutable EXTRA_GET_PARAMS); if(FAILED(hres) || V_VT(&vImmutable) == VT_NULL) { return WBEM_E_FAILED; }
m_Cache2.Create(V_BSTR(&v), V_BOOL(&vImmutable)); VariantClear(&v); if(!V_BOOL(&vImmutable)) m_bMayCacheResult = FALSE;
return S_OK; }
HRESULT CAssocRule::Produce(IWbemServices* pNamespace, IWbemObjectSink* pNotify) { HRESULT hres;
// Check if we have it cached
// ==========================
if(m_bResultCached) { return m_ObjectCache.Indicate(pNotify); }
// Get first enumerator
// ====================
IEnumWbemClassObject* pEnum1; hres = m_Cache1.GetInstanceEnum(pNamespace, &pEnum1); if(FAILED(hres)) { return hres; }
// Get second enumerator
// =====================
IEnumWbemClassObject* pEnum2; hres = m_Cache2.GetInstanceEnum(pNamespace, &pEnum2); if(FAILED(hres)) { pEnum1->Release(); return hres; }
// Get the association class
// =========================
IWbemClassObject* pClass; if(m_pClass != NULL) { pClass = m_pClass; pClass->AddRef(); } else { hres = pNamespace->GetObject(m_strAssocClass, 0, &pClass, NULL); if(FAILED(hres)) { pEnum1->Release(); pEnum2->Release(); return hres; } }
// Create all the associations
// ===========================
IWbemClassObject* pInstance1, *pInstance2; ULONG lNum;
VARIANT v; VariantInit(&v);
// Iterate through the first result set
// ====================================
pEnum1->Reset(); while(pEnum1->Next(1, &pInstance1, &lNum) == S_OK) { // Get the first path
// ==================
hres = pInstance1->Get(L"__PATH", 0, &v EXTRA_GET_PARAMS); if(FAILED(hres)) { pEnum1->Release(); pEnum2->Release(); pClass->Release(); return hres; } BSTR strPath1 = V_BSTR(&v); VariantInit(&v); // intentional.
// Iterate through the second result set
// =====================================
pEnum2->Reset(); while(pEnum2->Next(1, &pInstance2, &lNum) == S_OK) { // Get the second path
// ===================
hres = pInstance2->Get(L"__PATH", 0, &v EXTRA_GET_PARAMS); if(FAILED(hres)) { pEnum1->Release(); pEnum2->Release(); pClass->Release(); return hres; } BSTR strPath2 = V_BSTR(&v); VariantInit(&v); // intentional
// Create the association instance
// ===============================
IWbemClassObject* pInstance; hres = pClass->SpawnInstance(0, &pInstance); if(FAILED(hres)) { pEnum1->Release(); pEnum2->Release(); pClass->Release(); return hres; }
// Set the properties
// ==================
V_VT(&v) = VT_BSTR; V_BSTR(&v) = strPath1;
hres = pInstance->Put(m_strProp1, 0, &v EXTRA_PUT_PARAMS); if(FAILED(hres)) { pEnum1->Release(); pEnum2->Release(); pClass->Release(); pInstance->Release(); return hres; }
V_BSTR(&v) = strPath2; hres = pInstance->Put(m_strProp2, 0, &v EXTRA_PUT_PARAMS); if(FAILED(hres)) { pEnum1->Release(); pEnum2->Release(); pClass->Release(); pInstance->Release(); return hres; }
// Supply it
// =========
pNotify->Indicate(1, &pInstance);
// Cache it if allowed
// ===================
if(m_bMayCacheResult) m_ObjectCache.Add(pInstance);
pInstance->Release();
SysFreeString(strPath2); pInstance2->Release(); }
SysFreeString(strPath1); pInstance1->Release(); }
pEnum1->Release(); pEnum2->Release(); pClass->Release();
if(m_bMayCacheResult) m_bResultCached = TRUE; return S_OK; }
//*****************************************************************************
CAssocInfoCache::CAssocInfoCache() : m_pNamespace(NULL) { }
void CAssocInfoCache::SetNamespace(IWbemServices* pNamespace) { m_pNamespace = pNamespace; m_pNamespace->AddRef(); }
CAssocInfoCache::~CAssocInfoCache() { if(m_pNamespace) m_pNamespace->Release();
for(int i = 0; i < m_aRules.Size(); i++) { CAssocRule* pRule = (CAssocRule*)m_aRules[i]; pRule->Release(); } }
HRESULT CAssocInfoCache::GetRuleForClass(BSTR strClass, CAssocRule** ppRule) { // Search our rules to see if we have it
// =====================================
for(int i = 0; i < m_aRules.Size(); i++) { CAssocRule* pRule = (CAssocRule*)m_aRules[i]; if(!wcsicmp(pRule->GetAssocClass(), strClass)) { pRule->AddRef(); *ppRule = pRule; return S_OK; } }
// Don't have it. Search for the rule in the database.
// ===================================================
HRESULT hres;
BSTR strPath = SysAllocStringLen(NULL, wcslen(strClass) + 100); swprintf(strPath, L"%s.%s=\"%s\"", CLASSNAME_ASSOCIATION_RULE, PROPNAME_ASSOCIATION_CLASS, strClass);
IWbemClassObject* pRuleInstance; hres = m_pNamespace->GetObject(strPath, 0, &pRuleInstance, NULL); SysFreeString(strPath); if(FAILED(hres)) { return hres; }
// Check if it is cachable
// ========================
VARIANT v; VariantInit(&v); hres = pRuleInstance->Get(PROPNAME_RULE_IMMUTABLE, 0, &v EXTRA_GET_PARAMS); if(FAILED(hres)) { pRuleInstance->Release(); return hres; }
// Got it. Create the rule.
// ========================
CAssocRule* pRule = new CAssocRule; hres = pRule->LoadFromObject(pRuleInstance, V_BOOL(&v)); pRuleInstance->Release(); if(FAILED(hres)) { delete pRule; return hres; }
// Cache if allowed
// ================
if(V_BOOL(&v)) { m_aRules.Add(pRule); pRule->AddRef(); }
// Return it to the caller
// =======================
pRule->AddRef(); *ppRule = pRule;
return S_OK; }
//****************************************************************************
CObjectCache::~CObjectCache() { Invalidate(); }
void CObjectCache::Invalidate() { for(int i = 0; i < m_aObjects.Size(); i++) { IWbemClassObject* pObject = (IWbemClassObject*)m_aObjects[i]; pObject->Release(); } m_aObjects.Empty(); }
void CObjectCache::Add(IWbemClassObject* pObject) { m_aObjects.Add((void*)pObject); pObject->AddRef(); }
HRESULT CObjectCache::Indicate(IWbemObjectSink* pSink) { if(m_aObjects.Size() == 0) return S_OK;
void** ppvData = m_aObjects.GetArrayPtr();
return pSink->Indicate(m_aObjects.Size(), (IWbemClassObject**)ppvData); }
|