Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

651 lines
14 KiB

#include "precomp.h"
#include <objbase.h>
#include <wbemcli.h>
#include <wbemint.h>
#include <wmiutils.h>
#include "Globals.h"
#include "ProvRegDeCoupled.h"
#include <wmiutils.h>
#include "CGlobals.h"
#include "provcache.h"
#include "aggregator.h"
#include "ProvWsvS.h"
#include "ProvWsv.h"
#include "ProvInSk.h"
#include "ProvobSk.h"
#include <genlex.h>
#include <flexarry.h>
#include <wqllex.h>
struct SWQLColRef;
#include <wqlscan.h>
#include <autoptr.h>
/******************************************************************************
*
* 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<NULL_IWbemServices*>(this) ;
}
else if (iid == IID_IWbemServices)
{
*iplpv = static_cast<IWbemServices *>(this) ;
}
else if (iid == IID_IWbemPropertyProvider)
{
*iplpv = static_cast<IWbemPropertyProvider *>(this);
}
else if ( iid == IID_IWbemProviderInit )
{
*iplpv = static_cast<IWbemProviderInit *>(this) ;
}
else if ( iid == IID_IWbemEventProvider )
{
*iplpv = static_cast<IWbemEventProvider *>(this) ;
}
else if ( iid == IID_IWbemEventProviderSecurity )
{
*iplpv = static_cast<IWbemEventProviderSecurity *>(this) ;
}
else if ( iid == IID_IWbemProviderIdentity )
{
*iplpv = static_cast<IWbemProviderIdentity *>(this) ;
}
else if ( iid == IID_IWbemEventProviderQuerySink)
{
*iplpv = static_cast<IWbemEventProviderQuerySink *>(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<DCProxyAggr> 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<CriticalSection> 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<wchar_t> 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;
}