Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

376 lines
8.9 KiB

/*++
Copyright (C) 1997-1999 Microsoft Corporation
Module Name:
DATAOBJ.CPP
Abstract:
Implementation of IDataObject for data communication
--*/
#include "StdAfx.h"
#include "smlogcfg.h"
#include "smnode.h"
#include "dataobj.h"
// MMC uses these to get necessary information from our snapin about
// our nodes.
// Register the clipboard formats
unsigned int CDataObject::s_cfMmcMachineName =
RegisterClipboardFormat(CF_MMC_SNAPIN_MACHINE_NAME);
unsigned int CDataObject::s_cfDisplayName =
RegisterClipboardFormat(CCF_DISPLAY_NAME);
unsigned int CDataObject::s_cfNodeType =
RegisterClipboardFormat(CCF_NODETYPE);
unsigned int CDataObject::s_cfSnapinClsid =
RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
unsigned int CDataObject::s_cfInternal =
RegisterClipboardFormat(CF_INTERNAL);
#ifdef _DEBUG // For tracking data objects
static UINT nCount = 0;
WCHAR wszMsg[64];
#endif
/////////////////////////////////////////////////////////////////////////////
// CDataObject - This class is used to pass data back and forth with MMC. It
// uses a standard interface, IDataObject to acomplish this.
// Refer to OLE documentation for a description of clipboard
// formats and the IdataObject interface.
//---------------------------------------------------------------------------
// Added some code to check on data objects
CDataObject::CDataObject()
: m_cRefs(0),
m_ulCookie(0),
m_Context(CCT_UNINITIALIZED),
m_CookieType(COOKIE_IS_ROOTNODE)
{
#ifdef _DEBUG
swprintf( wszMsg, L"DATAOBJECT Create %u\n", nCount );
LOCALTRACE( wszMsg );
nCount++;
#endif
} // end Constructor()
//---------------------------------------------------------------------------
// Added some code to check on data objects
//
CDataObject::~CDataObject()
{
if ( ( COOKIE_IS_COUNTERMAINNODE == m_CookieType )
|| ( COOKIE_IS_TRACEMAINNODE == m_CookieType )
|| ( COOKIE_IS_ALERTMAINNODE == m_CookieType ) )
{
ASSERT( m_ulCookie );
}
#ifdef _DEBUG
swprintf( wszMsg, L"DATAOBJECT Delete %u\n", nCount );
LOCALTRACE( wszMsg );
nCount--;
#endif
} // end Destructor()
/////////////////////////////////////////////////////////////////////////////
// IDataObject implementation
//
//---------------------------------------------------------------------------
// Fill the hGlobal in pmedium with the requested data
//
STDMETHODIMP
CDataObject::GetDataHere
(
FORMATETC *pFormatEtc, // [in] Pointer to the FORMATETC structure
STGMEDIUM *pMedium // [out] Pointer to the STGMEDIUM structure
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = DV_E_FORMATETC; // Unknown format
const CLIPFORMAT cf = pFormatEtc->cfFormat;
IStream *pStream = NULL;
pMedium->pUnkForRelease = NULL; // by OLE spec
do // Write data to the stream based
{ // of the clipformat
hr = CreateStreamOnHGlobal( pMedium->hGlobal, FALSE, &pStream );
if ( FAILED(hr) )
return hr; // Minimal error checking
if( cf == s_cfDisplayName )
{
hr = WriteDisplayName( pStream );
}
else if( cf == s_cfInternal)
{
hr = WriteInternal (pStream);
}
else if( cf == s_cfMmcMachineName)
{
hr = WriteMachineName( pStream );
}
else if( cf == s_cfNodeType )
{
hr = WriteNodeType( pStream );
}
else if( cf == s_cfSnapinClsid )
{
hr = WriteClsid( pStream );
}
} while( 0 );
pStream->Release();
return hr;
} // end GetDataHere()
/////////////////////////////////////////////////////////////////////////////
// Support methods
//
//---------------------------------------------------------------------------
// Write the appropriate GUID to the stream
//
HRESULT
CDataObject::WriteNodeType
(
IStream* pStream // [in] Stream we are writing to
)
{
const GUID *pGuid = NULL;
switch( m_CookieType )
{
case COOKIE_IS_ROOTNODE:
pGuid = &GUID_RootNode;
break;
case COOKIE_IS_COUNTERMAINNODE:
pGuid = &GUID_CounterMainNode;
break;
case COOKIE_IS_TRACEMAINNODE:
pGuid = &GUID_TraceMainNode;
break;
case COOKIE_IS_ALERTMAINNODE:
pGuid = &GUID_AlertMainNode;
break;
default:
ASSERT( FALSE );
return E_UNEXPECTED;
}
return pStream->Write( (PVOID)pGuid, sizeof(GUID), NULL );
} // end WriteNodeType()
//---------------------------------------------------------------------------
// Writes the display name to the stream. This is the name associated
// with the root node
//
HRESULT
CDataObject::WriteDisplayName
(
IStream* pStream // [in] Stream we are writing to
)
{
CString strName;
ULONG ulSizeofName;
ResourceStateManager rsm;
if( NULL == m_ulCookie )
{
// Add Local vs machine name when implement machine name override/change.
// NOTE: For root node, cookie is either NULL or points to a root node object.
strName.LoadString( IDS_MMC_DEFAULT_NAME );
} else {
PSMNODE pTmp = reinterpret_cast<PSMNODE>(m_ulCookie);
//??? strName = *pTmp->GetDisplayName();
strName = pTmp->GetDisplayName();
}
ulSizeofName = strName.GetLength();
ulSizeofName++; // Count null character
ulSizeofName *= sizeof(WCHAR);
return pStream->Write((LPCWSTR)strName, ulSizeofName, NULL);
} // end WriteDisplayName()
//---------------------------------------------------------------------------
// Writes the machine name to the stream.
//
HRESULT
CDataObject::WriteMachineName
(
IStream* pStream // [in] Stream we are writing to
)
{
CString strName;
ULONG ulSizeOfName;
if( NULL == m_ulCookie ) {
// Cookie is null if not an extension. In that case, only support
// local machine.
strName = L""; // local
} else {
PSMNODE pTmp = reinterpret_cast<PSMNODE>(m_ulCookie);
strName = pTmp->GetMachineName();
}
ulSizeOfName = strName.GetLength();
ulSizeOfName++; // Count null character
ulSizeOfName *= sizeof(WCHAR);
return pStream->Write((LPCWSTR)strName, ulSizeOfName, NULL);
} // end WriteMachineName()
//---------------------------------------------------------------------------
// Writes a pointer to this data object to the stream
//
HRESULT
CDataObject::WriteInternal
(
IStream* pStream // [in] Stream we are writing to
)
{
CDataObject *pThis = this;
return pStream->Write( &pThis, sizeof(CDataObject*), NULL );
} // end WriteInternal
//---------------------------------------------------------------------------
// Writes the Class ID to the stream
//
HRESULT
CDataObject::WriteClsid
(
IStream* pStream // [in] Stream we are writing to
)
{
return pStream->Write( &CLSID_ComponentData,
sizeof(CLSID_ComponentData),
NULL
);
} // end WriteClsid()
//---------------------------------------------------------------------------
// The cookie is what ever we decide it is going to be.
// This is being called from QueryDataObject. Refer to that code.
//
VOID
CDataObject::SetData
(
MMC_COOKIE ulCookie, // [in] Unique indentifier
DATA_OBJECT_TYPES Context, // [in] Context of the caller
COOKIETYPE Type // [in] Type of cookie
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ASSERT( NULL == m_ulCookie );
m_ulCookie = ulCookie;
m_Context = Context;
m_CookieType = Type;
} // end SetData()
/////////////////////////////////////////////////////////////////////////////
// IUnknown implementation
//
//---------------------------------------------------------------------------
// Standard implementation
//
STDMETHODIMP
CDataObject::QueryInterface
(
REFIID riid,
LPVOID *ppvObj
)
{
HRESULT hr = S_OK;
do
{
if( NULL == ppvObj )
{
hr = E_INVALIDARG;
break;
}
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (IUnknown *)(IDataObject *)this;
}
else if (IsEqualIID(riid, IID_IDataObject))
{
*ppvObj = (IUnknown *)(IDataObject *)this;
}
else
{
hr = E_NOINTERFACE;
*ppvObj = NULL;
break;
}
// If we got this far we are handing out a new interface pointer on
// this object, so addref it.
AddRef();
} while (0);
return hr;
} // end QueryInterface()
//---------------------------------------------------------------------------
// Standard implementation
//
STDMETHODIMP_(ULONG)
CDataObject::AddRef()
{
return InterlockedIncrement((LONG*) &m_cRefs);
}
//---------------------------------------------------------------------------
// Standard implementation
//
STDMETHODIMP_(ULONG)
CDataObject::Release()
{
ULONG cRefsTemp;
cRefsTemp = InterlockedDecrement((LONG *)&m_cRefs);
if( 0 == cRefsTemp )
{
delete this;
}
return cRefsTemp;
} // end Release()