mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
495 lines
12 KiB
495 lines
12 KiB
//******************************************************************************
|
|
//
|
|
// Copyright (c) 1999-2000, Microsoft Corporation, All rights reserved
|
|
//
|
|
//*****************************************************************************
|
|
|
|
#include "precomp.h"
|
|
#include <stdio.h>
|
|
#include "ess.h"
|
|
#include "moniprov.h"
|
|
|
|
CMonitorProvider::CMonitorProvider(CLifeControl* pControl) : TUnkBase(pControl),
|
|
m_pNamespace(NULL), m_pSink(NULL), m_pAssertClass(NULL), m_pRetractClass(NULL), m_pGoingUpClass(NULL), m_pGoingDownClass(NULL), m_pErrorClass( NULL )
|
|
{
|
|
}
|
|
|
|
CMonitorProvider::~CMonitorProvider()
|
|
{
|
|
Shutdown();
|
|
if(m_pNamespace)
|
|
m_pNamespace->Release();
|
|
if(m_pSink)
|
|
m_pSink->Release();
|
|
|
|
if( m_pAssertClass )
|
|
{
|
|
m_pAssertClass->Release();
|
|
}
|
|
|
|
if ( m_pRetractClass )
|
|
{
|
|
m_pRetractClass->Release();
|
|
}
|
|
|
|
if ( m_pGoingUpClass )
|
|
{
|
|
m_pGoingUpClass->Release();
|
|
}
|
|
|
|
if ( m_pGoingDownClass )
|
|
{
|
|
m_pGoingDownClass->Release();
|
|
}
|
|
|
|
if ( m_pErrorClass )
|
|
{
|
|
m_pErrorClass->Release();
|
|
}
|
|
}
|
|
|
|
HRESULT CMonitorProvider::Shutdown()
|
|
{
|
|
CInCritSec ics(&m_cs);
|
|
|
|
for(TIterator it = m_mapMonitors.begin(); it != m_mapMonitors.end(); it++)
|
|
{
|
|
delete it->second;
|
|
}
|
|
m_mapMonitors.clear();
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
HRESULT CMonitorProvider::SetNamespace(CEssNamespace* pNamespace)
|
|
{
|
|
m_pNamespace = pNamespace;
|
|
m_pNamespace->AddRef();
|
|
|
|
//
|
|
// Retrieve system classes from the namespace
|
|
//
|
|
|
|
if(FAILED(m_pNamespace->GetClass(ASSERT_EVENT_CLASS, &m_pAssertClass)))
|
|
return WBEM_E_CRITICAL_ERROR;
|
|
if(FAILED(m_pNamespace->GetClass(RETRACT_EVENT_CLASS, &m_pRetractClass)))
|
|
return WBEM_E_CRITICAL_ERROR;
|
|
if(FAILED(m_pNamespace->GetClass(GOINGUP_EVENT_CLASS, &m_pGoingUpClass)))
|
|
return WBEM_E_CRITICAL_ERROR;
|
|
if(FAILED(m_pNamespace->GetClass(GOINGDOWN_EVENT_CLASS, &m_pGoingDownClass)))
|
|
return WBEM_E_CRITICAL_ERROR;
|
|
if(FAILED(m_pNamespace->GetClass(MONITORERROR_EVENT_CLASS, &m_pErrorClass)))
|
|
return WBEM_E_CRITICAL_ERROR;
|
|
|
|
//
|
|
// Retrieve handle values
|
|
//
|
|
|
|
m_pAssertClass->GetPropertyHandleEx(MONITORNAME_EVENT_PROPNAME,
|
|
0, NULL, &m_lNameHandle);
|
|
m_pAssertClass->GetPropertyHandleEx(MONITOROBJECT_EVENT_PROPNAME,
|
|
0, NULL, &m_lObjectHandle);
|
|
m_pAssertClass->GetPropertyHandleEx(MONITORCOUNT_EVENT_PROPNAME,
|
|
0, NULL, &m_lCountHandle);
|
|
m_pAssertClass->GetPropertyHandleEx(MONITORNEW_EVENT_PROPNAME,
|
|
0, NULL, &m_lNewHandle);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CMonitorProvider::ProvideEvents(IWbemObjectSink* pSink,
|
|
long lFlags)
|
|
{
|
|
return pSink->QueryInterface(IID_IWbemEventSink, (void**)&m_pSink);
|
|
}
|
|
|
|
HRESULT CMonitorProvider::AddMonitor(LPCWSTR wszName, LPCWSTR wszQuery,
|
|
long lFlags, IWbemContext* pContext)
|
|
{
|
|
HRESULT hres;
|
|
|
|
CMonitor* pMonitor = new CMonitor;
|
|
if(pMonitor == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
CFiringMonitorCallback* pCallback =
|
|
new CFiringMonitorCallback(this, wszName);
|
|
if(pCallback == NULL || pCallback->GetName() == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
pCallback->AddRef();
|
|
CTemplateReleaseMe<CFiringMonitorCallback> rm1(pCallback);
|
|
|
|
hres = pCallback->Initialize();
|
|
if(FAILED(hres))
|
|
{
|
|
delete pMonitor;
|
|
return hres;
|
|
}
|
|
|
|
hres = pMonitor->Construct(m_pNamespace, pCallback, wszQuery);
|
|
if(FAILED(hres))
|
|
{
|
|
delete pMonitor;
|
|
return hres;
|
|
}
|
|
|
|
//
|
|
// Attempt to start the monitor. TBD: consider monitor's guard
|
|
//
|
|
|
|
hres = pMonitor->Start(pContext);
|
|
if(FAILED(hres))
|
|
{
|
|
//
|
|
// Could not start monitor --- depending on whether strong validation
|
|
// is required, remove the monitor or keep it inactive
|
|
//
|
|
|
|
if(lFlags & WBEM_FLAG_STRONG_VALIDATION)
|
|
{
|
|
delete pMonitor;
|
|
return hres;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add the monitor to the list, active or not
|
|
//
|
|
|
|
{
|
|
CInCritSec ics(&m_cs);
|
|
m_mapMonitors[wszName] = pMonitor;
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CMonitorProvider::RemoveMonitor(LPCWSTR wszName, IWbemContext* pContext)
|
|
{
|
|
CInCritSec ics(&m_cs);
|
|
|
|
TIterator it = m_mapMonitors.find(wszName);
|
|
if(it == m_mapMonitors.end())
|
|
return WBEM_S_FALSE;
|
|
|
|
it->second->Stop(pContext);
|
|
delete it->second;
|
|
m_mapMonitors.erase(it);
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
// static
|
|
HRESULT CMonitorProvider::GetMonitorInfo(IWbemClassObject* pMonitorObj,
|
|
BSTR* pstrKey, BSTR* pstrQuery, long* plFlags)
|
|
{
|
|
HRESULT hres;
|
|
|
|
if(pstrKey)
|
|
{
|
|
//
|
|
// Extract the relpath to use as the key
|
|
//
|
|
|
|
VARIANT v;
|
|
hres = pMonitorObj->Get(MONITOR_NAME_PROPNAME, 0, &v, NULL, NULL);
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Monitor without a path? Not valid\n"));
|
|
return hres;
|
|
}
|
|
|
|
if(V_VT(&v) != VT_BSTR)
|
|
return WBEM_E_CRITICAL_ERROR;
|
|
|
|
*pstrKey = V_BSTR(&v);
|
|
}
|
|
|
|
if(pstrQuery)
|
|
{
|
|
//
|
|
// Check query type
|
|
//
|
|
|
|
VARIANT vType;
|
|
VariantInit(&vType);
|
|
CClearMe cm1(&vType);
|
|
|
|
hres = pMonitorObj->Get(MONITOR_QUERYLANG_PROPNAME, 0, &vType, NULL,
|
|
NULL);
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Monitor without a query type? Not valid\n"));
|
|
return hres;
|
|
}
|
|
|
|
if(V_VT(&vType) != VT_BSTR)
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Monitor without a query type? Not valid\n"));
|
|
return WBEM_E_INVALID_OBJECT;
|
|
}
|
|
|
|
if(wbem_wcsicmp(V_BSTR(&vType), L"WQL"))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Monitor with invalid query type %S is "
|
|
"rejected\n", V_BSTR(&vType)));
|
|
return hres;
|
|
}
|
|
|
|
//
|
|
// Extract the query
|
|
//
|
|
|
|
VARIANT v;
|
|
hres = pMonitorObj->Get(MONITOR_QUERY_PROPNAME, 0, &v, NULL, NULL);
|
|
if(FAILED(hres))
|
|
{
|
|
ERRORTRACE((LOG_ESS, "Monitor without a name? Not valid\n"));
|
|
return hres;
|
|
}
|
|
|
|
if(V_VT(&v) != VT_BSTR)
|
|
return hres;
|
|
|
|
*pstrQuery = V_BSTR(&v);
|
|
}
|
|
|
|
if(plFlags)
|
|
{
|
|
//
|
|
// TBD: no flags for now
|
|
//
|
|
|
|
*plFlags = 0;
|
|
}
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
|
|
HRESULT CMonitorProvider::ConstructAssert(LPCWSTR wszName, _IWmiObject* pObj,
|
|
bool bEvent,
|
|
DWORD dwTotalCount, _IWmiObject** ppEvent)
|
|
{
|
|
HRESULT hres;
|
|
hres = GetInstance(m_pAssertClass, wszName, dwTotalCount, ppEvent);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
hres = SetObject(*ppEvent, pObj, bEvent);
|
|
if(FAILED(hres))
|
|
(*ppEvent)->Release();
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CMonitorProvider::ConstructRetract(LPCWSTR wszName, _IWmiObject* pObj, bool bEvent,
|
|
DWORD dwTotalCount, _IWmiObject** ppEvent)
|
|
{
|
|
HRESULT hres;
|
|
hres = GetInstance(m_pRetractClass, wszName, dwTotalCount, ppEvent);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
hres = SetObject(*ppEvent, pObj, bEvent);
|
|
if(FAILED(hres))
|
|
(*ppEvent)->Release();
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CMonitorProvider::ConstructGoingUp(LPCWSTR wszName, DWORD dwNumMatching,
|
|
_IWmiObject** ppEvent)
|
|
{
|
|
return GetInstance(m_pGoingUpClass, wszName, dwNumMatching, ppEvent);
|
|
}
|
|
|
|
HRESULT CMonitorProvider::ConstructGoingDown(LPCWSTR wszName, DWORD dwNumMatching,
|
|
_IWmiObject** ppEvent)
|
|
{
|
|
return GetInstance(m_pGoingDownClass, wszName, dwNumMatching, ppEvent);
|
|
}
|
|
|
|
HRESULT CMonitorProvider::ConstructError(LPCWSTR wszName, HRESULT hresError,
|
|
IWbemClassObject* pErrorObj,
|
|
_IWmiObject** ppEvent)
|
|
{
|
|
return GetInstance(m_pErrorClass, wszName, 0, ppEvent);
|
|
}
|
|
|
|
HRESULT CMonitorProvider::GetInstance(_IWmiObject* pClass, LPCWSTR wszName, DWORD dwCount,
|
|
_IWmiObject** ppEvent)
|
|
{
|
|
if(pClass == NULL)
|
|
return WBEM_E_CRITICAL_ERROR;
|
|
|
|
HRESULT hres;
|
|
IWbemClassObject* pEvent = NULL;
|
|
hres = pClass->SpawnInstance(0, &pEvent);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
pEvent->QueryInterface(IID__IWmiObject, (void**)ppEvent);
|
|
pEvent->Release();
|
|
|
|
hres = (*ppEvent)->SetPropByHandle(m_lCountHandle, 0, sizeof(DWORD),
|
|
&dwCount);
|
|
if(FAILED(hres))
|
|
{
|
|
(*ppEvent)->Release();
|
|
return hres;
|
|
}
|
|
|
|
hres = (*ppEvent)->SetPropByHandle(m_lNameHandle, 0,
|
|
wcslen(wszName)*2+2, (LPVOID)wszName);
|
|
if(FAILED(hres))
|
|
{
|
|
(*ppEvent)->Release();
|
|
return hres;
|
|
}
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
HRESULT CMonitorProvider::SetObject(_IWmiObject* pEvent, _IWmiObject* pObj,
|
|
bool bFromEvent)
|
|
{
|
|
HRESULT hres;
|
|
|
|
hres = pEvent->SetPropByHandle(m_lObjectHandle, 0, sizeof(_IWmiObject*),
|
|
&pObj);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
|
|
short bNew = (bFromEvent?-1:0);
|
|
hres = pEvent->SetPropByHandle(m_lNewHandle, 0, sizeof(short), &bNew);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
|
|
CFiringMonitorCallback::CFiringMonitorCallback(CMonitorProvider* pProvider,
|
|
LPCWSTR wszName)
|
|
: m_pProvider(pProvider), m_wsName(wszName), m_pSink(NULL), m_lRef(0)
|
|
{
|
|
if(m_pProvider)
|
|
m_pProvider->AddRef();
|
|
}
|
|
|
|
CFiringMonitorCallback::~CFiringMonitorCallback()
|
|
{
|
|
if(m_pProvider)
|
|
m_pProvider->Release();
|
|
if(m_pSink)
|
|
m_pSink->Release();
|
|
}
|
|
|
|
ULONG STDMETHODCALLTYPE CFiringMonitorCallback::AddRef()
|
|
{
|
|
return InterlockedIncrement(&m_lRef);
|
|
}
|
|
|
|
ULONG STDMETHODCALLTYPE CFiringMonitorCallback::Release()
|
|
{
|
|
long lRef = InterlockedIncrement(&m_lRef);
|
|
if(lRef == 0)
|
|
delete this;
|
|
return lRef;
|
|
}
|
|
|
|
HRESULT CFiringMonitorCallback::Initialize()
|
|
{
|
|
//
|
|
// Get us a restricted sink for our key. TBD
|
|
//
|
|
|
|
m_pSink = m_pProvider->GetSink();
|
|
m_pSink->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
bool CFiringMonitorCallback::CheckSink()
|
|
{
|
|
return (m_pSink && (m_pSink->IsActive() == WBEM_S_NO_ERROR));
|
|
}
|
|
|
|
HRESULT CFiringMonitorCallback::FireEvent(_IWmiObject* pEvent)
|
|
{
|
|
return m_pSink->Indicate(1, (IWbemClassObject**)&pEvent);
|
|
}
|
|
|
|
HRESULT CFiringMonitorCallback::Assert(_IWmiObject* pObj, LPCWSTR wszPath,
|
|
bool bEvent, DWORD dwTotalCount)
|
|
{
|
|
if(!CheckSink())
|
|
return WBEM_S_FALSE;
|
|
|
|
HRESULT hres;
|
|
_IWmiObject* pEvent = NULL;
|
|
hres = m_pProvider->ConstructAssert(m_wsName, pObj, bEvent, dwTotalCount, &pEvent);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
CReleaseMe rm(pEvent);
|
|
|
|
return FireEvent(pEvent);
|
|
}
|
|
|
|
HRESULT CFiringMonitorCallback::Retract(_IWmiObject* pObj, LPCWSTR wszPath,
|
|
bool bEvent, DWORD dwTotalCount)
|
|
{
|
|
if(!CheckSink())
|
|
return WBEM_S_FALSE;
|
|
|
|
HRESULT hres;
|
|
_IWmiObject* pEvent = NULL;
|
|
hres = m_pProvider->ConstructRetract(m_wsName, pObj, bEvent, dwTotalCount, &pEvent);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
CReleaseMe rm(pEvent);
|
|
|
|
return FireEvent(pEvent);
|
|
}
|
|
|
|
HRESULT CFiringMonitorCallback::GoingUp(DWORD dwNumMatching)
|
|
{
|
|
if(!CheckSink())
|
|
return WBEM_S_FALSE;
|
|
|
|
HRESULT hres;
|
|
_IWmiObject* pEvent = NULL;
|
|
hres = m_pProvider->ConstructGoingUp(m_wsName, dwNumMatching, &pEvent);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
CReleaseMe rm(pEvent);
|
|
|
|
return FireEvent(pEvent);
|
|
}
|
|
|
|
HRESULT CFiringMonitorCallback::GoingDown(DWORD dwNumMatching)
|
|
{
|
|
if(!CheckSink())
|
|
return WBEM_S_FALSE;
|
|
|
|
HRESULT hres;
|
|
_IWmiObject* pEvent = NULL;
|
|
hres = m_pProvider->ConstructGoingDown(m_wsName, dwNumMatching, &pEvent);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
CReleaseMe rm(pEvent);
|
|
|
|
return FireEvent(pEvent);
|
|
}
|
|
|
|
HRESULT CFiringMonitorCallback::Error(HRESULT hresError,
|
|
IWbemClassObject* pErrorObj)
|
|
{
|
|
if(!CheckSink())
|
|
return WBEM_S_FALSE;
|
|
|
|
HRESULT hres;
|
|
_IWmiObject* pEvent = NULL;
|
|
hres = m_pProvider->ConstructError(m_wsName, hresError, pErrorObj, &pEvent);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
CReleaseMe rm(pEvent);
|
|
|
|
return FireEvent(pEvent);
|
|
}
|