587 lines
15 KiB
C++
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
|