/**************************************************************************** * * RealNetworks Transform Architecture * * $Id: rtaexternalpluginhelper.h,v 1.4.4.1 2002/06/21 00:04:49 rbunnage Exp $ * * Copyright (C) 1995-2001 RealNetworks, Inc. All rights reserved. * * http://www.real.com/devzone * * This program contains proprietary information of RealNetworks, Inc, * and is licensed subject to restrictions on use and distribution. * * External Plugin Helper Template class * * This file defines a template for implementing the IRMAPlugin and * IRMAPluginProperties interfaces which define an external plugin for the * RealNetworks Transform Architecture. * */ #ifndef _rtaexternalpluginhelper_h #define _rtaexternalpluginhelper_h #include "rmaplugn.h" // for IRMAPlugin #include "rmaplgns.h" // for IRMAPluginProperties #include "rmapckts.h" // for CLSID_IRMABuffer template class CRSExternalPluginHelper : public IRMAPlugin , public IRMAPluginProperties { public: CRSExternalPluginHelper( ) : m_pContext( NULL ) , m_lRefCount( 0 ) , m_pAgent( NULL ) { } ~CRSExternalPluginHelper( ) { PN_RELEASE( m_pContext ); PN_RELEASE( m_pAgent ); } // IRMAPlugin Interface Methods // called by plugin handler to get basic properties STDMETHOD(GetPluginInfo) (THIS_ REF(BOOL) bLoadMultiple, REF(const char*) pDescription, REF(const char*) pCopyright, REF(const char*) pMoreInfoURL, REF(UINT32) versionNumber ) { bLoadMultiple = FALSE; pDescription = kValueDescription; pCopyright = kValueRealCopyright; pMoreInfoURL = kValueGenericMoreInfoURL; versionNumber = kDefaultPluginVersion; return PNR_OK; } // called once by plugin handler, and later by session manager with RSMA factory STDMETHOD(InitPlugin) (THIS_ IUnknown* pContext ) { if ( !pContext ) { return PNR_POINTER; } PN_RELEASE(m_pContext); m_pContext = pContext; m_pContext->AddRef(); return PNR_OK; } enum EPropType { eIntType = 1, eStringType, eBufferType, eEndType }; struct SValueEntry { EPropType eType; const char* pName; void* pData; UINT32 uDataSize; }; STDMETHODIMP GetProperties( REF(IRMAValues*) pOptions ) { IRMACommonClassFactory *pCCF = NULL; PN_RESULT res = m_pContext->QueryInterface(IID_IRMACommonClassFactory, (void **) &pCCF ); if (SUCCEEDED(res)) res = pCCF->CreateInstance( IID_IRMAValues, (void **) &pOptions ); if (FAILED(res)) return res; // Count number of components, add appropriate entries to the CLSID->function list SValueEntry* pEntry = s_pPluginInfo; if( pEntry ) { while( pEntry->eType != eEndType && SUCCEEDED(res) ) { if( pEntry->eType == eStringType ) { res = SetStringProperty( pOptions, pCCF, pEntry->pName, (const char*) pEntry->pData ); } else if ( pEntry->eType == eIntType ) { res = pOptions->SetPropertyULONG32( pEntry->pName, (ULONG32) pEntry->pData ); } else if ( pEntry->eType == eBufferType ) { AddBufferProperty( pCCF, pOptions, pEntry->pName, (const unsigned char*) pEntry->pData, pEntry->uDataSize ); } pEntry++; } } PN_RELEASE( pCCF ); return res; } // IUnknown Interface Methods STDMETHOD(QueryInterface) (THIS_ REFIID riid, void** ppvObj) { if (IsEqualIID(riid, IID_IUnknown)) { AddRef(); *ppvObj = (IUnknown*) (IRMAPlugin*) this; return PNR_OK; } else if (IsEqualIID(riid, IID_IRMAPlugin)) { AddRef(); *ppvObj = (IRMAPlugin*) this; return PNR_OK; } else if (IsEqualIID(riid, IID_IRMAPluginProperties)) { AddRef(); *ppvObj = (IRMAPluginProperties*) this; return PNR_OK; } else if ( IsEqualIID(riid, IID_IRTAConfigurationAgent) || IsEqualIID(riid, IID_IRTAConnectionAgent) || IsEqualIID(riid, IID_IRTAFilter) ) { if (!m_pAgent) { m_pAgent = new T(); if (m_pAgent) m_pAgent->AddRef(); } return m_pAgent->QueryInterface( riid, ppvObj ); } else if (m_pAgent) { return m_pAgent->QueryInterface( riid, ppvObj ); } *ppvObj = NULL; return PNR_NOINTERFACE; } STDMETHOD_(ULONG32,AddRef) (THIS) { return InterlockedIncrement(&m_lRefCount); } STDMETHOD_(ULONG32,Release) (THIS) { if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0; } protected: // override for plugin properties STDMETHOD(OnGetProperties) ( THIS_ REF(IRMAValues*) pIRMAValuesProperties ) { return PNR_FAIL; } // helper for GetProperties PN_RESULT SetStringProperty( IRMAValues* pOptions, IRMACommonClassFactory* pFactory, const char* sName, const char* sValue) { IRMABuffer* pVal = NULL; PN_RESULT res = pFactory->CreateInstance( IID_IRMABuffer, (void **) &pVal ); if (SUCCEEDED(res)) res = pVal->Set((UCHAR *) sValue, strlen(sValue) +1 ); if (SUCCEEDED(res)) res = pOptions->SetPropertyCString( sName, pVal ); pVal->Release(); return res; } void AddBufferProperty( IRMACommonClassFactory* pCCF, IRMAValues* pValues, const char* pName, const unsigned char* pValue, UINT32 dataLen ) { IUnknown* pIUnk = NULL; if( SUCCEEDED( pCCF->CreateInstance( CLSID_IRMABuffer, (void**) &pIUnk ) ) ) { IRMABuffer* pBuffer = NULL; pIUnk->QueryInterface( IID_IRMABuffer, (void**) &pBuffer ); // NOTE: We have to do this here, because the Set fails if the ref count is above 1 PN_RELEASE( pIUnk ); pBuffer->Set( (const unsigned char *) pValue, dataLen ); pValues->SetPropertyBuffer( pName, pBuffer ); PN_RELEASE( pBuffer ); } } IUnknown* m_pContext; // context for accessing factory private: static SValueEntry s_pPluginInfo[]; LONG32 m_lRefCount; // QI count T* m_pAgent; }; #endif // _rtaexternalpluginhelper_h