|
|
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997-2002 Microsoft Corporation
//
// 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.
//
// Maintained By:
// David Potter (DavidP) Mmmm DD, 1997
//
// Revision History:
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DebugEx.h"
#include "ExtObj.h"
#include "ResProp.h"
/////////////////////////////////////////////////////////////////////////////
// Global Variables
/////////////////////////////////////////////////////////////////////////////
static CRuntimeClass * g_rgprtcResPSPages[] = { RUNTIME_CLASS(CDebugParamsPage), NULL }; static CRuntimeClass ** g_rgpprtcResPSPages[] = { g_rgprtcResPSPages, }; static CRuntimeClass * g_rgprtcResTypePSPages[] = { RUNTIME_CLASS(CDebugParamsPage), NULL }; static CRuntimeClass ** g_rgpprtcResTypePSPages[] = { g_rgprtcResTypePSPages, };
/////////////////////////////////////////////////////////////////////////////
// CExtObject
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::CExtObject
//
// Routine Description:
// Default constructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CExtObject::CExtObject(void) { m_piData = NULL; m_bWizard = FALSE; m_istrResTypeName = 0;
m_lcid = NULL; m_hfont = NULL; m_hicon = NULL; m_hcluster = NULL; m_cobj = 0; m_podObjData = NULL;
} //*** CExtObject::CExtObject()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::~CExtObject
//
// Routine Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CExtObject::~CExtObject(void) { // Release the data interface.
if (PiData() != NULL) { PiData()->Release(); m_piData = NULL; } // if: we have a data interface pointer
// Delete the pages.
{ POSITION pos;
pos = Lpg().GetHeadPosition(); while (pos != NULL) delete Lpg().GetNext(pos); } // Delete the pages
delete m_podObjData;
} //*** 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) { static const IID * rgiid[] = { &IID_IWEExtendPropertySheet, }; int iiid;
for (iiid = 0 ; iiid < sizeof(rgiid) / sizeof(rgiid[0]) ; iiid++) { if (InlineIsEqualGUID(*rgiid[iiid], riid)) return S_OK; } return S_FALSE;
} //*** CExtObject::InterfaceSupportsErrorInfo()
/////////////////////////////////////////////////////////////////////////////
// IWEExtendPropertySheet Implementation
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::CreatePropertySheetPages (IWEExtendPropertySheet)
//
// Routine Description:
// Create property sheet pages and add them to the sheet.
//
// Arguments:
// piData IUnkown pointer from which to obtain interfaces
// for obtaining data describing the object for
// which the sheet is being displayed.
// piCallback Pointer to an IWCPropertySheetCallback interface
// for adding pages to the sheet.
//
// Return Value:
// NOERROR 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.
// Any error codes from IDataObject::GetData() (through HrSaveData()).
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CExtObject::CreatePropertySheetPages( IN IUnknown * piData, IN IWCPropertySheetCallback * piCallback ) { HRESULT hr = NOERROR; HPROPSHEETPAGE hpage = NULL; CException exc(FALSE /*bAutoDelete*/); CRuntimeClass ** pprtc = NULL; int irtc; CBasePropertyPage * ppage;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Validate the parameters.
if ((piData == NULL) || (piCallback == NULL)) return E_INVALIDARG;
try { // Get info about displaying UI.
hr = HrGetUIInfo(piData); if (hr != NOERROR) throw &exc;
// Save the data.
hr = HrSaveData(piData); if (hr != NOERROR) throw &exc;
// Delete any previous pages.
{ POSITION pos;
pos = Lpg().GetHeadPosition(); while (pos != NULL) delete Lpg().GetNext(pos); Lpg().RemoveAll(); } // Delete any previous pages
// Create property pages.
ASSERT(PodObjData() != NULL); switch (PodObjData()->m_cot) { case CLUADMEX_OT_RESOURCE: pprtc = g_rgpprtcResPSPages[0]; break; case CLUADMEX_OT_RESOURCETYPE: pprtc = g_rgpprtcResTypePSPages[0]; break; default: hr = E_NOTIMPL; throw &exc; break; } // switch: object type
// Create each page.
for (irtc = 0 ; pprtc[irtc] != NULL ; irtc++) { // Create the page.
ppage = (CBasePropertyPage *) pprtc[irtc]->CreateObject(); ASSERT(ppage->IsKindOf(pprtc[irtc]));
// Add it to the list.
Lpg().AddTail(ppage);
// Initialize the property page.
if (!ppage->BInit(this)) throw &exc;
// Create the page.
hpage = ::CreatePropertySheetPage(&ppage->m_psp); if (hpage == NULL) throw &exc;
// Save the hpage in the page itself.
ppage->SetHpage(hpage);
// Add it to the property sheet.
hr = piCallback->AddPropertySheetPage((LONG *) hpage); if (hr != NOERROR) throw &exc; } // for: each page in the list
} // try
catch (CMemoryException * pme) { TRACE(_T("CExtObject::CreatePropetySheetPages() - Failed to add property page\n")); pme->Delete(); hr = E_OUTOFMEMORY; } // catch: anything
catch (CException * pe) { TRACE(_T("CExtObject::CreatePropetySheetPages() - Failed to add property page\n")); pe->Delete(); if (hr == NOERROR) hr = E_FAIL; } // catch: anything
if (hr != NOERROR) { if (hpage != NULL) ::DestroyPropertySheetPage(hpage); piData->Release(); m_piData = NULL; } // if: error occurred
piCallback->Release(); return hr;
} //*** CExtObject::CreatePropertySheetPages()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::HrGetUIInfo
//
// Routine Description:
// Get info about displaying UI.
//
// Arguments:
// piData IUnkown pointer from which to obtain interfaces
// for obtaining data describing the object.
//
// Return Value:
// NOERROR Data saved successfully.
// E_NOTIMPL Not implemented for this type of data.
// Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
// or HrGetResourceName().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CExtObject::HrGetUIInfo(IUnknown * piData) { HRESULT hr = NOERROR;
ASSERT(piData != NULL);
// Save info about all types of objects.
{ IGetClusterUIInfo * pi;
hr = piData->QueryInterface(IID_IGetClusterUIInfo, (LPVOID *) &pi); if (hr != NOERROR) return hr;
m_lcid = pi->GetLocale(); m_hfont = pi->GetFont(); m_hicon = pi->GetIcon();
pi->Release(); } // Save info about all types of objects
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:
// piData IUnkown pointer from which to obtain interfaces
// for obtaining data describing the object.
//
// Return Value:
// NOERROR Data saved successfully.
// E_NOTIMPL Not implemented for this type of data.
// Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
// or HrGetResourceName().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CExtObject::HrSaveData(IUnknown * piData) { HRESULT hr = NOERROR;
ASSERT(piData != NULL);
if (piData != m_piData) { if (m_piData != NULL) m_piData->Release(); m_piData = piData; } // if: different data interface pointer
// Save info about all types of objects.
{ IGetClusterDataInfo * pi;
hr = piData->QueryInterface(IID_IGetClusterDataInfo, (LPVOID *) &pi); if (hr != NOERROR) return hr;
m_hcluster = pi->GetClusterHandle(); m_cobj = pi->GetObjectCount(); if (Cobj() != 1) // Only have support for one selected object.
hr = E_NOTIMPL;
pi->Release(); if (hr != NOERROR) return hr; } // Save info about all types of objects
// Save info about this object.
hr = HrGetObjectInfo(); if (hr != NOERROR) return hr;
return hr;
} //*** CExtObject::HrSaveData()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::HrGetObjectInfo
//
// Routine Description:
// Get information about the object.
//
// Arguments:
// None.
//
// Return Value:
// NOERROR Data saved successfully.
// E_OUTOFMEMORY Error allocating memory.
// E_NOTIMPL Not implemented for this type of data.
// Any error codes from IUnknown::QueryInterface(), HrGetObjectName(),
// or HrGetResourceTypeName().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CExtObject::HrGetObjectInfo(void) { HRESULT hr = NOERROR; IGetClusterObjectInfo * piGcoi; CLUADMEX_OBJECT_TYPE cot; CException exc(FALSE /*bAutoDelete*/);
ASSERT(PiData() != NULL);
// Get object info.
{ // Get an IGetClusterObjectInfo interface pointer.
hr = PiData()->QueryInterface(IID_IGetClusterObjectInfo, (LPVOID *) &piGcoi); if (hr != NOERROR) return hr;
// Read the object data.
try { // Delete the previous object data.
delete m_podObjData; m_podObjData = NULL;
// Get the type of the object.
cot = piGcoi->GetObjectType(0); switch (cot) { case CLUADMEX_OT_RESOURCE: { IGetClusterResourceInfo * pi;
m_podObjData = new CResData;
// Get an IGetClusterResourceInfo interface pointer.
hr = PiData()->QueryInterface(IID_IGetClusterResourceInfo, (LPVOID *) &pi); if (hr != NOERROR) throw &exc;
PrdResDataRW()->m_hresource = pi->GetResourceHandle(0); hr = HrGetResourceTypeName(pi); pi->Release(); if (hr != NOERROR) throw &exc; } // if: object is a node
break; case CLUADMEX_OT_RESOURCETYPE: m_podObjData = new CObjData; break; default: hr = E_NOTIMPL; throw &exc; } // switch: object type
PodObjDataRW()->m_cot = cot; hr = HrGetObjectName(piGcoi); } // try
catch (CException * pe) { pe->Delete(); } // catch: CException
piGcoi->Release(); if (hr != NOERROR) return hr; } // Get object info
return hr;
} //*** CExtObject::HrGetObjectInfo()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::HrGetObjectName
//
// Routine Description:
// Get the name of the object.
//
// Arguments:
// piData IGetClusterObjectInfo interface pointer for getting
// the object name.
//
// Return Value:
// NOERROR Data saved successfully.
// E_OUTOFMEMORY Error allocating memory.
// E_NOTIMPL Not implemented for this type of data.
// Any error codes from IGetClusterObjectInfo::GetObjectInfo().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CExtObject::HrGetObjectName( IN OUT IGetClusterObjectInfo * pi ) { HRESULT hr = NOERROR; WCHAR * pwszName = NULL; LONG cchName; BSTR bstr = NULL;
ASSERT(pi != NULL);
hr = pi->GetObjectName(0, NULL, &cchName); if (hr != NOERROR) return hr;
bstr = SysAllocStringLen( NULL, cchName ); if ( bstr != NULL ) { try { hr = pi->GetObjectName(0, bstr, &cchName); if (hr == NOERROR) { pwszName = new WCHAR[cchName]; hr = StringCchCopyNW( pwszName, cchName, bstr, SysStringLen( bstr ) ); if ( FAILED( hr ) ) { goto Cleanup; } }
PodObjDataRW()->m_strName = pwszName; } // try
catch (CMemoryException * pme) { pme->Delete(); hr = E_OUTOFMEMORY; } // catch: CMemoryException
} // if: ( bstr != NULL )
else { hr = E_OUTOFMEMORY; }
Cleanup:
delete [] pwszName; SysFreeString( bstr ); return hr;
} //*** CExtObject::HrGetObjectName()
/////////////////////////////////////////////////////////////////////////////
//++
//
// CExtObject::HrGetResourceTypeName
//
// Routine Description:
// Get the name of the resource's type.
//
// Arguments:
// piData IGetClusterResourceInfo interface pointer for getting
// the resource type name.
//
// Return Value:
// NOERROR Data saved successfully.
// E_OUTOFMEMORY Error allocating memory.
// E_NOTIMPL Not implemented for this type of data.
// Any error codes from IGetClusterResourceInfo::GetResourceTypeName().
//
//--
/////////////////////////////////////////////////////////////////////////////
HRESULT CExtObject::HrGetResourceTypeName( IN OUT IGetClusterResourceInfo * pi ) { HRESULT hr = NOERROR; WCHAR * pwszName = NULL; LONG cchName; BSTR bstr = NULL;
ASSERT(pi != NULL);
hr = pi->GetResourceTypeName(0, NULL, &cchName); if (hr != NOERROR) return hr;
bstr = SysAllocStringLen( NULL, cchName ); if ( bstr != NULL ) { try { hr = pi->GetResourceTypeName(0, bstr, &cchName); if (hr == NOERROR) { pwszName = new WCHAR[cchName]; hr = StringCchCopyNW( pwszName, cchName, bstr, SysStringLen( bstr ) ); if ( FAILED( hr ) ); { goto Cleanup; } }
PrdResDataRW()->m_strResTypeName = pwszName; } // try
catch (CMemoryException * pme) { pme->Delete(); hr = E_OUTOFMEMORY; } // catch: CMemoryException
} // if: ( bstr != NULL )
else { hr = E_OUTOFMEMORY; }
Cleanup:
delete [] pwszName; SysFreeString( bstr ); return hr;
} //*** CExtObject::HrGetResourceTypeName()
|