windows-nt/Source/XPSP1/NT/net/layer2svc/wlsnp/dataobj.h
2020-09-26 16:20:57 +08:00

559 lines
18 KiB
C++

//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2001.
//
// File: Dataobj.h
//
// Contents: Wifi Policy management Snapin
//
//
// History: TaroonM
// 10/30/01
//
//----------------------------------------------------------------------------
#ifndef _DATAOBJ_H
#define _DATAOBJ_H
#define ByteOffset(base, offset) (((LPBYTE)base)+offset)
/////////////////////////////////////////////////////////////////////////////
// class CSnapInClipboardFormats - contains the clipboard formats supported
// by the WIRELESS snap-in
class CSnapInClipboardFormats
{
public:
// Clipboard formats that are required by the console
static unsigned int m_cfNodeType; // Required by the console
static unsigned int m_cfNodeTypeString; // Required by the console
static unsigned int m_cfDisplayName; // Required by the console
static unsigned int m_cfCoClass; // Required by the console
// static unsigned int m_cfInternal; // Step 3
static unsigned int m_cfWorkstation; // Published information
static unsigned int m_cfDSObjectNames; // Published information
static unsigned int m_cfPolicyObject;
};
/////////////////////////////////////////////////////////////////////////////
// Template class to extract the TYPE format from the data object
template <class TYPE>
TYPE* Extract(LPDATAOBJECT lpDataObject, unsigned int cf)
{
ASSERT(lpDataObject != NULL);
TYPE* p = NULL;
STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
FORMATETC formatetc = { (CLIPFORMAT)cf, NULL,
DVASPECT_CONTENT, -1, TYMED_HGLOBAL
};
// Allocate memory for the stream
int len = (int)((cf == CDataObject::m_cfWorkstation) ?
((MAX_COMPUTERNAME_LENGTH+1) * sizeof(TYPE)) : sizeof(TYPE));
stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, len);
// Get the workstation name from the data object
do
{
if (stgmedium.hGlobal == NULL)
{
TRACE(_T("Extract - stgmedium.hGlobal == NULL\n"));
break;
}
if (lpDataObject->GetDataHere(&formatetc, &stgmedium) != S_OK)
{
TRACE(_T("Extract - GetDataHere FAILED\n"));
break;
}
p = reinterpret_cast<TYPE*>(stgmedium.hGlobal);
if (p == NULL)
{
TRACE(_T("Extract - stgmedium.hGlobal cast to NULL\n"));
break;
}
} while (FALSE);
return p;
}
// helper methods extracting data from data object
// INTERNAL * ExtractInternalFormat(LPDATAOBJECT lpDataObject);
wchar_t * ExtractWorkstation(LPDATAOBJECT lpDataObject);
GUID * ExtractNodeType(LPDATAOBJECT lpDataObject);
CLSID * ExtractClassID(LPDATAOBJECT lpDataObject);
#define FREE_DATA(pData) \
ASSERT(pData != NULL); \
do { if (pData != NULL) \
GlobalFree(pData); } \
while(0);
/////////////////////////////////////////////////////////////////////////////
// Template class implementing IDataObject for the WIRELESS snap-in
template <class T>
class ATL_NO_VTABLE CDataObjectImpl :
public IDataObject,
public CSnapInClipboardFormats
{
friend class CComponentImpl;
// Construction/Destruction
public:
CDataObjectImpl()
#ifdef _DEBUG
: m_ComponentData( NULL )
#endif
{
DSOBJECTObjectNamesPtr (NULL);
POLICYOBJECTPtr (NULL);
// INTERNALCookie (0);
};
~CDataObjectImpl()
{
#ifdef _DEBUG
SetComponentData( NULL );
#endif
if (DSOBJECTObjectNamesPtr() != NULL)
{
// TODO: we need to free the memory associated with this
ASSERT (0);
// and null the member ptr
DSOBJECTObjectNamesPtr(NULL);
}
if (POLICYOBJECTPtr() != NULL)
{
delete POLICYOBJECTPtr();
POLICYOBJECTPtr (NULL);
}
};
// Standard IDataObject methods
public:
// Implemented
STDMETHOD(GetData)(LPFORMATETC lpFormatetcIn, LPSTGMEDIUM lpMedium);
STDMETHOD(GetDataHere)(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium);
STDMETHOD(SetData)(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium, BOOL bRelease);
// Not Implemented
private:
STDMETHOD(QueryGetData)(LPFORMATETC lpFormatetc)
{ return E_NOTIMPL; };
STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC lpFormatetcIn, LPFORMATETC lpFormatetcOut)
{ return E_NOTIMPL; };
STDMETHOD(DAdvise)(LPFORMATETC lpFormatetc, DWORD advf,
LPADVISESINK pAdvSink, LPDWORD pdwConnection)
{ return E_NOTIMPL; };
STDMETHOD(DUnadvise)(DWORD dwConnection)
{ return E_NOTIMPL; };
STDMETHOD(EnumDAdvise)(LPENUMSTATDATA* ppEnumAdvise)
{ return E_NOTIMPL; };
STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC* ppEnumFormatEtc)
{ return E_NOTIMPL; };
// Implementation
public:
STDMETHOD_(const GUID*, GetDataObjectTypeGuid)() { return &cNodeTypeWirelessMan; }
STDMETHOD_(const wchar_t*, GetDataStringObjectTypeGuid)() { return cszNodeTypeWirelessMan; }
// This is used only as a diagnostic in debug builds to track if
// anyone is hanging on to any data objects that's have been handed out
// Snapin's should view context data objects as ephemeral.
#ifdef _DEBUG
public:
void SetComponentData(CComponentDataImpl* pCCD)
{
ASSERT((m_ComponentData == NULL && pCCD != NULL) || pCCD == NULL);
m_ComponentData = pCCD;
} ;
private:
CComponentDataImpl* m_ComponentData;
#endif
public:
// access functions for IDataObject hglobal data in its raw form(s)
// void INTERNALCookie(long cookie) { m_internalData.cookie( cookie );}
// long INTERNALCookie() {return m_internalData.cookie();}
// void INTERNALType(DATA_OBJECT_TYPES type) {ASSERT(m_internalData.type() == CCT_UNINITIALIZED); m_internalData.type(type);}
// DATA_OBJECT_TYPES INTERNALType() {return m_internalData.type();}
//void INTERNALclsid(const CLSID& clsid) {m_internalData.clsid( clsid );}
//CLSID INTERNALclsid () {return m_internalData.clsid();}
void clsid(const CLSID& clsid) {m_clsid = clsid;}
CLSID clsid () {return m_clsid;}
void DSOBJECTObjectNamesPtr (DSOBJECTNAMES* pDSObjectNames) {m_pDSObjectNamesPtr = pDSObjectNames;}
DSOBJECTNAMES* DSOBJECTObjectNamesPtr () {return m_pDSObjectNamesPtr;}
void POLICYOBJECTPtr (POLICYOBJECT* pPolicyObjPtr) {m_pPolicyObjPtr = pPolicyObjPtr;}
POLICYOBJECT* POLICYOBJECTPtr () {return m_pPolicyObjPtr;}
void NodeName (CString &strNodeName) {m_strNodeName = strNodeName;};
CString NodeName () {return m_strNodeName;};
protected:
// allocate hglobal helpers
HRESULT CreateNodeTypeData(LPSTGMEDIUM lpMedium);
HRESULT CreateNodeTypeStringData(LPSTGMEDIUM lpMedium);
HRESULT CreateDisplayName(LPSTGMEDIUM lpMedium);
HRESULT CreateInternal(LPSTGMEDIUM lpMedium);
HRESULT CreateWorkstationName(LPSTGMEDIUM lpMedium);
HRESULT CreateCoClassID(LPSTGMEDIUM lpMedium);
HRESULT CreateDSObjectNames(LPSTGMEDIUM lpMedium);
HRESULT CreatePolicyObject(LPSTGMEDIUM lpMedium);
HRESULT Create(const void* pBuffer, int len, LPSTGMEDIUM lpMedium);
int DataGlobalAllocLen (CLIPFORMAT cf);
// data associated with this IDataObject
// INTERNAL m_internalData;
POLICYOBJECT* m_pPolicyObjPtr;
DSOBJECTNAMES* m_pDSObjectNamesPtr;
CString m_strNodeName;
// Class ID of who created this data object
CLSID m_clsid;
};
/////////////////////////////////////////////////////////////////////////////
// template CDataObjectImpl - IDataObject interface
template <class T>
STDMETHODIMP CDataObjectImpl<T>::GetData(LPFORMATETC lpFormatetcIn, LPSTGMEDIUM lpMedium)
{
OPT_TRACE(_T("CDataObjectImpl<T>::GetData this-%p\n"), this);
AFX_MANAGE_STATE(AfxGetStaticModuleState());
T* pThis = (T*)this;
// allocate the memory
int iLen = DataGlobalAllocLen (lpFormatetcIn->cfFormat);
if (iLen != -1)
{
// allocate the required amount of memory
lpMedium->hGlobal = GlobalAlloc(GMEM_SHARE, iLen);
// make sure they know they need to free this memory
lpMedium->pUnkForRelease = NULL;
// put the data in it
if (lpMedium->hGlobal != NULL)
{
// make use of
return pThis->GetDataHere(lpFormatetcIn, lpMedium);
}
}
OPT_TRACE(_T("CDataObjectImpl<T>::GetData format-%i return E_UNEXPECTED\n"), lpFormatetcIn->cfFormat);
return E_UNEXPECTED;
}
template <class T>
STDMETHODIMP CDataObjectImpl<T>::GetDataHere(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
{
OPT_TRACE(_T("CDataObjectImpl<T>::GetDataHere this-%p\n"), this);
AFX_MANAGE_STATE(AfxGetStaticModuleState());
#ifdef DO_TRACE
{
CLIPFORMAT cfDebug = lpFormatetc->cfFormat;
if (cfDebug == m_cfNodeType)
{
OPT_TRACE(_T(" Format: NodeTypeData\n"));
} else if (cfDebug == m_cfCoClass)
{
OPT_TRACE(_T(" Format: CoClassID\n"));
} else if(cfDebug == m_cfNodeTypeString)
{
OPT_TRACE(_T(" Format: NodeTypeString\n"));
} else if (cfDebug == m_cfDisplayName)
{
OPT_TRACE(_T(" Format: DisplayName\n"));
//} else if (cfDebug == m_cfInternal)
//{
// OPT_TRACE(_T(" Format: INTERNAL\n"));
} else if (cfDebug == m_cfWorkstation)
{
OPT_TRACE(_T(" Format: Workstation\n"));
} else if (cfDebug == m_cfDSObjectNames)
{
OPT_TRACE(_T(" Format: DSObjectNames\n"));
} else if (cfDebug == m_cfPolicyObject)
{
OPT_TRACE(_T(" Format: PolicyObject\n"));
} else
{
OPT_TRACE(_T(" ERROR, Unknown format\n"));
}
}
#endif //#ifdef DO_TRACE
HRESULT hr = DV_E_CLIPFORMAT;
T* pThis = (T*)this;
// Based on the CLIPFORMAT create the alloc the correct amount
// of memory and write the data to it
const CLIPFORMAT cf = lpFormatetc->cfFormat;
if (cf == m_cfNodeType)
{
hr = pThis->CreateNodeTypeData(lpMedium);
} else if (cf == m_cfCoClass)
{
hr = pThis->CreateCoClassID(lpMedium);
} else if(cf == m_cfNodeTypeString)
{
hr = pThis->CreateNodeTypeStringData(lpMedium);
} else if (cf == m_cfDisplayName)
{
hr = pThis->CreateDisplayName(lpMedium);
//} else if (cf == m_cfInternal)
//{
// hr = pThis->CreateInternal(lpMedium);
} else if (cf == m_cfWorkstation)
{
hr = pThis->CreateWorkstationName(lpMedium);
} else if (cf == m_cfDSObjectNames)
{
hr = pThis->CreateDSObjectNames(lpMedium);
} else if (cf == m_cfPolicyObject)
{
hr = pThis->CreatePolicyObject (lpMedium);
}
return hr;
}
template <class T>
STDMETHODIMP CDataObjectImpl<T>::SetData(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium, BOOL bRelease)
{
OPT_TRACE(_T("CDataObjectImpl<T>::SetData this-%p\n"), this);
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = E_NOTIMPL;
// only implemeneted for cf == m_cfPolicyObject
const CLIPFORMAT cf = lpFormatetc->cfFormat;
if (cf == m_cfPolicyObject)
{
// let our POLICYOBJECT pull its data out of the ObjMedium
if (POLICYOBJECTPtr() != NULL)
{
hr = POLICYOBJECTPtr()->FromObjMedium (lpMedium);
// did the user OK or Apply some settings?
if (POLICYOBJECTPtr()->dwInterfaceFlags() == POFLAG_APPLY)
{
// well then...
ASSERT (0);
::MMCPropertyChangeNotify(POLICYOBJECTPtr()->lMMCUpdateHandle(), NULL /*INTERNALCookie()*/);
}
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// template CDataObjectImpl - protected members
template <class T>
HRESULT CDataObjectImpl<T>::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
{
// Create the node type object in GUID format
const GUID* pcObjectType = NULL;
T* pThis = (T*)this;
// get correct object type
pcObjectType = pThis->GetDataObjectTypeGuid ();
return Create(reinterpret_cast<const void*>(pcObjectType), sizeof(GUID), lpMedium);
}
template <class T>
HRESULT CDataObjectImpl<T>::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
{
// Create the node type object in GUID string format
const wchar_t* cszObjectType = NULL;
T* pThis = (T*)this;
// get correct object type string
cszObjectType = pThis->GetDataStringObjectTypeGuid ();
return Create(cszObjectType, ((wcslen(cszObjectType)+1) * sizeof(wchar_t)), lpMedium);
}
template <class T>
HRESULT CDataObjectImpl<T>::CreateDisplayName(LPSTGMEDIUM lpMedium)
{
// This is the display named used in the scope pane and snap-in manager
return Create(NodeName(), ((NodeName().GetLength()+1) * sizeof(wchar_t)), lpMedium);
}
template <class T>
HRESULT CDataObjectImpl<T>::CreateWorkstationName(LPSTGMEDIUM lpMedium)
{
wchar_t pzName[MAX_COMPUTERNAME_LENGTH+1] = {0};
DWORD len = MAX_COMPUTERNAME_LENGTH+1;
if (GetComputerName(pzName, &len) == FALSE)
{
TRACE(_T("CDataObjectImpl<T>::CreateWorkstationName returning E_FAIL\n"));
return E_FAIL;
}
// Add 1 for the NULL and calculate the bytes for the stream
return Create(pzName, ((len+1)* sizeof(wchar_t)), lpMedium);
}
template <class T>
HRESULT CDataObjectImpl<T>::CreateCoClassID(LPSTGMEDIUM lpMedium)
{
// Create the CoClass information
return Create(reinterpret_cast<const void*>(&clsid()), sizeof(CLSID), lpMedium);
}
template <class T>
HRESULT CDataObjectImpl<T>::CreateDSObjectNames(LPSTGMEDIUM lpMedium)
{
int len = 0;
HRESULT hr = S_OK;
len = DataGlobalAllocLen((CLIPFORMAT)m_cfDSObjectNames);
hr = Create(DSOBJECTObjectNamesPtr(), len, lpMedium);
return(hr);
}
template <class T>
HRESULT CDataObjectImpl<T>::CreatePolicyObject(LPSTGMEDIUM lpMedium)
{
HRESULT hr = E_UNEXPECTED;
// can only do this if there is a POLICYOBJECTPtr
if (POLICYOBJECTPtr() != NULL)
{
// allocate a POLICYOBJECTSTRUCT of the correct length
int iLen = POLICYOBJECTPtr()->DataGlobalAllocLen();
POLICYOBJECTSTRUCT* pPolicyStruct = (POLICYOBJECTSTRUCT* ) malloc (iLen);
if (POLICYOBJECTPtr()->ToPolicyStruct (pPolicyStruct) == S_OK)
{
return Create (reinterpret_cast<const void*>(pPolicyStruct), iLen, lpMedium);
};
}
return hr;
}
template <class T>
HRESULT CDataObjectImpl<T>::Create(const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
{
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 (hr == S_OK)
{
// Write to the stream the number of bytes
unsigned long written;
hr = lpStream->Write(pBuffer, len, &written);
// Because we told 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;
}
template <class T>
int CDataObjectImpl<T>::DataGlobalAllocLen (CLIPFORMAT cf)
{
int iLen = -1;
// need to determine the correct amount of space depending on the time
if (cf == CSnapInClipboardFormats::m_cfCoClass)
{
iLen = sizeof (CLSID);
} else if (cf == m_cfNodeType)
{
iLen = sizeof (GUID);
} else if (cf == m_cfWorkstation)
{
iLen = ((MAX_COMPUTERNAME_LENGTH+1) * sizeof(wchar_t));
} else if (cf == m_cfDSObjectNames)
{
// compute size of the DSOBJECTNAMES structure
if (DSOBJECTObjectNamesPtr() != NULL)
{
CString strName = (LPWSTR)ByteOffset(DSOBJECTObjectNamesPtr(), DSOBJECTObjectNamesPtr()->aObjects[0].offsetName);;
CString strClass = (LPWSTR)ByteOffset(DSOBJECTObjectNamesPtr(), DSOBJECTObjectNamesPtr()->aObjects[0].offsetClass);;
iLen = sizeof(DSOBJECTNAMES) + sizeof(DSOBJECT);
iLen += strName.GetLength()*sizeof(wchar_t)+1 + strClass.GetLength()*sizeof(wchar_t)+1;
}
} else if (cf == m_cfPolicyObject)
{
// compute size of the needed POLICYSTORAGE structure
iLen = POLICYOBJECTPtr()->DataGlobalAllocLen();
} else
{
// unknown type!!
}
return iLen;
}
/////////////////////////////////////////////////////////////////////////////
// class CDataObject - standalone instantiation of IDataObject implementation
class CDataObject :
public CDataObjectImpl <CDataObject>,
public CComObjectRoot
{
friend class CComponentImpl;
public:
CDataObject() {};
virtual ~CDataObject() {};
// ATL Maps
DECLARE_NOT_AGGREGATABLE(CDataObject)
BEGIN_COM_MAP(CDataObject)
COM_INTERFACE_ENTRY(IDataObject)
END_COM_MAP()
// Standard IDataObject methods implemented in CDataObjectImpl
};
#endif