#include "precomp.h" #include #include #include #include #include #include #include #include #include "fconprov.h" #include "fconnspc.h" #include "fconsink.h" LPCWSTR g_wszNamespace = L"__NAMESPACE"; LPCWSTR g_wszClass = L"__CLASS"; LPCWSTR g_wszEventFwdCons = L"MSFT_EventForwardingConsumer"; LPCWSTR g_wszDataFwdCons = L"MSFT_DataForwardingConsumer"; static CStaticCritSec g_cs; typedef CWbemPtr CFwdConsNamespaceP; typedef std::map > NamespaceMap; NamespaceMap* g_pNamespaces; HRESULT CFwdConsProv::InitializeModule() { g_pNamespaces = new NamespaceMap; if ( g_pNamespaces == NULL ) { return WBEM_E_OUT_OF_MEMORY; } return WBEM_S_NO_ERROR; } void CFwdConsProv::UninitializeModule() { delete g_pNamespaces; } HRESULT CFwdConsProv::FindConsumer( IWbemClassObject* pCons, IWbemUnboundObjectSink** ppSink ) { ENTER_API_CALL HRESULT hr; // // workaround for bogus context object left on thread by wmi. // just remove it. shouldn't leak because this call doesn't addref it. // IUnknown* pCtx; CoSwitchCallContext( NULL, &pCtx ); // // first obtain the namespace object. we derive the namespace from // the consumer object. If no namespace obj is there, create one. // CPropVar vNamespace; hr = pCons->Get( g_wszNamespace, 0, &vNamespace, NULL, NULL ); if ( FAILED(hr) || FAILED(hr=vNamespace.SetType(VT_BSTR)) ) { return hr; } CInCritSec ics( &g_cs ); CWbemPtr pNspc = (*g_pNamespaces)[V_BSTR(&vNamespace)]; if ( pNspc == NULL ) { pNspc = new CFwdConsNamespace; if ( pNspc == NULL ) { return WBEM_E_OUT_OF_MEMORY; } hr = pNspc->Initialize( V_BSTR(&vNamespace) ); if ( FAILED(hr) ) { return hr; } (*g_pNamespaces)[V_BSTR(&vNamespace)] = pNspc; } return CFwdConsSink::Create( m_pControl, pNspc, pCons, ppSink ); EXIT_API_CALL }