2025-11-28 00:35:46 +09:00

770 lines
18 KiB
C++

/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003 <company name>
//
// Module Name:
// ExtObj.cpp
//
// Description:
// Implementation of the CExtObject class, which implements the
// extension interfaces required by a Microsoft Windows NT Cluster
// Administrator Extension DLL.
//
// Author:
// <name> (<e-mail name>) Mmmm DD, 2003
//
// Revision History:
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ClipBook ServerEx.h"
#include "ExtObj.h"
#include "ExtObjData.h"
#include "ResProp.h"
/////////////////////////////////////////////////////////////////////////////
// CExtObject
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::CExtObject
//
// Description:
// Default constructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CExtObject::CExtObject( void )
{
m_piData = NULL;
m_piWizardCallback = NULL;
m_bWizard = FALSE;
m_lcid = NULL;
m_hfont = NULL;
m_hicon = NULL;
m_hCluster = NULL;
m_cobj = 0;
m_podObjData = NULL;
} //*** CExtObject::CExtObject
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::~CExtObject
//
// Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CExtObject::~CExtObject( void )
{
POSITION pos = NULL;
//
// Release the data interface.
//
if ( m_piData != NULL )
{
m_piData->Release();
m_piData = NULL;
} // if: we have a data interface pointer
//
// Release the wizard callback interface.
//
if ( m_piWizardCallback != NULL )
{
m_piWizardCallback->Release();
m_piWizardCallback = NULL;
} // if: we have a wizard callback interface pointer
//
// Delete the pages.
//
pos = m_lpg.GetHeadPosition();
while ( pos != NULL )
{
delete m_lpg.GetNext(pos);
} // while: more pages in the list
//
// Delete the object.
//
delete m_podObjData;
m_podObjData = NULL;
} //*** CExtObject::~CExtObject
/////////////////////////////////////////////////////////////////////////////
// ISupportErrorInfo Implementation
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::InterfaceSupportsErrorInfo (ISupportErrorInfo)
//
// Routine Description:
// Indicates whether an interface suportes the IErrorInfo interface.
// This interface is provided by ATL.
//
// Arguments:
// riid Interface ID.
//
// Return Value:
// S_OK Interface supports IErrorInfo.
// S_FALSE Interface does not support IErrorInfo.
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CExtObject::InterfaceSupportsErrorInfo(
REFIID riid
)
{
HRESULT hr = S_FALSE;
int iiid = 0;
static const IID * rgiid[] =
{
&IID_IWEExtendPropertySheet
, &IID_IWEExtendWizard
};
for ( iiid = 0 ; iiid < sizeof( rgiid ) / sizeof( rgiid[ 0 ] ) ; iiid++ )
{
if ( ::InlineIsEqualGUID( *rgiid[ iiid ], riid ) )
{
hr = S_OK;
goto Cleanup;
} // if: found a matching IID
} // for: each interface we support
Cleanup:
return hr;
} //*** CExtObject::InterfaceSupportsErrorInfo
/////////////////////////////////////////////////////////////////////////////
// IWEExtendPropertySheet Implementation
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::CreatePropertySheetPages (IWEExtendPropertySheet)
//
// Description:
// Create property sheet pages and add them to the sheet.
//
// Arguments:
// piDataIn
// IUnkown pointer from which to obtain interfaces for obtaining data
// describing the object for which the sheet is being displayed.
//
// piCallbackIn
// Pointer to an IWCPropertySheetCallback interface for adding pages
// to the sheet.
//
// Return Value:
// S_OK Pages added successfully.
// E_INVALIDARG Invalid arguments to the function.
// E_OUTOFMEMORY Error allocating memory.
// E_FAIL Error creating a page.
// E_NOTIMPL Not implemented for this type of data.
// hr Any error codes from HrGetUIInfo() or HrSaveData().
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CExtObject::CreatePropertySheetPages(
IUnknown * piDataIn
, IWCPropertySheetCallback * piCallbackIn
)
{
HRESULT hr = S_OK;
CRuntimeClass ** pprtc = NULL;
int irtc = 0;
CBasePropertyPage * ppage = NULL;
POSITION pos = NULL;
AFX_MANAGE_STATE( AfxGetStaticModuleState() );
//
// Validate the parameters.
//
if ( (piDataIn == NULL) || (piCallbackIn == NULL) )
{
hr = E_INVALIDARG;
goto Cleanup;
} // if: all interfaces not specified
//
// Since the MFC collection classes can throw exceptions a minimal try
// catch block is needed.
//
try
{
//
// Get info about displaying UI.
//
hr = HrGetUIInfo( piDataIn );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error getting UI info
//
// Save the data.
//
hr = HrSaveData( piDataIn );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error saving data from host
//
// Delete any previous pages.
//
pos = m_lpg.GetHeadPosition();
while ( pos != NULL )
{
delete m_lpg.GetNext( pos );
} // while: more pages in the list
m_lpg.RemoveAll();
//
// Create property pages.
//
ASSERT( m_podObjData != NULL );
hr = m_podObjData->GetPropertySheetPages( &pprtc );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: failed to get the property sheet pages.
//
// Create each page.
//
for ( irtc = 0 ; pprtc[ irtc ] != NULL ; irtc++ )
{
//
// Create the page.
//
ppage = static_cast< CBasePropertyPage * >( pprtc[ irtc ]->CreateObject() );
ASSERT( ppage->IsKindOf( pprtc[ irtc ] ) );
//
// Add it to the list.
//
m_lpg.AddTail( ppage );
//
// Initialize the property page.
//
hr = ppage->HrInit( this );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error initializing the page
//
// Create the page.
//
hr = ppage->HrCreatePage();
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error creating the page
//
// Add it to the property sheet.
//
hr = piCallbackIn->AddPropertySheetPage( reinterpret_cast< LONG * >( ppage->Hpage() ) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error adding the page to the sheet
} // for: each page in the list
} // try:
catch ( CMemoryException * pme )
{
//
// An MFC memory exception occurred.
//
TRACE( _T("CExtObject::CreatePropetySheetPages() - Failed to add property page\n") );
pme->Delete();
hr = E_OUTOFMEMORY;
} // catch: MFC memory exception.
catch( ... )
{
//
// An unknown exception occurred.
//
hr = E_UNEXPECTED;
} // catch: anything.
Cleanup:
//
// Contractually obligated to release these interfaces. Cluadmin did
// an AddRef on them before we were called.
//
piDataIn->Release();
piCallbackIn->Release();
return hr;
} //*** CExtObject::CreatePropertySheetPages
/////////////////////////////////////////////////////////////////////////////
// IWEExtendWizard Implementation
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::CreateWizardPages (IWEExtendWizard)
//
// Description:
// Create property sheet pages and add them to the wizard.
//
// Arguments:
// piDataIn
// IUnkown pointer from which to obtain interfaces for obtaining data
// describing the object for which the wizard is being displayed.
//
// piCallbackIn
// Pointer to an IWCPropertySheetCallback interface for adding pages
// to the sheet.
//
// Return Value:
// S_OK Pages added successfully.
// E_INVALIDARG Invalid arguments to the function.
// E_OUTOFMEMORY Error allocating memory.
// E_FAIL Error creating a page.
// E_NOTIMPL Not implemented for this type of data.
// hr Any error codes from HrGetUIInfo() or HrSaveData().
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CExtObject::CreateWizardPages(
IUnknown * piDataIn
, IWCWizardCallback * piCallbackIn
)
{
HRESULT hr = S_OK;
CRuntimeClass ** pprtc = NULL;
int irtc = 0;
CBasePropertyPage * ppage = NULL;
POSITION pos = NULL;
AFX_MANAGE_STATE( AfxGetStaticModuleState() );
//
// Validate the parameters.
//
if ( (piDataIn == NULL) || (piCallbackIn == NULL) )
{
hr = E_INVALIDARG;
goto Cleanup;
} // if: all interfaces not specified
//
// Since the MFC collection classes can throw exceptions a minimal try
// catch block is needed.
//
try
{
//
// Get info about displaying UI.
//
hr = HrGetUIInfo( piDataIn );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error getting UI info
//
// Save the data.
//
hr = HrSaveData( piDataIn );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error saving data from host
//
// Delete any previous pages.
//
pos = m_lpg.GetHeadPosition();
while ( pos != NULL )
{
delete m_lpg.GetNext( pos );
} // while: more pages in the list
m_lpg.RemoveAll();
//
// Update our callback pointer.
//
piCallbackIn->AddRef();
m_piWizardCallback = piCallbackIn;
m_bWizard = TRUE;
//
// Create property pages.
//
ASSERT( m_podObjData != NULL );
hr = m_podObjData->GetWizardPages( &pprtc );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: failed to get the wizard pages.
//
// Create each page.
//
for ( irtc = 0 ; pprtc[ irtc ] != NULL ; irtc++ )
{
//
// Create the page.
//
ppage = static_cast< CBasePropertyPage * >( pprtc[ irtc ]->CreateObject() );
ASSERT( ppage->IsKindOf( pprtc[ irtc ] ) );
//
// Add it to the list.
//
m_lpg.AddTail( ppage );
//
// Initialize the property page.
//
hr = ppage->HrInit( this );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error initializing the page
//
// Create the page.
//
hr = ppage->HrCreatePage();
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error creating the page
//
// Add it to the property sheet.
//
hr = piCallbackIn->AddWizardPage( reinterpret_cast< LONG * >( ppage->Hpage() ) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error adding the page to the sheet
} // for: each page in the list
} // try:
catch ( CMemoryException * pme )
{
//
// An MFC memory exception occurred.
//
TRACE( _T("CExtObject::CreateWizardPages() - Failed to add wizard page\n") );
pme->Delete();
hr = E_OUTOFMEMORY;
} // catch: MFC memory exception.
catch( ... )
{
//
// An unknown exception occurred.
//
hr = E_UNEXPECTED;
} // catch: anything.
Cleanup:
//
// If we failed for any reason then we need to cleanup up the wizard
// callback interface if we saved it off.
//
if ( FAILED( hr ) )
{
if ( m_piWizardCallback == piCallbackIn )
{
m_piWizardCallback->Release();
m_piWizardCallback = NULL;
} // if: already saved interface pointer
} // if: error occurred
//
// Contractually obligated to release these interfaces. Cluadmin did
// an AddRef on them before we were called.
//
piDataIn->Release();
piCallbackIn->Release();
return hr;
} //*** CExtObject::CreateWizardPages
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::HrGetUIInfo
//
// Description:
// Get info about displaying UI.
//
// Arguments:
// piDataIn
// IUnkown pointer from which to obtain interfaces for obtaining data
// describing the object.
//
// Return Value:
// S_OK
// Data saved successfully.
//
// E_NOTIMPL
// Not implemented for this type of data.
//
// hr
// Any error codes from IUnknown::QueryInterface(),
// HrGetObjectName(), or HrGetResourceName().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT
CExtObject::HrGetUIInfo(
IUnknown * piDataIn
)
{
ASSERT( piDataIn != NULL );
HRESULT hr = S_OK;
IGetClusterUIInfo * pi = NULL;
//
// Save info about all types of objects.
//
hr = piDataIn->QueryInterface( IID_IGetClusterUIInfo, reinterpret_cast< LPVOID * >( &pi ) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error querying for interface
m_lcid = pi->GetLocale();
m_hfont = pi->GetFont();
m_hicon = pi->GetIcon();
Cleanup:
if ( pi != NULL )
{
pi->Release();
} // if:
return hr;
} //*** CExtObject::HrGetUIInfo
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::HrSaveData
//
// Routine Description:
// Save data from the object so that it can be used for the life
// of the object.
//
// Arguments:
// piDataIn
// IUnkown pointer from which to obtain interfaces for obtaining data
// describing the object.
//
// Return Value:
// S_OK
// Data saved successfully.
//
// E_NOTIMPL
// Not implemented for this type of data.
//
// hr
// Any error codes from IUnknown::QueryInterface(),
// HrGetObjectName(), or HrGetResourceName().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT
CExtObject::HrSaveData(
IUnknown * piDataIn
)
{
ASSERT( piDataIn != NULL );
HRESULT hr = S_OK;
IGetClusterDataInfo * pi = NULL;
//
// Save the new piData interface.
//
if ( piDataIn != m_piData )
{
if ( m_piData != NULL )
{
m_piData->Release();
} // if: interface queried for previously
piDataIn->AddRef();
m_piData = piDataIn;
} // if: different data interface pointer
//
// Save info about all types of objects.
//
hr = piDataIn->QueryInterface( IID_IGetClusterDataInfo, reinterpret_cast< LPVOID * >( &pi ) );
if ( FAILED( hr ) )
{
goto Cleanup;
} // if: error querying for interface
m_hCluster = pi->GetClusterHandle();
m_cobj = pi->GetObjectCount();
if ( m_cobj != 1 ) // We only have support for one selected object.
{
hr = E_NOTIMPL;
goto Cleanup;
} // if: too many objects for us to handle
//
// Save info about this object.
//
hr = HrGetObjectInfo();
if ( FAILED( hr ) )
{
goto Cleanup;
} // if:
Cleanup:
if ( pi != NULL )
{
pi->Release();
} // if:
return hr;
} //*** CExtObject::HrSaveData
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::HrGetObjectInfo
//
// Description:
// Get information about the object.
//
// Arguments:
// None.
//
// Return Value:
// S_OK
// Data saved successfully.
//
// E_OUTOFMEMORY
// Error allocating memory.
//
// E_NOTIMPL
// Not implemented for this type of data.
//
// hr
// Any error codes from IUnknown::QueryInterface(),
// HrGetObjectName(), or HrGetResourceTypeName().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT
CExtObject::HrGetObjectInfo( void )
{
HRESULT hr = S_OK;
//
// Delete the old object and create a new one.
//
delete m_podObjData;
m_podObjData = NULL;
hr = CObjData::S_HrCreateObject( m_piData, &m_podObjData );
return hr;
} //*** CExtObject::HrGetObjectInfo