|
|
//******************************************************************************
//
// 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; }
|