windows-nt/Source/XPSP1/NT/inetsrv/iis/ui/admin/mmc/dataobj.cpp
2020-09-26 16:20:57 +08:00

694 lines
13 KiB
C++

/*++
Copyright (c) 1994-1998 Microsoft Corporation
Module Name :
dataobj.cpp
Abstract:
Snapin data object
Author:
Ronald Meijer (ronaldm)
Project:
Internet Services Manager
Revision History:
--*/
//
// Include Files
//
#include "stdafx.h"
#include "inetmgr.h"
#include "cinetmgr.h"
#include "dataobj.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// Snap-in NodeType in both GUID format and string format
// Note - Typically there is a node type for each different object, sample
// only uses one node type.
//
unsigned int CDataObject::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
unsigned int CDataObject::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
unsigned int CDataObject::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
unsigned int CDataObject::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
/*
//
// Multi-select
//
unsigned int CDataObject::m_cfpMultiSelDataObj = RegisterClipboardFormat(CCF_MMC_MULTISELECT_DATAOBJECT);
unsigned int CDataObject::m_cfMultiObjTypes = RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT);
unsigned int CDataObject::m_cfMultiSelDataObjs = RegisterClipboardFormat(CCF_MULTI_SELECT_SNAPINS);
*/
//
// Internal
//
unsigned int CDataObject::m_cfInternal = RegisterClipboardFormat(ISM_SNAPIN_INTERNAL);
//
// Published Information
//
unsigned int CDataObject::m_cfISMMachineName = RegisterClipboardFormat(ISM_SNAPIN_MACHINE_NAME);
unsigned int CDataObject::m_cfMyComputMachineName = RegisterClipboardFormat(MYCOMPUT_MACHINE_NAME);
unsigned int CDataObject::m_cfISMService = RegisterClipboardFormat(ISM_SNAPIN_SERVICE);
unsigned int CDataObject::m_cfISMInstance = RegisterClipboardFormat(ISM_SNAPIN_INSTANCE);
unsigned int CDataObject::m_cfISMParentPath = RegisterClipboardFormat(ISM_SNAPIN_PARENT_PATH);
unsigned int CDataObject::m_cfISMNode = RegisterClipboardFormat(ISM_SNAPIN_NODE);
unsigned int CDataObject::m_cfISMMetaPath = RegisterClipboardFormat(ISM_SNAPIN_META_PATH);
STDMETHODIMP
CDataObject::GetDataHere(
IN LPFORMATETC lpFormatetc,
IN LPSTGMEDIUM lpMedium
)
/*++
Routine Description:
Write requested information type to the given medium
Arguments:
LPFORMATETC lpFormatetc : Format etc
LPSTGMEDIUM lpMedium : Medium to write to.
Return Value:
HRESULT
--*/
{
HRESULT hr = DV_E_CLIPFORMAT;
//
// Based on the CLIPFORMAT write data to the stream
//
const CLIPFORMAT cf = lpFormatetc->cfFormat;
if (cf == m_cfNodeType)
{
hr = CreateNodeTypeData(lpMedium);
}
else if (cf == m_cfNodeTypeString)
{
hr = CreateNodeTypeStringData(lpMedium);
}
else if (cf == m_cfCoClass)
{
hr = CreateCoClassID(lpMedium);
}
else if (cf == m_cfDisplayName)
{
hr = CreateDisplayName(lpMedium);
}
else if (cf == m_cfInternal)
{
hr = CreateInternal(lpMedium);
}
else if (cf == m_cfISMMachineName)
{
hr = CreateMachineName(lpMedium);
}
/*
multi-select pulled
else if (cf == m_cfpMultiSelDataObj)
{
TRACEEOLID("CCF_MMC_MULTISELECT_DATAOBJECT");
}
else if (cf == m_cfMultiObjTypes)
{
TRACEEOLID("CCF_OBJECT_TYPES_IN_MULTI_SELECT");
}
else if (cf == m_cfMultiSelDataObjs)
{
TRACEEOLID("CCF_MULTI_SELECT_SNAPINS");
}
*/
else if (cf == m_cfISMService)
{
hr = CreateMetaField(lpMedium, META_SERVICE);
}
else if (cf == m_cfISMInstance)
{
hr = CreateMetaField(lpMedium, META_INSTANCE);
}
else if (cf == m_cfISMParentPath)
{
hr = CreateMetaField(lpMedium, META_PARENT);
}
else if (cf == m_cfISMNode)
{
hr = CreateMetaField(lpMedium, META_NODE);
}
else if (cf == m_cfISMMetaPath)
{
hr = CreateMetaField(lpMedium, META_WHOLE);
}
else
{
TRACEEOLID("Unrecognized format");
hr = DV_E_CLIPFORMAT;
}
return hr;
}
STDMETHODIMP
CDataObject::GetData(
IN LPFORMATETC lpFormatetcIn,
IN LPSTGMEDIUM lpMedium
)
/*++
Routine Description:
Get data from the data object
Arguments:
LPFORMATETC lpFormatetcIn : Formatetc Input
LPSTGMEDIUM lpMedium : Pointer to medium
Return Value:
HRESULT
--*/
{
//
// Not implemented
//
return E_NOTIMPL;
}
STDMETHODIMP
CDataObject::EnumFormatEtc(
IN DWORD dwDirection,
IN LPENUMFORMATETC * ppEnumFormatEtc
)
/*++
Routine Description:
Enumerate format etc information
Arguments:
DWORD dwDirection : Direction
LPENUMFORMATETC * ppEnumFormatEtc : Format etc array
Return Value:
HRESULT
--*/
{
//
// Not implemented
//
return E_NOTIMPL;
}
//
// CDataObject creation members
//
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
HRESULT
CDataObject::Create(
IN const void * pBuffer,
IN int len,
IN LPSTGMEDIUM lpMedium
)
/*++
Routine Description:
Create information on the given medium
Arguments:
const void * pBuffer : Data buffer
int len : Size of data
LPSTGMEDIUM lpMedium : Medium to write to.
Return Value:
HRESULT
--*/
{
HRESULT hr = DV_E_TYMED;
//
// Do some simple validation
//
if (pBuffer == NULL || lpMedium == NULL)
{
return E_POINTER;
}
//
// Make sure the type medium is HGLOBAL
//
if (lpMedium->tymed == TYMED_HGLOBAL)
{
//
// Create the stream on the hGlobal passed in
//
LPSTREAM lpStream;
hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
if (SUCCEEDED(hr))
{
//
// Write to the stream the number of bytes
//
unsigned long written;
hr = lpStream->Write(pBuffer, len, &written);
//
// Because we called CreateStreamOnHGlobal with 'FALSE',
// only the stream is released here.
// Note - the caller (i.e. snap-in, object) will free
// the HGLOBAL at the correct time. This is according to
// the IDataObject specification.
//
lpStream->Release();
}
}
return hr;
}
HRESULT
CDataObject::CreateNodeTypeData(
IN LPSTGMEDIUM lpMedium
)
/*++
Routine Description:
Create node type data on medium
Arguments:
LPSTGMEDIUM lpMedium : Medium to write to.
Return Value:
HRESULT
--*/
{
//
// Create the node type object in GUID format
//
const GUID * pcObjectType = NULL;
if (m_internal.m_cookie == NULL)
{
//
// Blank CIISNode, must be the static root
//
pcObjectType = &cInternetRootNode;
}
else
{
//
// Ask the object what kind of object it is.
//
CIISObject * pObject = (CIISObject *)m_internal.m_cookie;
pcObjectType = pObject->GetGUIDPtr();
}
return Create((const void *)pcObjectType, sizeof(GUID), lpMedium);
}
HRESULT
CDataObject::CreateNodeTypeStringData(
IN LPSTGMEDIUM lpMedium
)
/*++
Routine Description:
Create node type in string format
Arguments:
LPSTGMEDIUM lpMedium : Medium to write to.
Return Value:
HRESULT
--*/
{
//
// Create the node type object in GUID string format
//
const wchar_t * cszObjectType = NULL;
CString str;
if (m_internal.m_cookie == NULL)
{
//
// This must be the static root node
//
cszObjectType = GUIDToCString(cInternetRootNode, str);
}
else
{
//
// Ask the CIISObject what type it is
//
CIISObject * pObject = (CIISObject *)m_internal.m_cookie;
cszObjectType = GUIDToCString(pObject->QueryGUID(), str);
}
return Create(
cszObjectType,
((wcslen(cszObjectType) + 1) * sizeof(wchar_t)),
lpMedium
);
}
HRESULT
CDataObject::CreateDisplayName(
IN LPSTGMEDIUM lpMedium
)
/*++
Routine Description:
CDataObject implementations
Arguments:
Return Value:
HRESULT
--*/
{
//
// This is the display name used in the scope pane and snap-in manager
//
// Load the name from resource
// Note - if this is not provided, the console will used the snap-in name
//
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString szDispName;
szDispName.LoadString(IDS_NODENAME);
return Create(
szDispName,
((szDispName.GetLength() + 1) * sizeof(wchar_t)),
lpMedium
);
}
HRESULT
CDataObject::CreateInternal(
IN LPSTGMEDIUM lpMedium
)
/*++
Routine Description:
CDataObject implementations
Arguments:
Return Value:
HRESULT
--*/
{
return Create(&m_internal, sizeof(INTERNAL), lpMedium);
}
HRESULT
CDataObject::CreateMachineName(
IN LPSTGMEDIUM lpMedium
)
/*++
Routine Description:
Create the machine name
Arguments:
LPSTGMEDIUM lpMedium : Address of STGMEDIUM object
Return Value:
HRESULT
--*/
{
wchar_t pzName[MAX_PATH + 1] = {0};
DWORD len; // = MAX_PATH + 1;
CIISObject * pObject = (CIISObject *)m_internal.m_cookie;
if (pObject == NULL)
{
ASSERT(FALSE);
return E_FAIL;
}
lstrcpyn(pzName, pObject->GetMachineName(), MAX_PATH);
len = lstrlen(pzName);
//
// Add 1 for the NULL and calculate the bytes for the stream
//
return Create(pzName, ((len + 1) * sizeof(wchar_t)), lpMedium);
}
HRESULT
CDataObject::CreateMetaField(
IN LPSTGMEDIUM lpMedium,
IN META_FIELD fld
)
/*++
Routine Description:
Create a field from the metabase path, indicated by fld, or the entire
path.
Arguments:
LPSTGMEDIUM lpMedium : Address of STGMEDIUM object
META_FIELD fld : Type of metabase information
Return Value:
HRESULT
--*/
{
CIISObject * pObject = (CIISObject *)m_internal.m_cookie;
if (pObject == NULL)
{
//
// Static root node has no metabase path
//
ASSERT(FALSE);
return E_FAIL;
}
//
// Generate complete metabase path for this node
//
CString strField;
CString strMetaPath;
pObject->BuildFullPath(strMetaPath, TRUE);
if (fld == META_WHOLE)
{
//
// Whole metabase path requested
//
strField = strMetaPath;
}
else
{
//
// A portion of the metabase is requested. Return the requested
// portion
//
LPCTSTR lpMetaPath = (LPCTSTR)strMetaPath;
LPCTSTR lpEndPath = lpMetaPath + strMetaPath.GetLength() + 1;
LPCTSTR lpSvc = NULL;
LPCTSTR lpInstance = NULL;
LPCTSTR lpParent = NULL;
LPCTSTR lpNode = NULL;
//
// Break up the metabase path in portions
//
if (lpSvc = _tcschr(lpMetaPath, _T('/')))
{
++lpSvc;
if (lpInstance = _tcschr(lpSvc, _T('/')))
{
++lpInstance;
if (lpParent = _tcschr(lpInstance, _T('/')))
{
++lpParent;
lpNode = _tcsrchr(lpParent, _T('/'));
if (lpNode)
{
++lpNode;
}
}
}
}
int n1, n2;
switch(fld)
{
case META_SERVICE:
//
// Requested the service string
//
if (lpSvc)
{
n1 = DIFF(lpSvc - lpMetaPath);
n2 = lpInstance ? DIFF(lpInstance - lpSvc) : DIFF(lpEndPath - lpSvc);
strField = strMetaPath.Mid(n1, n2 - 1);
}
break;
case META_INSTANCE:
//
// Requested the instance number
//
if (lpInstance)
{
n1 = DIFF(lpInstance - lpMetaPath);
n2 = lpParent ? DIFF(lpParent - lpInstance) : DIFF(lpEndPath - lpInstance);
strField = strMetaPath.Mid(n1, n2 - 1);
}
break;
case META_PARENT:
//
// Requestd the parent path
//
if (lpParent)
{
n1 = DIFF(lpParent - lpMetaPath);
n2 = lpNode ? DIFF(lpNode - lpParent) : DIFF(lpEndPath - lpParent);
strField = strMetaPath.Mid(n1, n2 - 1);
}
break;
case META_NODE:
//
// Requested the node name
//
if (lpNode)
{
n1 = DIFF(lpNode - lpMetaPath);
n2 = DIFF(lpEndPath - lpNode);
strField = strMetaPath.Mid(n1, n2 - 1);
}
break;
default:
//
// Bogus
//
ASSERT(FALSE);
return E_FAIL;
}
}
TRACEEOLID("Requested metabase path data: " << strField);
int len = strField.GetLength() + 1;
return Create((LPCTSTR)strField, (len) * sizeof(TCHAR), lpMedium);
}
HRESULT
CDataObject::CreateCoClassID(
IN LPSTGMEDIUM lpMedium
)
/*++
Routine Description:
Create the CoClassID
Arguments:
LPSTGMEDIUM lpMedium : Medium
Return Value:
HRESULT
--*/
{
//
// Create the CoClass information
//
return Create((const void *)&m_internal.m_clsid, sizeof(CLSID), lpMedium);
}