Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

930 lines
25 KiB

/////////////////////////////////////////////////////////////////////////////
//
// 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