#include "precomp.h" #include #include #include #include #include "Globals.h" #include "ProvRegDeCoupled.h" #include #include "CGlobals.h" #include "provcache.h" #include "aggregator.h" #include "ProvWsvS.h" #include "ProvWsv.h" #include "ProvInSk.h" #include "ProvobSk.h" #include #include #include struct SWQLColRef; #include #include /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ DCProxy :: DCProxy ( ) : m_ReferenceCount ( 0 ) , event_only_(false), m_Sink(NULL), NULL_IWbemServices( WBEM_E_NOT_AVAILABLE ) { InterlockedIncrement (&DecoupledProviderSubSystem_Globals::s_ObjectsInProgress); } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ DCProxy :: ~DCProxy () { if (m_aggregator_) m_aggregator_->deActivate(); InterlockedDecrement (&DecoupledProviderSubSystem_Globals::s_ObjectsInProgress); } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ STDMETHODIMP_(ULONG) DCProxy :: AddRef ( void ) { return InterlockedIncrement (&m_ReferenceCount) ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ STDMETHODIMP_(ULONG) DCProxy :: Release ( void ) { LONG t_Reference = InterlockedDecrement (&m_ReferenceCount); if ( 0 == t_Reference ) { delete this ; return 0 ; } else { return t_Reference ; } } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ STDMETHODIMP DCProxy :: QueryInterface ( REFIID iid , LPVOID FAR *iplpv ) { if (iplpv == 0) return E_POINTER; if (iid == IID_IUnknown) { *iplpv = static_cast(this) ; } else if (iid == IID_IWbemServices) { *iplpv = static_cast(this) ; } else if (iid == IID_IWbemPropertyProvider) { *iplpv = static_cast(this); } else if ( iid == IID_IWbemProviderInit ) { *iplpv = static_cast(this) ; } else if ( iid == IID_IWbemEventProvider ) { *iplpv = static_cast(this) ; } else if ( iid == IID_IWbemEventProviderSecurity ) { *iplpv = static_cast(this) ; } else if ( iid == IID_IWbemProviderIdentity ) { *iplpv = static_cast(this) ; } else if ( iid == IID_IWbemEventProviderQuerySink) { *iplpv = static_cast(this) ; } else { *iplpv = 0; return E_NOINTERFACE; } DCProxy::AddRef () ; return S_OK; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HRESULT DCProxy :: Initialize ( LPWSTR a_User, LONG a_Flags, LPWSTR a_Namespace, LPWSTR a_Locale, IWbemServices *a_CoreService, // For anybody IWbemContext *a_Context, IWbemProviderInitSink *a_Sink // For init signals ) { // The connection to the agregator is deffered if( !a_Sink) return WBEM_E_INVALID_PARAMETER; if(!a_CoreService ) return a_Sink->SetStatus ( WBEM_E_INVALID_PARAMETER , 0 ) ; m_CoreService = a_CoreService; m_Context = a_Context; m_Flags = a_Flags; try{ m_User = a_User; m_Locale = a_Locale; m_Namespace = a_Namespace; // Register the Registrar if (DC_registrar::instance()) DC_registrar::instance()->Save(); } catch( _com_error& err) { return a_Sink->SetStatus ( WBEM_E_OUT_OF_MEMORY , 0 ) ; } // Instance provider - we don't know the provider name // The real initialization is deffered if(!event_only_) return a_Sink->SetStatus ( S_OK , 0 ) ; // Event provider - safely to initialize HRESULT hr = _initialize(); return a_Sink->SetStatus ( hr , 0 ) ; } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HRESULT DCProxy::GetObjectAsync (const BSTR a_ObjectPath, long a_Flags, IWbemContext *a_Context, IWbemObjectSink *a_Sink) { HRESULT t_Result = initialize_from_instance (a_ObjectPath); if (FAILED (t_Result)) return WBEM_E_FAILED; return m_aggregator_->GetObjectAsync( a_ObjectPath, a_Flags, a_Context, a_Sink ); } HRESULT DCProxy :: PutInstanceAsync ( IWbemClassObject *a_Instance, long a_Flags , IWbemContext *a_Context , IWbemObjectSink *a_Sink ) { HRESULT t_Result = initialize( a_Instance ); if ( FAILED (t_Result ) ) return t_Result; return m_aggregator_->PutInstanceAsync( a_Instance, a_Flags, a_Context, a_Sink ); } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HRESULT DCProxy :: DeleteInstanceAsync ( const BSTR a_ObjectPath, long a_Flags, IWbemContext *a_Context, IWbemObjectSink *a_Sink ) { HRESULT t_Result = initialize_from_instance (a_ObjectPath); if (FAILED (t_Result)) return WBEM_E_FAILED; return m_aggregator_->DeleteInstanceAsync(a_ObjectPath, a_Flags, a_Context, a_Sink ); } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HRESULT DCProxy::CreateInstanceEnumAsync (const BSTR a_Class , long a_Flags , IWbemContext *a_Context , IWbemObjectSink *a_Sink) { HRESULT t_Result = initialize (a_Class); if (FAILED (t_Result)) return t_Result; return m_aggregator_->CreateInstanceEnumAsync (a_Class, a_Flags, a_Context, a_Sink); } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HRESULT DCProxy::ExecMethodAsync (const BSTR a_ObjectPath, const BSTR a_MethodName, long a_Flags, IWbemContext *a_Context, IWbemClassObject *a_InParams, IWbemObjectSink *a_Sink) { HRESULT t_Result = initialize (a_ObjectPath); if (FAILED (t_Result)) return t_Result; return m_aggregator_->ExecMethodAsync (a_ObjectPath, a_MethodName, a_Flags , a_Context, a_InParams, a_Sink); } /****************************************************************************** * * Name: * * * Description: * * *****************************************************************************/ HRESULT DCProxy::ProvideEvents (IWbemObjectSink *a_Sink , long a_Flags) { if (m_aggregator_) return m_aggregator_->ProvideEvents (a_Sink, a_Flags); else return WBEM_E_FAILED; } bool DCProxy::initialized () { return m_aggregator_; }; HRESULT DCProxy::_initialize () { DC_DBkey key( m_User, m_Locale, m_Namespace, m_ProviderName); auto_ref tmp = DC_registrar::instance()->GetAggregator( key ); if( tmp ) { if ( tmp->initialized() ) { m_aggregator_ = tmp; m_aggregator_->activate(); return S_OK; } CServerObject_ProviderInitSink *t_ProviderInitSink = new CServerObject_ProviderInitSink ; if (t_ProviderInitSink) { t_ProviderInitSink->AddRef(); HRESULT hr = tmp ->Initialize( (wchar_t *)m_User, m_Flags, (wchar_t *)m_Namespace, (wchar_t *)m_Locale, (wchar_t *)m_ProviderName, m_CoreService.GetInterfacePtr(), m_Context.GetInterfacePtr(), t_ProviderInitSink ); t_ProviderInitSink->Release(); if( SUCCEEDED ( hr) ) { m_aggregator_ = tmp; m_aggregator_->activate(); }; return hr; } else return WBEM_E_OUT_OF_MEMORY ; } else return WBEM_E_OUT_OF_MEMORY ; }; HRESULT DCProxy ::initialize (IWbemClassObject * pObj) { if (initialized()) return S_OK; _variant_t v; HRESULT hr = pObj->Get(L"__CLASS", 0, &v, 0, 0); // check the HRESULT to see if the action succeeded if (SUCCEEDED (hr)) { return initialize ( _bstr_t (v)); } return WBEM_E_FAILED; }; HRESULT DCProxy::initialize (const BSTR _name) { if (initialized ()) return S_OK; LockGuard t_guard( DC_registrar::instance()->GetLock()); if (t_guard.locked()==false) return WBEM_E_OUT_OF_MEMORY; // Double checked looking variant if (initialized ()) return S_OK; IWbemClassObject * t_ObjectPath = NULL ; IWbemClassObject *Identity ; HRESULT t_Result = m_CoreService->GetObject (_name , 0 , m_Context , & Identity , NULL) ; if (FAILED (t_Result)) return t_Result; IWbemQualifierSet *t_QualifierObject = NULL ; t_Result = Identity->GetQualifierSet (&t_QualifierObject); if (SUCCEEDED (t_Result)) { _variant_t prov_name; t_Result = t_QualifierObject->Get (L"provider", 0, & prov_name, NULL); if (SUCCEEDED (t_Result)) { m_ProviderName = (_bstr_t)prov_name; }; t_QualifierObject->Release(); } return _initialize(); } HRESULT DCProxy::initialize_from_instance (const BSTR _path) { if (initialized ()) return S_OK; wchar_t * pszClassName = NULL; IWbemPathPtr pPath; HRESULT t_Result = pPath.CreateInstance (CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER); if (SUCCEEDED (t_Result)) { t_Result = pPath->SetText (WBEMPATH_CREATE_ACCEPT_ALL , _path) ; if (SUCCEEDED (t_Result)) { ULONG uBuf = 0; t_Result = pPath->GetClassName(&uBuf, 0); if (SUCCEEDED (t_Result)) { pszClassName = new wchar_t[uBuf+1]; if (pszClassName == 0) return WBEM_E_OUT_OF_MEMORY; wmilib::auto_buffer deleteArray(pszClassName); t_Result = pPath->GetClassName(&uBuf, pszClassName); if (FAILED(t_Result)) { return WBEM_E_FAILED; } t_Result = initialize (pszClassName); } } } return t_Result; // The return code is used internally } HRESULT DCProxy ::AccessCheck ( WBEM_CWSTR a_QueryLanguage , WBEM_CWSTR a_Query , long a_SidLength , const BYTE *a_Sid ) { if( m_aggregator_ ) return m_aggregator_ ->AccessCheck ( a_QueryLanguage, a_Query, a_SidLength, a_Sid); else return WBEM_E_FAILED; } HRESULT DCProxy::SetRegistrationObject( long lFlags, IWbemClassObject* pProvReg ) { HRESULT t_Result = WBEM_E_FAILED; _variant_t v; t_Result = pProvReg->Get(L"NAME", 0, &v, 0, 0); // check the HRESULT to see if the action succeeded if ( SUCCEEDED( t_Result) ) { m_ProviderName = (_bstr_t)v; event_only_ = true; return WBEM_S_NO_ERROR; } else { return WBEM_E_FAILED; } }; HRESULT DCProxy::NewQuery( unsigned long dwId, WBEM_WSTR wszQueryLanguage, WBEM_WSTR wszQuery ) { if( !initialized() ) return WBEM_E_FAILED; return m_aggregator_->NewQuery( dwId, wszQueryLanguage, wszQuery ); } HRESULT DCProxy::CancelQuery( unsigned long dwId ) { if( !initialized() ) return WBEM_E_FAILED; return m_aggregator_->CancelQuery( dwId ); }; HRESULT DCProxy::ExecQueryAsync( const BSTR strQueryLanguage, const BSTR strQuery, long lFlags, IWbemContext *pCtx, IWbemObjectSink *pResponseHandler ) { // Try to parse it // =============== CTextLexSource src(strQuery); CWQLScanner Parser(&src); int nRes = Parser.Parse(); if(nRes != CWQLScanner::SUCCESS) { return WBEM_E_INVALID_QUERY; } // Successfully parsed. Go to the first tables involved // ====================================================== CWStringArray awsTables; Parser.GetReferencedTables(awsTables); if (awsTables.Size()>0) { HRESULT t_Result = initialize( awsTables[0] ); if (SUCCEEDED(t_Result)) { return m_aggregator_->ExecQueryAsync( strQueryLanguage, strQuery, lFlags, pCtx, pResponseHandler ); } else return t_Result; } else { return WBEM_E_FAILED; } }; STDMETHODIMP DCProxy::GetProperty( long lFlags, const BSTR strLocale, const BSTR strClassMapping, const BSTR strInstMapping, const BSTR strPropMapping, VARIANT *pvValue ) { return WBEM_S_FALSE; }; STDMETHODIMP DCProxy::PutProperty( long lFlags, const BSTR strLocale, const BSTR strClassMapping, const BSTR strInstMapping, const BSTR strPropMapping, const VARIANT *pvValue ) { return WBEM_S_FALSE; }