windows-nt/Source/XPSP1/NT/base/cluster/mgmt/cluscfg/middletier/taskpollingcallback.cpp
2020-09-26 16:20:57 +08:00

587 lines
15 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2001 Microsoft Corporation
//
// Module Name:
// TaskPollingCallback.cpp
//
// Description:
// CTaskPollingCallback implementation.
//
// Maintained By:
// Galen Barbee (GalenB) 10-JUL-2000
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.h"
#include <ClusCfgPrivate.h>
#include "TaskPollingCallback.h"
DEFINE_THISCLASS("CTaskPollingCallback")
// ************************************************************************
//
// Constructor / Destructor
//
// ************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// HRESULT
// CTaskPollingCallback::S_HrCreateInstance(
// IUnknown ** ppunkOut
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
HRESULT
CTaskPollingCallback::S_HrCreateInstance(
IUnknown ** ppunkOut
)
{
TraceFunc( "" );
Assert( ppunkOut != NULL );
HRESULT hr = S_FALSE;
CTaskPollingCallback * pTaskPollingCallback = NULL;
if ( ppunkOut == NULL )
{
hr = THR( E_POINTER );
goto Cleanup;
} // if:
pTaskPollingCallback = new CTaskPollingCallback;
if ( pTaskPollingCallback == NULL )
{
hr = E_OUTOFMEMORY;
goto Cleanup;
} // if:
TraceMoveToMemoryList( pTaskPollingCallback, g_GlobalMemoryList );
hr = THR( pTaskPollingCallback->Init() );
if ( FAILED( hr ) )
{
goto Cleanup;
}
hr = THR( pTaskPollingCallback->TypeSafeQI( IUnknown, ppunkOut ) );
Cleanup:
if ( pTaskPollingCallback != NULL )
{
pTaskPollingCallback->Release();
} // if:
HRETURN( hr );
} //*** CTaskPollingCallback::S_HrCreateInstance
//////////////////////////////////////////////////////////////////////////////
//++
//
// CTaskPollingCallback::CTaskPollingCallback( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
CTaskPollingCallback::CTaskPollingCallback( void )
: m_cRef( 1 )
{
TraceFunc( "" );
InterlockedIncrement( &g_cObjects );
Assert( m_fStop == false );
Assert( m_dwServerGITCookie == NULL );
TraceFuncExit();
} //*** CTaskPollingCallback::CTaskPollingCallback
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP
// CTaskPollingCallback::Init( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CTaskPollingCallback::Init( void )
{
TraceFunc( "" );
HRESULT hr = S_OK;
HRETURN( hr );
} //*** CTaskPollingCallback::Init
//////////////////////////////////////////////////////////////////////////////
//++
//
// CTaskPollingCallback::~CTaskPollingCallback( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
CTaskPollingCallback::~CTaskPollingCallback( void )
{
TraceFunc( "" );
TraceMoveFromMemoryList( this, g_GlobalMemoryList );
InterlockedDecrement( &g_cObjects );
TraceFuncExit();
} //*** CTaskPollingCallback::~CTaskPollingCallback
// ************************************************************************
//
// IUnknown
//
// ************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP
// CTaskPollingCallback::QueryInterface(
// REFIID riidIn,
// LPVOID * ppvOut
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CTaskPollingCallback::QueryInterface(
REFIID riidIn,
LPVOID * ppvOut
)
{
TraceQIFunc( riidIn, ppvOut );
HRESULT hr = E_NOINTERFACE;
if ( IsEqualIID( riidIn, IID_IUnknown ) )
{
*ppvOut = static_cast< ITaskPollingCallback * >( this );
hr = S_OK;
} // if: IUnknown
else if ( IsEqualIID( riidIn, IID_ITaskPollingCallback ) )
{
*ppvOut = TraceInterface( __THISCLASS__, ITaskPollingCallback, this, 0 );
hr = S_OK;
} // else if: ITaskPollingCallback
else if ( IsEqualIID( riidIn, IID_IDoTask ) )
{
*ppvOut = TraceInterface( __THISCLASS__, IDoTask, this, 0 );
hr = S_OK;
} // else if: IDoTask
if ( SUCCEEDED( hr ) )
{
((IUnknown*) *ppvOut)->AddRef();
} // if: success
QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
} // QueryInterface
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP_( ULONG )
// CTaskPollingCallback::AddRef( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG )
CTaskPollingCallback::AddRef( void )
{
TraceFunc( "[IUnknown]" );
InterlockedIncrement( &m_cRef );
RETURN( m_cRef );
} //*** CTaskPollingCallback::AddRef
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP_( ULONG )
// CTaskPollingCallback::Release( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG )
CTaskPollingCallback::Release( void )
{
TraceFunc( "[IUnknown]" );
InterlockedDecrement( &m_cRef );
if ( m_cRef )
RETURN( m_cRef );
TraceDo( delete this );
RETURN( 0 );
} //*** CTaskPollingCallback::Release
//****************************************************************************
//
// ITaskPollingCallback
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP
// CTaskPollingCallback::BeginTask( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CTaskPollingCallback::BeginTask( void )
{
TraceFunc( "[IDoTask]" );
HRESULT hr = S_OK;
BSTR bstrNodeName = NULL;
BSTR bstrLastNodeName = NULL;
BSTR bstrReference = NULL;
BSTR bstrDescription = NULL;
CLSID clsidTaskMajor;
CLSID clsidTaskMinor;
ULONG ulMin;
ULONG ulMax;
ULONG ulCurrent;
HRESULT hrStatus;
FILETIME ft;
IGlobalInterfaceTable * pgit = NULL;
IClusCfgServer * pccs = NULL;
IClusCfgPollingCallback * piccpc = NULL;
IClusCfgPollingCallbackInfo * piccpci = NULL;
IServiceProvider * psp = NULL;
IConnectionPointContainer * pcpc = NULL;
IConnectionPoint * pcp = NULL;
IClusCfgCallback * pcccb = NULL;
//
// Collect the manager we need to complete this task.
//
hr = THR( CoCreateInstance( CLSID_ServiceManager, NULL, CLSCTX_INPROC_SERVER, TypeSafeParams( IServiceProvider, &psp ) ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( psp->TypeSafeQS( CLSID_NotificationManager, IConnectionPointContainer, &pcpc ) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( pcpc->FindConnectionPoint( IID_IClusCfgCallback, &pcp ) );
if ( FAILED( hr ) )
goto Cleanup;
pcp = TraceInterface( L"CConfigurationConnection!IConnectionPoint", IConnectionPoint, pcp, 1 );
hr = THR( pcp->TypeSafeQI( IClusCfgCallback, &pcccb ) );
if ( FAILED( hr ) )
goto Cleanup;
pcccb = TraceInterface( L"CConfigurationConnection!IClusCfgCallback", IClusCfgCallback, pcccb, 1 );
psp->Release();
psp = NULL;
//
// Create the GIT.
//
hr = THR( CoCreateInstance( CLSID_StdGlobalInterfaceTable,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable,
reinterpret_cast< void ** >( &pgit )
) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if
//
// Get the ClusCfgServer interface from the GIT.
//
hr = THR( pgit->GetInterfaceFromGlobal( m_dwServerGITCookie, IID_IClusCfgServer, reinterpret_cast< void ** >( &pccs ) ) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if
//
// Get the PollingCallback object from the server.
//
hr = THR( pccs->TypeSafeQI( IClusCfgPollingCallbackInfo, &piccpci ) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if
hr = THR( piccpci->GetCallback( &piccpc ) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if
//
// Begin polling for SendStatusReports.
//
while ( !m_fStop )
{
if ( bstrNodeName != NULL )
{
TraceSysFreeString( bstrLastNodeName );
bstrLastNodeName = NULL;
// Give up ownership
bstrLastNodeName = bstrNodeName;
bstrNodeName = NULL;
} // if:
TraceSysFreeString( bstrDescription );
bstrDescription = NULL;
TraceSysFreeString( bstrReference );
bstrReference = NULL;
hr = STHR( piccpc->GetStatusReport(
&bstrNodeName,
&clsidTaskMajor,
&clsidTaskMinor,
&ulMin,
&ulMax,
&ulCurrent,
&hrStatus,
&bstrDescription,
&ft,
&bstrReference
) );
TraceMemoryAddBSTR( bstrNodeName );
TraceMemoryAddBSTR( bstrDescription );
TraceMemoryAddBSTR( bstrReference );
if ( FAILED( hr ) )
{
HRESULT hr2;
BSTR bstrNotification = NULL;
LogMsg( L"PollingCallback: GetStatusReport() failed. hr = 0x%08x", hr );
hr2 = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_POLLING_CONNECTION_FAILURE, &bstrNotification ) );
hr2 = THR( pcccb->SendStatusReport(
bstrLastNodeName
, TASKID_Major_Establish_Connection
, TASKID_Minor_Polling_Connection_Failure
, 0
, 1
, 0
, hr
, bstrNotification
, NULL
, NULL
) );
TraceSysFreeString( bstrNotification );
switch ( hr )
{
case S_OK:
case S_FALSE:
break; // ignore
case HRESULT_FROM_WIN32( RPC_E_DISCONNECTED ):
LogMsg( L"PollingCallback: GetStatusReport() failed. hr = RPC_E_DISCONNECTED. Aborting polling.", hr );
goto Cleanup;
case HRESULT_FROM_WIN32( RPC_S_SERVER_UNAVAILABLE ):
LogMsg( L"PollingCallback: GetStatusReport() failed. hr = RPC_S_SERVER_UNAVAILABLE. Aborting polling.", hr );
goto Cleanup;
case HRESULT_FROM_WIN32( RPC_S_CALL_FAILED ):
LogMsg( L"PollingCallback: GetStatusReport() failed. hr = RPC_S_CALL_FAILED. Aborting polling.", hr );
goto Cleanup;
default:
LogMsg( L"PollingCallback: GetStatusReport() failed. hr = %#08x. Continuing to poll.", hr );
break;
}
if ( hr2 == E_ABORT )
{
LogMsg( L"PollingCallback: UI layer returned E_ABORT. Aborting polling." );
break;
}
} // if:
if ( hr == S_OK )
{
HRESULT hrTmp;
hr = THR( pcccb->SendStatusReport(
bstrNodeName,
clsidTaskMajor,
clsidTaskMinor,
ulMin,
ulMax,
ulCurrent,
hrStatus,
bstrDescription,
&ft,
bstrReference
) );
if ( hr == E_ABORT )
{
LogMsg( L"PollingCallback: UI layer returned E_ABORT. Aborting polling." );
}
hrTmp = hr;
hr = THR( piccpc->SetHResult( hrTmp ) );
if ( FAILED( hr ) )
{
LogMsg( L"PollingCallback: SetHResult() failed. hr = 0x%08x", hr );
} // if:
} // if:
else
{
Sleep( 1000 );
//
// Check to see if we need to bail.
//
hr = THR( CServiceManager::S_HrGetManagerPointer( &psp ) );
if ( FAILED( hr ) )
break;
psp->Release();
psp = NULL;
}
} // while:
Cleanup:
if ( psp != NULL )
{
psp->Release();
} // if:
if ( pgit != NULL )
{
pgit->Release();
} // if:
if ( pccs != NULL )
{
pccs->Release();
} // if:
if ( piccpc != NULL )
{
piccpc->Release();
} // if:
if ( piccpci != NULL )
{
piccpci->Release();
} // if:
if ( pcpc != NULL )
{
pcpc->Release();
} // if:
if ( pcp != NULL )
{
pcp->Release();
} // if:
if ( pcccb != NULL )
{
pcccb->Release();
} // if:
TraceSysFreeString( bstrNodeName );
TraceSysFreeString( bstrDescription );
TraceSysFreeString( bstrReference );
TraceSysFreeString( bstrLastNodeName );
HRETURN( hr );
} //*** CTaskPollingCallback::BeginTask
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP
// CTaskPollingCallback::StopTask( void )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CTaskPollingCallback::StopTask( void )
{
TraceFunc( "[IDoTask]" );
HRESULT hr = S_OK;
m_fStop = true;
HRETURN( hr );
} //*** CTaskPollingCallback::StopTask
//////////////////////////////////////////////////////////////////////////////
//++
//
// STDMETHODIMP
// CTaskPollingCallback::SetServerGITCookie(
// DWORD dwGITCookieIn
// )
//
//--
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CTaskPollingCallback::SetServerGITCookie(
DWORD dwGITCookieIn
)
{
TraceFunc( "[ITaskPollingCallback]" );
HRESULT hr = S_OK;
m_dwServerGITCookie = dwGITCookieIn;
HRETURN( hr );
} //*** CTaskPollingCallback::SetServerGITCookie