|
|
/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1996-2002 Microsoft Corporation
//
// Module Name:
// DataObj.cpp
//
// Abstract:
// Implementation of the CDataObject class, which is the IDataObject
// class used to transfer data between CluAdmin and the extension DLL
// handlers.
//
// Author:
// David Potter (davidp) June 4, 1996
//
// Revision History:
//
// Notes:
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <CluAdmEx.h>
#include "DataObj.h"
#include "ClusItem.h"
#include "ClusItem.inl"
#include "Res.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// Global Variables
/////////////////////////////////////////////////////////////////////////////
// Object type map.
static IDS g_rgidsObjectType[] = { NULL, IDS_ITEMTYPE_CLUSTER, IDS_ITEMTYPE_NODE, IDS_ITEMTYPE_GROUP, IDS_ITEMTYPE_RESOURCE, IDS_ITEMTYPE_RESTYPE, IDS_ITEMTYPE_NETWORK, IDS_ITEMTYPE_NETIFACE }; #define RGIDS_OBJECT_TYPE_SIZE sizeof(g_rgidsObjectType) / sizeof(IDS)
/////////////////////////////////////////////////////////////////////////////
// CDataObject
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CDataObject, CObject)
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::CDataObject
//
// Routine Description:
// Default constructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CDataObject::CDataObject(void) { m_pci = NULL; m_lcid = NULL; m_hfont = NULL; m_hicon = NULL;
m_pfGetResNetName = NULL;
m_pModuleState = AfxGetModuleState(); ASSERT(m_pModuleState != NULL);
} //*** CDataObject::CDataObject
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::~CDataObject
//
// Routine Description:
// Destructor.
//
// Arguments:
// None.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
CDataObject::~CDataObject(void) { m_pModuleState = NULL;
} //*** CDataObject::~CDataObject
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::Init
//
// Routine Description:
// Second-phase constructor.
//
// Arguments:
// pci [IN OUT] Cluster item for which a property sheet is being displayed.
// lcid [IN] Locale ID of resources to be loaded by extension.
// hfont [IN] Font to use for property page text.
// hicon [IN] Icon for upper left icon control.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CDataObject::Init( IN OUT CClusterItem * pci, IN LCID lcid, IN HFONT hfont, IN HICON hicon ) { ASSERT_VALID(pci);
// Save parameters.
m_pci = pci; m_lcid = lcid; m_hfont = hfont; m_hicon = hicon;
} //*** CDataObject::Init
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::InterfaceSupportsErrorInfo [ISupportsErrorInfo]
//
// Routine Description:
// Determines whether the interface supports error info (???).
//
// Arguments:
// riid [IN] Reference to the interface ID.
//
// Return Value:
// S_OK Interface supports error info.
// S_FALSE Interface does not support error info.
//
// Exceptions Thrown:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CDataObject::InterfaceSupportsErrorInfo(REFIID riid) { static const IID * rgiid[] = { &IID_IGetClusterDataInfo, &IID_IGetClusterObjectInfo, &IID_IGetClusterNodeInfo, &IID_IGetClusterGroupInfo, &IID_IGetClusterResourceInfo, }; int iiid; HRESULT hr = S_FALSE;
for (iiid = 0 ; iiid < sizeof(rgiid) / sizeof(rgiid[0]) ; iiid++) { if (InlineIsEqualGUID(*rgiid[iiid], riid)) { hr = S_OK; } }
return hr;
} //*** CDataObject::InterfaceSupportsErrorInfo
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetLocale [IGetClusterUIInfo]
//
// Routine Description:
// Get the locale ID for the extension to use.
//
// Arguments:
// None.
//
// Return Value:
// LCID
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(LCID) CDataObject::GetLocale(void) { return Lcid();
} //*** CDataObject::GetLocale
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetFont [IGetClusterUIInfo]
//
// Routine Description:
// Get the font to use for property pages and wizard pages.
//
// Arguments:
// None.
//
// Return Value:
// HFONT
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(HFONT) CDataObject::GetFont(void) { return Hfont();
} //*** CDataObject::GetFont
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetIcon [IGetClusterUIInfo]
//
// Routine Description:
// Get the icon to use in the upper left corner of property pages
// and wizard pages.
//
// Arguments:
// None.
//
// Return Value:
// HICON
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(HICON) CDataObject::GetIcon(void) { return Hicon();
} //*** CDataObject::GetIcon
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetClusterName [IGetClusterDataInfo]
//
// Routine Description:
// Get the name of the cluster in which this object exists.
//
// Arguments:
// lpszName [OUT] String in which to return the name.
// pcchName [IN OUT] Maximum length of lpszName buffer on
// input. Set to the total number of characters
// upon return, including terminating null character.
// If no lpszName buffer is not specified, the
// status returned will be NOERROR. If an lpszName
// buffer is specified but it is too small, the
// number of characters will be returned in pcchName
// and an ERROR_MORE_DATA status will be returned.
//
// Return Value:
// NOERROR Data (or size) copied successfully.
// E_INVALIDARG Invalid arguments specified.
// ERROR_MORE_DATA Buffer is too small.
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CDataObject::GetClusterName( OUT BSTR lpszName, IN OUT LONG * pcchName ) { LONG cchName = 0; HRESULT hr = NOERROR;
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci()); ASSERT_VALID(Pci()->Pdoc());
// Validate parameters.
if (pcchName == NULL) { hr = E_INVALIDARG; goto Cleanup; }
try { // Save the length to copy.
cchName = *pcchName; *pcchName = Pci()->Pdoc()->StrName().GetLength() + 1; } // try
catch (...) { hr = E_INVALIDARG; goto Cleanup; } // catch: anything
// If only the length is being requested, return it now.
if (lpszName == NULL) { hr = NOERROR; goto Cleanup; }
// If a buffer is specified and it is too small, return an error.
if (cchName < *pcchName) { hr = ERROR_MORE_DATA; goto Cleanup; }
// Copy the data.
hr = StringCchCopyNW( lpszName, cchName, Pci()->Pdoc()->StrName(), Pci()->Pdoc()->StrName().GetLength() ); if ( FAILED( hr ) ) { goto Cleanup; }
Cleanup:
return hr;
} //*** CDataObject::GetClusterName
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetClusterHandle [IGetClusterDataInfo]
//
// Routine Description:
// Get the cluster handle for these objects.
//
// Arguments:
// None.
//
// Return Value:
// HCLUSTER
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(HCLUSTER) CDataObject::GetClusterHandle(void) { AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci()); return Pci()->Hcluster();
} //*** CDataObject::GetClusterHandle
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetObjectCount [IGetClusterDataInfo]
//
// Routine Description:
// Get the number of selected objects.
//
// Arguments:
// None.
//
// Return Value:
// cObj
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(LONG) CDataObject::GetObjectCount(void) { // We only support one selected object at a time for now.
return 1;
} //*** CDataObject::GetObjectCount
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetObjectName [IGetClusterObjectInfo]
//
// Routine Description:
// Get the name of the specified object.
//
// Arguments:
// lObjIndex [IN] Zero-based index of the object.
// lpszName [OUT] String in which to return the name.
// pcchName [IN OUT] Maximum length of lpszName buffer on
// input. Set to the total number of characters
// upon return, including terminating null character.
// If no lpszName buffer is not specified, the
// status returned will be NOERROR. If an lpszName
// buffer is specified but it is too small, the
// number of characters will be returned in pcchName
// and an ERROR_MORE_DATA status will be returned.
//
// Return Value:
// NOERROR Data (or size) copied successfully.
// E_INVALIDARG Invalid arguments specified.
// ERROR_MORE_DATA Buffer is too small.
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CDataObject::GetObjectName( IN LONG lObjIndex, OUT BSTR lpszName, IN OUT LONG * pcchName ) { LONG cchName = 0; HRESULT hr = NOERROR;
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci());
// Validate parameters.
// We only support one selected object at a time for now.
if ((lObjIndex != 0) || (pcchName == NULL)) { hr = E_INVALIDARG; goto Cleanup; }
// Save the length to copy.
try { cchName = *pcchName; *pcchName = Pci()->StrName().GetLength() + 1; } // try
catch (...) { hr = E_INVALIDARG; goto Cleanup; } // catch: anything
// If only the length is being requested, return it now.
if (lpszName == NULL) { hr = NOERROR; goto Cleanup; }
// If a buffer is specified and it is too small, return an error.
if (cchName < *pcchName) { hr = ERROR_MORE_DATA; goto Cleanup; }
// Copy the data.
hr = StringCchCopyNW( lpszName, cchName, Pci()->StrName(), Pci()->StrName().GetLength() ); if ( FAILED( hr ) ) { goto Cleanup; }
Cleanup:
return hr;
} //*** CDataObject::GetObjectName
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetObjectType [IGetClusterObjectInfo]
//
// Routine Description:
// Get the cluster database registry key for the specified object.
//
// Arguments:
// lObjIndex [IN] Zero-based index of the object.
//
// Return Value:
// -1 Invalid argument. Call GetLastError for more information.
// CLUADMEX_OBJECT_TYPE
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(CLUADMEX_OBJECT_TYPE) CDataObject::GetObjectType( IN LONG lObjIndex ) { int iids; CLUADMEX_OBJECT_TYPE cot = CLUADMEX_OT_NONE;
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci());
// Validate parameters.
// We only support one selected object at a time for now.
if (lObjIndex != 0) { SetLastError((DWORD) E_INVALIDARG); cot = (CLUADMEX_OBJECT_TYPE) -1; goto Cleanup; } // if: invalid argument
// Get the object type.
for (iids = 0 ; iids < RGIDS_OBJECT_TYPE_SIZE ; iids++) { if (g_rgidsObjectType[iids] == Pci()->IdsType()) { cot = (CLUADMEX_OBJECT_TYPE) iids; break; } } // for: each entry in the table
Cleanup:
return cot;
} //*** CDataObject::GetObjectType
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetNodeHandle [IGetClusterNodeInfo]
//
// Routine Description:
// Get the handle for the specified node.
//
// Arguments:
// lObjIndex [IN] Zero-based index of the object.
//
// Return Value:
// HNODE
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(HNODE) CDataObject::GetNodeHandle( IN LONG lObjIndex ) { CClusterNode * pciNode = (CClusterNode *) Pci(); HNODE hnode = NULL;
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci());
// Validate parameters.
// We only support one selected object at a time for now.
if ( (lObjIndex != 0) || (Pci()->IdsType() != IDS_ITEMTYPE_NODE)) { SetLastError((DWORD) E_INVALIDARG); goto Cleanup; } // if: invalid argument
ASSERT_KINDOF(CClusterNode, pciNode);
hnode = pciNode->Hnode();
Cleanup:
return hnode;
} //*** CDataObject::GetNodeHandle
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetGroupHandle [IGetClusterGroupInfo]
//
// Routine Description:
// Get the handle for the specified group.
//
// Arguments:
// lObjIndex [IN] Zero-based index of the object.
//
// Return Value:
// HGROUP
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(HGROUP) CDataObject::GetGroupHandle( IN LONG lObjIndex ) { CGroup * pciGroup = (CGroup *) Pci(); HGROUP hgroup = NULL;
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci());
// Validate parameters.
// We only support one selected object at a time for now.
if ( (lObjIndex != 0) || (Pci()->IdsType() != IDS_ITEMTYPE_GROUP)) { SetLastError((DWORD) E_INVALIDARG); goto Cleanup; } // if: invalid argument
ASSERT_KINDOF(CGroup, pciGroup);
hgroup = pciGroup->Hgroup();
Cleanup:
return hgroup;
} //*** CDataObject::GetGroupHandle
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetResourceHandle [IGetClusterResourceInfo]
//
// Routine Description:
// Get the handle for the specified resource.
//
// Arguments:
// lObjIndex [IN] Zero-based index of the object.
//
// Return Value:
// HRESOURCE
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(HRESOURCE) CDataObject::GetResourceHandle( IN LONG lObjIndex ) { CResource * pciRes = (CResource *) Pci(); HRESOURCE hres = NULL;
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci());
// Validate parameters.
// We only support one selected object at a time for now.
if ( (lObjIndex != 0) || (Pci()->IdsType() != IDS_ITEMTYPE_RESOURCE)) { SetLastError((DWORD) E_INVALIDARG); goto Cleanup; } // if: invalid argument
ASSERT_KINDOF(CResource, pciRes);
hres = pciRes->Hresource();
Cleanup:
return hres;
} //*** CDataObject::GetResourceHandle
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetResourceTypeName [IGetClusterResourceInfo]
//
// Routine Description:
// Returns the name of the resource type of the specified resource.
//
// Arguments:
// lObjIndex [IN] Zero-based index of the object.
// lpszResTypeName [OUT] String in which to return the resource type name.
// pcchResTypeName [IN OUT] Maximum length of lpszResTypeName buffer on
// input. Set to the total number of characters
// upon return, including terminating null character.
// If no lpszResTypeName buffer is not specified, the
// status returned will be NOERROR. If an lpszResTypeName
// buffer is specified but it is too small, the
// number of characters will be returned in pcchResTypeName
// and an ERROR_MORE_DATA status will be returned.
//
// Return Value:
// NOERROR Data (or size) copied successfully.
// E_INVALIDARG Invalid arguments specified.
// ERROR_MORE_DATA Buffer is too small.
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CDataObject::GetResourceTypeName( IN LONG lObjIndex, OUT BSTR lpszResTypeName, IN OUT LONG * pcchResTypeName ) { LONG cchResTypeName = 0; CResource * pciRes = (CResource *) Pci(); CString const * pstrResourceTypeName; HRESULT hr = NOERROR;
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci());
// Validate parameters.
// We only support one selected object at a time for now.
if ((lObjIndex != 0) || (pcchResTypeName == NULL) || (Pci()->IdsType() != IDS_ITEMTYPE_RESOURCE)) { hr = E_INVALIDARG; goto Cleanup; } // if: invalid argument
ASSERT_KINDOF(CResource, pciRes);
// Get a pointer to the name to copy.
if (pciRes->PciResourceType() != NULL) { ASSERT_VALID(pciRes->PciResourceType()); pstrResourceTypeName = &pciRes->PciResourceType()->StrName(); } // if: valid resource type pointer
else pstrResourceTypeName = &pciRes->StrResourceType();
// Save the length to copy.
try { cchResTypeName = *pcchResTypeName; *pcchResTypeName = pstrResourceTypeName->GetLength() + 1; } // try
catch (...) { hr = E_INVALIDARG; goto Cleanup; } // catch: anything
// If only the length is being requested, return it now.
if (lpszResTypeName == NULL) { hr = NOERROR; goto Cleanup; }
// If a buffer is specified and it is too small, return an error.
if (cchResTypeName < *pcchResTypeName) { hr = ERROR_MORE_DATA; goto Cleanup; }
// Copy the data.
hr = StringCchCopyNW(lpszResTypeName, cchResTypeName, *pstrResourceTypeName, pstrResourceTypeName->GetLength() ); if ( FAILED( hr ) ) { goto Cleanup; }
Cleanup:
return hr;
} //*** CDataObject::GetResourceTypeName
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetResourceNetworkName [IGetClusterResourceInfo]
//
// Routine Description:
// Returns the name of the network name of the first Network Name
// resource on which the specified resource depends.
//
// Arguments:
// lObjIndex [IN] Zero-based index of the object.
// lpszNetName [OUT] String in which to return the network name.
// pcchNetName [IN OUT] Points to a variable that specifies the
// maximum size, in characters, of the buffer. This
// value should be large enough to contain
// MAX_COMPUTERNAME_LENGTH + 1 characters. Upon
// return it contains the actual number of characters
// copied.
//
// Return Value:
// TRUE Data (or size) copied successfully.
// FALSE Error getting information. GetLastError() returns:
// E_INVALIDARG Invalid arguments specified.
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(BOOL) CDataObject::GetResourceNetworkName( IN LONG lObjIndex, OUT BSTR lpszNetName, IN OUT ULONG * pcchNetName ) { BOOL bSuccess = FALSE; CResource * pciRes = (CResource *) Pci();
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci());
try { // Validate parameters.
// We only support one selected object at a time for now.
if ((lObjIndex != 0) || (pcchNetName == NULL) || (*pcchNetName < MAX_COMPUTERNAME_LENGTH) || (Pci()->IdsType() != IDS_ITEMTYPE_RESOURCE)) { SetLastError((DWORD) E_INVALIDARG); goto Cleanup; } // if: invalid argument
ASSERT_KINDOF(CResource, pciRes);
// If there is a function for getting this information, call it.
// Otherwise, handle it ourselves.
if (PfGetResNetName() != NULL) { bSuccess = (*PfGetResNetName())(lpszNetName, pcchNetName, m_pvGetResNetNameContext); } else { bSuccess = pciRes->BGetNetworkName(lpszNetName, pcchNetName); } } // try
catch (...) { bSuccess = FALSE; SetLastError((DWORD) E_INVALIDARG); } // catch: anything
Cleanup:
return bSuccess;
} //*** CDataObject::GetResourceNetworkName
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetNetworkHandle [IGetClusterNetworkInfo]
//
// Routine Description:
// Get the handle for the specified network.
//
// Arguments:
// lObjIndex [IN] Zero-based index of the object.
//
// Return Value:
// HNETWORK
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(HNETWORK) CDataObject::GetNetworkHandle( IN LONG lObjIndex ) { CNetwork * pciNetwork = (CNetwork *) Pci(); HNETWORK hnet = NULL;
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci());
// Validate parameters.
// We only support one selected object at a time for now.
if ( (lObjIndex != 0) || (Pci()->IdsType() != IDS_ITEMTYPE_NETWORK)) { SetLastError((DWORD) E_INVALIDARG); goto Cleanup; } // if: invalid argument
ASSERT_KINDOF(CNetwork, pciNetwork);
hnet = pciNetwork->Hnetwork();
Cleanup:
return hnet;
} //*** CDataObject::GetNetworkHandle
/////////////////////////////////////////////////////////////////////////////
//++
//
// CDataObject::GetNetInterfaceHandle [IGetClusterNetInterfaceInfo]
//
// Routine Description:
// Get the handle for the specified network interface.
//
// Arguments:
// lObjIndex [IN] Zero-based index of the object.
//
// Return Value:
// HNETINTERFACE
//
//--
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(HNETINTERFACE) CDataObject::GetNetInterfaceHandle( IN LONG lObjIndex ) { CNetInterface * pciNetIFace = (CNetInterface *) Pci(); HNETINTERFACE hnetiface = NULL;
AFX_MANAGE_STATE(m_pModuleState); ASSERT_VALID(Pci());
// Validate parameters.
// We only support one selected object at a time for now.
if ( (lObjIndex != 0) || (Pci()->IdsType() != IDS_ITEMTYPE_NETIFACE)) { SetLastError((DWORD) E_INVALIDARG); goto Cleanup; } // if: invalid argument
ASSERT_KINDOF(CNetwork, pciNetIFace);
hnetiface = pciNetIFace->Hnetiface();
Cleanup:
return hnetiface;
} //*** CDataObject::GetNetInterfaceHandle
|