windows-nt/Source/XPSP1/NT/admin/wmi/wbem/winmgmt/ess3/evsink.cpp

313 lines
6.5 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//******************************************************************************
//
// EVSINK.CPP
//
// Copyright (C) 1996-1999 Microsoft Corporation
//
//******************************************************************************
#include "precomp.h"
#include <stdio.h>
#include <genutils.h>
#include <cominit.h>
#include "ess.h"
#include "evsink.h"
//****************************** CONTEXT **********************************//
CEventContext::~CEventContext()
{
if( m_bOwning )
{
delete [] m_pSD;
}
}
BOOL CEventContext::SetSD( long lSDLength, BYTE* pSD, BOOL bMakeCopy )
{
BOOL bRes = TRUE;
if ( m_bOwning )
{
delete [] m_pSD;
m_bOwning = false;
}
m_lSDLength = lSDLength;
if ( m_lSDLength > 0 )
{
if ( !bMakeCopy )
{
m_pSD = pSD;
m_bOwning = false;
}
else
{
m_pSD = new BYTE[m_lSDLength];
if ( m_pSD != NULL )
{
memcpy( m_pSD, pSD, m_lSDLength );
m_bOwning = true;
}
else
{
bRes = FALSE;
}
}
}
else
{
m_pSD = NULL;
}
return bRes;
}
CReuseMemoryManager CEventContext::mstatic_Manager(sizeof CEventContext);
void *CEventContext::operator new(size_t nBlock)
{
return mstatic_Manager.Allocate();
}
void CEventContext::operator delete(void* p)
{
mstatic_Manager.Free(p);
}
/*
void* CEventContext::operator new(size_t nSize)
{
return CTemporaryHeap::Alloc(nSize);
}
void CEventContext::operator delete(void* p)
{
CTemporaryHeap::Free(p, sizeof(CEventContext));
}
*/
//*************************** ABSTRTACT EVENT SINK *************************//
STDMETHODIMP CAbstractEventSink::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown || riid == IID_IWbemObjectSink )
{
*ppv = (IWbemObjectSink*)this;
AddRef();
return S_OK;
}
else
return E_NOINTERFACE;
}
STDMETHODIMP CAbstractEventSink::SetStatus(long, long, BSTR, IWbemClassObject*)
{
return E_NOTIMPL;
}
HRESULT CAbstractEventSink::Indicate(long lNumEvemts, IWbemEvent** apEvents,
CEventContext* pContext)
{
return WBEM_E_CRITICAL_ERROR; // if not implemented, but called
}
STDMETHODIMP CAbstractEventSink::Indicate(long lNumEvents,
IWbemClassObject** apEvents)
{
//
// Event is being raised without security --- send it along with an empty
// context
//
return Indicate(lNumEvents, apEvents, NULL);
}
STDMETHODIMP CAbstractEventSink::IndicateWithSD(long lNumEvents,
IUnknown** apEvents,
long lSDLength, BYTE* pSD)
{
HRESULT hres;
//
// Event is being raised with security -- send it along with that SD in the
// context
//
CEventContext Context;
Context.SetSD( lSDLength, pSD, FALSE );
//
// Allocate a stack buffer to cast the pointers
//
IWbemClassObject** apCast = NULL;
try
{
apCast = (IWbemClassObject**)_alloca(sizeof(IUnknown*) * lNumEvents);
}
catch(...)
{
return WBEM_E_OUT_OF_MEMORY;
}
for(int i = 0; i < lNumEvents; i++)
{
hres = apEvents[i]->QueryInterface( IID_IWbemClassObject,
(void**)&apCast[i] );
if ( FAILED(hres) )
{
return hres;
}
}
return Indicate(lNumEvents, apCast, &Context);
}
//*************************** OBJECT SINK *************************//
STDMETHODIMP CObjectSink::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown || riid == IID_IWbemObjectSink)
{
*ppv = (IWbemObjectSink*)this;
AddRef();
return S_OK;
}
// Hack to idenitfy ourselves to the core as a trusted component
else if(riid == CLSID_WbemLocator)
return S_OK;
else
return E_NOINTERFACE;
}
STDMETHODIMP CObjectSink::SetStatus(long, long, BSTR, IWbemClassObject*)
{
return E_NOTIMPL;
}
ULONG STDMETHODCALLTYPE CObjectSink::AddRef()
{
return InterlockedIncrement(&m_lRef);
}
ULONG STDMETHODCALLTYPE CObjectSink::Release()
{
long lRef = InterlockedDecrement(&m_lRef);
if(lRef == 0)
delete this;
return lRef;
}
//*************************** EVENT SINK *************************//
ULONG STDMETHODCALLTYPE CEventSink::AddRef()
{
return InterlockedIncrement(&m_lRef);
}
ULONG STDMETHODCALLTYPE CEventSink::Release()
{
long lRef = InterlockedDecrement(&m_lRef);
if(lRef == 0)
delete this;
return lRef;
}
//*************************** OWNED EVENT SINK *************************//
COwnedEventSink::COwnedEventSink(CAbstractEventSink* pOwner)
: m_pOwner(pOwner), m_lRef(0), m_bReleasing(false)
{
}
ULONG STDMETHODCALLTYPE COwnedEventSink::AddRef()
{
CInCritSec ics(&m_cs);
//
// Increment our ref count, as well as that of our putative owner
//
m_lRef++;
if(m_pOwner)
m_pOwner->AddRef();
return m_lRef;
}
ULONG STDMETHODCALLTYPE COwnedEventSink::Release()
{
bool bDelete = false;
{
CInCritSec ics(&m_cs);
m_bReleasing = true;
m_lRef--;
//
// Propagate release to our owner. This may cause Disconnect to be
// called, but it will know not to self-destruct because of
// m_bReleasing
//
if(m_pOwner)
m_pOwner->Release();
//
// Determine whether self-destruct is called for
//
if(m_lRef == 0 && m_pOwner == NULL)
{
bDelete = true;
}
m_bReleasing = false;
}
if(bDelete)
delete this;
return 1;
}
void COwnedEventSink::Disconnect()
{
bool bDelete = false;
{
CInCritSec ics(&m_cs);
if(m_pOwner == NULL)
return;
//
// Release all the ref-counts that the owner has received through us
//
for(int i = 0; i < m_lRef; i++)
m_pOwner->Release();
//
// Forget about the owner. Once we have been released by externals,
// we go away
//
m_pOwner = NULL;
//
// Check if we are already fully released by externals
//
if(m_lRef == 0 && !m_bReleasing)
bDelete = true;
}
if(bDelete)
delete this;
}