490 lines
7.9 KiB
C++
490 lines
7.9 KiB
C++
|
//***************************************************************************
|
||
|
|
||
|
//
|
||
|
|
||
|
// VPSINKS.CPP
|
||
|
|
||
|
//
|
||
|
|
||
|
// Module: WBEM VIEW PROVIDER
|
||
|
|
||
|
//
|
||
|
|
||
|
// Purpose: Contains the sinks implementations
|
||
|
|
||
|
//
|
||
|
|
||
|
// Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#include <provexpt.h>
|
||
|
#include <provcoll.h>
|
||
|
#include <provtempl.h>
|
||
|
#include <provmt.h>
|
||
|
#include <typeinfo.h>
|
||
|
#include <process.h>
|
||
|
#include <objbase.h>
|
||
|
#include <objidl.h>
|
||
|
#include <stdio.h>
|
||
|
#include <wbemidl.h>
|
||
|
#include <provcont.h>
|
||
|
#include <provevt.h>
|
||
|
#include <provthrd.h>
|
||
|
#include <provlog.h>
|
||
|
#include <cominit.h>
|
||
|
#include <dsgetdc.h>
|
||
|
#include <lmcons.h>
|
||
|
#include <lmapibuf.h>
|
||
|
|
||
|
#include <instpath.h>
|
||
|
#include <genlex.h>
|
||
|
#include <sql_1.h>
|
||
|
#include <objpath.h>
|
||
|
|
||
|
#include <vpdefs.h>
|
||
|
#include <vpcfac.h>
|
||
|
#include <vpquals.h>
|
||
|
#include <vpserv.h>
|
||
|
#include <vptasks.h>
|
||
|
|
||
|
extern CRITICAL_SECTION g_CriticalSection;
|
||
|
|
||
|
|
||
|
CWbemClassObjectWithIndex :: CWbemClassObjectWithIndex(DWORD a_indx, IWbemClassObject *a_pObj)
|
||
|
: m_pObject(NULL), m_ReferenceCount(0), m_nsindex(a_indx)
|
||
|
{
|
||
|
if (a_pObj)
|
||
|
{
|
||
|
a_pObj->AddRef();
|
||
|
m_pObject = a_pObj;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CWbemClassObjectWithIndex :: ~CWbemClassObjectWithIndex()
|
||
|
{
|
||
|
if (m_pObject)
|
||
|
{
|
||
|
m_pObject->Release();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ULONG CWbemClassObjectWithIndex :: AddRef ()
|
||
|
{
|
||
|
return InterlockedIncrement(&m_ReferenceCount);
|
||
|
}
|
||
|
|
||
|
ULONG CWbemClassObjectWithIndex :: Release ()
|
||
|
{
|
||
|
ULONG t_Ref;
|
||
|
|
||
|
if ( (t_Ref = InterlockedDecrement(&m_ReferenceCount)) == 0 )
|
||
|
{
|
||
|
delete this ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return t_Ref ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CObjectSinkResults::CObjectSinkResults(WbemTaskObject* parent, DWORD index)
|
||
|
{
|
||
|
m_ReferenceCount = 0;
|
||
|
m_index = index;
|
||
|
m_bSet = FALSE;
|
||
|
m_hr = 0;
|
||
|
m_parent = parent;
|
||
|
m_parent->AddRef();
|
||
|
m_ObjArray.SetSize(0, 10); //grow by 10s
|
||
|
}
|
||
|
|
||
|
CObjectSinkResults::~CObjectSinkResults()
|
||
|
{
|
||
|
if (m_parent != NULL)
|
||
|
{
|
||
|
m_parent->Release();
|
||
|
}
|
||
|
|
||
|
m_ObjArray.RemoveAll();
|
||
|
}
|
||
|
|
||
|
ULONG CObjectSinkResults::AddRef()
|
||
|
{
|
||
|
return InterlockedIncrement(&m_ReferenceCount);
|
||
|
}
|
||
|
|
||
|
ULONG CObjectSinkResults::Release()
|
||
|
{
|
||
|
LONG t_Ref;
|
||
|
|
||
|
if ( (t_Ref = InterlockedDecrement(&m_ReferenceCount)) == 0 )
|
||
|
{
|
||
|
delete this ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return t_Ref ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CObjectSinkResults::SetStatus(HRESULT hr, CViewProvObjectSink *pSnk)
|
||
|
{
|
||
|
if (m_CriticalSection.Lock())
|
||
|
{
|
||
|
if (SUCCEEDED(m_hr))
|
||
|
{
|
||
|
m_hr = hr;
|
||
|
}
|
||
|
|
||
|
RemoveSink(pSnk);
|
||
|
m_bSet = TRUE;
|
||
|
|
||
|
if (m_parent != NULL)
|
||
|
{
|
||
|
m_parent->SetStatus(hr, m_index);
|
||
|
}
|
||
|
|
||
|
m_CriticalSection.Unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CObjectSinkResults::SetSink(CViewProvObjectSink *pSnk)
|
||
|
{
|
||
|
if (m_CriticalSection.Lock())
|
||
|
{
|
||
|
m_realSnks.AddTail(pSnk);
|
||
|
m_CriticalSection.Unlock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL CObjectSinkResults::RemoveSink(CViewProvObjectSink *pSnk)
|
||
|
{
|
||
|
BOOL retVal = FALSE;
|
||
|
|
||
|
if (m_CriticalSection.Lock())
|
||
|
{
|
||
|
POSITION t_pos = m_realSnks.GetHeadPosition();
|
||
|
|
||
|
while (t_pos)
|
||
|
{
|
||
|
POSITION t_badPos = t_pos;
|
||
|
CViewProvObjectSink * t_pSnk = m_realSnks.GetNext(t_pos);
|
||
|
|
||
|
if (pSnk == t_pSnk)
|
||
|
{
|
||
|
m_realSnks.RemoveAt(t_badPos);
|
||
|
retVal = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_CriticalSection.Unlock();
|
||
|
}
|
||
|
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
void CObjectSinkResults::Disconnect()
|
||
|
{
|
||
|
//can't call disconnect when locked, since this calls CancelAsyncCall
|
||
|
CList<CViewProvObjectSink*,CViewProvObjectSink*> t_realSnks;
|
||
|
|
||
|
if (m_CriticalSection.Lock())
|
||
|
{
|
||
|
while (m_realSnks.GetCount() > 0)
|
||
|
{
|
||
|
CViewProvObjectSink* t_pSnk = m_realSnks.RemoveTail();
|
||
|
|
||
|
if (t_pSnk)
|
||
|
{
|
||
|
t_pSnk->AddRef();
|
||
|
t_realSnks.AddTail(t_pSnk);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_parent != NULL)
|
||
|
{
|
||
|
m_parent->Release();
|
||
|
m_parent = NULL;
|
||
|
}
|
||
|
|
||
|
m_CriticalSection.Unlock();
|
||
|
}
|
||
|
|
||
|
while (t_realSnks.GetCount() > 0)
|
||
|
{
|
||
|
CViewProvObjectSink* t_pSnk = t_realSnks.RemoveTail();
|
||
|
|
||
|
if (t_pSnk)
|
||
|
{
|
||
|
t_pSnk->Disconnect();
|
||
|
t_pSnk->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT CObjectSinkResults::Indicate(LONG count, IWbemClassObject** ppObjArray, DWORD a_indx)
|
||
|
{
|
||
|
HRESULT hr = WBEM_NO_ERROR;
|
||
|
|
||
|
if ( (count > 0) && m_CriticalSection.Lock() )
|
||
|
{
|
||
|
if (m_parent != NULL)
|
||
|
{
|
||
|
m_parent->SetResultReceived();
|
||
|
|
||
|
for (LONG x = 0; x < count; x++)
|
||
|
{
|
||
|
if (ppObjArray[x] != NULL)
|
||
|
{
|
||
|
CWbemClassObjectWithIndex *t_clsWrap = new CWbemClassObjectWithIndex(a_indx, ppObjArray[x]);
|
||
|
t_clsWrap->AddRef();
|
||
|
m_ObjArray.Add(t_clsWrap);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = WBEM_E_INVALID_PARAMETER;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = WBEM_E_CALL_CANCELLED;
|
||
|
}
|
||
|
|
||
|
m_CriticalSection.Unlock();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (count < 0)
|
||
|
{
|
||
|
hr = WBEM_E_INVALID_PARAMETER;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
CViewProvObjectSink::CViewProvObjectSink(CObjectSinkResults* parent, CWbemServerWrap *pServ, DWORD a_indx)
|
||
|
:m_parent(NULL), m_ServWrap(NULL), m_nsindex(a_indx)
|
||
|
{
|
||
|
EnterCriticalSection(&g_CriticalSection);
|
||
|
CViewProvClassFactory :: objectsInProgress++;
|
||
|
LeaveCriticalSection(&g_CriticalSection);
|
||
|
m_ReferenceCount = 0;
|
||
|
m_parent = parent;
|
||
|
m_parent->AddRef();
|
||
|
m_parent->SetSink(this);
|
||
|
m_ServWrap = pServ;
|
||
|
m_ServWrap->AddRef();
|
||
|
m_RemoteSink = NULL;
|
||
|
m_DoCancel = TRUE;
|
||
|
}
|
||
|
|
||
|
CViewProvObjectSink::~CViewProvObjectSink()
|
||
|
{
|
||
|
if (m_parent != NULL)
|
||
|
{
|
||
|
//set status has not been called so call it...
|
||
|
m_parent->SetStatus(WBEM_E_FAILED, this);
|
||
|
m_parent->Release();
|
||
|
}
|
||
|
|
||
|
if (m_ServWrap != NULL)
|
||
|
{
|
||
|
m_ServWrap->Release();
|
||
|
}
|
||
|
|
||
|
if (m_RemoteSink != NULL)
|
||
|
{
|
||
|
m_RemoteSink->Release();
|
||
|
}
|
||
|
|
||
|
EnterCriticalSection(&g_CriticalSection);
|
||
|
CViewProvClassFactory :: objectsInProgress--;
|
||
|
LeaveCriticalSection(&g_CriticalSection);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CViewProvObjectSink::QueryInterface (REFIID refIID, LPVOID FAR * ppV)
|
||
|
{
|
||
|
if (ppV == NULL)
|
||
|
{
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
|
||
|
*ppV = NULL ;
|
||
|
|
||
|
if ( refIID == IID_IUnknown )
|
||
|
{
|
||
|
*ppV = ( IWbemObjectSink* ) this ;
|
||
|
}
|
||
|
else if ( refIID == IID_IWbemObjectSink )
|
||
|
{
|
||
|
*ppV = ( IWbemObjectSink* ) this ;
|
||
|
}
|
||
|
|
||
|
if ( *ppV )
|
||
|
{
|
||
|
( ( LPUNKNOWN ) *ppV )->AddRef () ;
|
||
|
|
||
|
return S_OK ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return E_NOINTERFACE ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CViewProvObjectSink::AddRef()
|
||
|
{
|
||
|
return InterlockedIncrement(&m_ReferenceCount);
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CViewProvObjectSink::Release()
|
||
|
{
|
||
|
LONG t_Ref;
|
||
|
|
||
|
if ( (t_Ref = InterlockedDecrement(&m_ReferenceCount)) == 0 )
|
||
|
{
|
||
|
delete this ;
|
||
|
return 0 ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return t_Ref ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT CViewProvObjectSink::Indicate(LONG count, IWbemClassObject** ppObjArray)
|
||
|
{
|
||
|
HRESULT hr = WBEM_NO_ERROR;
|
||
|
|
||
|
if (m_lock.Lock())
|
||
|
{
|
||
|
if (m_parent != NULL)
|
||
|
{
|
||
|
hr = m_parent->Indicate(count, ppObjArray, m_nsindex);
|
||
|
}
|
||
|
|
||
|
m_lock.Unlock();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CViewProvObjectSink::SetStatus(LONG lFlags, HRESULT hr, BSTR bStr, IWbemClassObject* pObj)
|
||
|
{
|
||
|
if (m_lock.Lock())
|
||
|
{
|
||
|
if (m_parent != NULL)
|
||
|
{
|
||
|
m_parent->SetStatus(hr, this);
|
||
|
m_parent->Release();
|
||
|
m_parent = NULL;
|
||
|
|
||
|
DisAssociate();
|
||
|
m_DoCancel = FALSE;
|
||
|
}
|
||
|
|
||
|
m_lock.Unlock();
|
||
|
}
|
||
|
|
||
|
return WBEM_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
void CViewProvObjectSink::Disconnect()
|
||
|
{
|
||
|
BOOL doCancel = FALSE;
|
||
|
|
||
|
if (m_lock.Lock())
|
||
|
{
|
||
|
if (m_DoCancel)
|
||
|
{
|
||
|
doCancel = TRUE;
|
||
|
m_DoCancel = FALSE;
|
||
|
|
||
|
if (m_parent != NULL)
|
||
|
{
|
||
|
m_parent->Release();
|
||
|
m_parent = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_lock.Unlock();
|
||
|
}
|
||
|
|
||
|
if (doCancel)
|
||
|
{
|
||
|
if (m_ServWrap != NULL)
|
||
|
{
|
||
|
IWbemServices *ptmpServ = m_ServWrap->GetServerOrProxy();
|
||
|
|
||
|
if (ptmpServ)
|
||
|
{
|
||
|
if (m_RemoteSink != NULL)
|
||
|
{
|
||
|
ptmpServ->CancelAsyncCall(this);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ptmpServ->CancelAsyncCall(m_RemoteSink);
|
||
|
DisAssociate();
|
||
|
}
|
||
|
|
||
|
m_ServWrap->ReturnServerOrProxy(ptmpServ);
|
||
|
}
|
||
|
|
||
|
m_ServWrap->Release();
|
||
|
m_ServWrap = NULL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IWbemObjectSink* CViewProvObjectSink::Associate()
|
||
|
{
|
||
|
IUnsecuredApartment* pUA = NULL;
|
||
|
|
||
|
if ( SUCCEEDED(CViewProvServ::GetUnsecApp(&pUA)) )
|
||
|
{
|
||
|
IUnknown* pUnk = NULL;
|
||
|
|
||
|
if ( SUCCEEDED(pUA->CreateObjectStub(this, &pUnk)) )
|
||
|
{
|
||
|
if ( FAILED(pUnk->QueryInterface(IID_IWbemObjectSink, (void **)&m_RemoteSink)) )
|
||
|
{
|
||
|
pUnk = NULL;
|
||
|
}
|
||
|
|
||
|
pUnk->Release();
|
||
|
}
|
||
|
|
||
|
pUA->Release();
|
||
|
}
|
||
|
|
||
|
return m_RemoteSink;
|
||
|
}
|
||
|
|
||
|
void CViewProvObjectSink::DisAssociate()
|
||
|
{
|
||
|
if (m_RemoteSink != NULL)
|
||
|
{
|
||
|
m_RemoteSink->Release();
|
||
|
m_RemoteSink = NULL;
|
||
|
}
|
||
|
|
||
|
if (m_lock.Lock())
|
||
|
{
|
||
|
if (m_parent != NULL)
|
||
|
{
|
||
|
m_parent->Release();
|
||
|
m_parent = NULL;
|
||
|
}
|
||
|
|
||
|
m_lock.Unlock();
|
||
|
}
|
||
|
}
|