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.
 
 
 
 
 
 

513 lines
12 KiB

/**************************************************************************
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright 1998 Microsoft Corporation. All Rights Reserved.
**************************************************************************/
/**************************************************************************
File: DataObj.cpp
Description: CDataObject implementation.
**************************************************************************/
/**************************************************************************
#include statements
**************************************************************************/
#include "DataObj.h"
/**************************************************************************
global variables
**************************************************************************/
/**************************************************************************
CDataObject::CDataObject()
**************************************************************************/
CDataObject::CDataObject(CShellFolder *psfParent, LPCITEMIDLIST *aPidls, UINT uItemCount)
{
g_DllRefCount++;
m_uItemCount = 0;
m_psfParent = psfParent;
if(m_psfParent)
m_psfParent->AddRef();
m_ObjRefCount = 1;
m_aPidls = NULL;
SHGetMalloc(&m_pMalloc);
if(!m_pMalloc)
{
delete this;
return;
}
m_pPidlMgr = new CPidlMgr();
m_uItemCount = uItemCount;
AllocPidlTable(uItemCount);
if(m_aPidls)
{
FillPidlTable(aPidls, uItemCount);
}
m_cfPrivateData = RegisterClipboardFormat(CFSTR_SAMPVIEWDATA);
m_cfShellIDList = RegisterClipboardFormat(CFSTR_SHELLIDLIST);
m_cFormatEtc = 2;
m_pFormatEtc = new FORMATETC[m_cFormatEtc];
SETDefFormatEtc(m_pFormatEtc[0], m_cfPrivateData, TYMED_HGLOBAL);
SETDefFormatEtc(m_pFormatEtc[1], m_cfShellIDList, TYMED_HGLOBAL);
m_iCurrent = 0;
}
/**************************************************************************
CDataObject::~CDataObject()
**************************************************************************/
CDataObject::~CDataObject()
{
if(m_psfParent)
m_psfParent->Release();
g_DllRefCount--;
//make sure the pidls are freed
if(m_aPidls && m_pMalloc)
{
FreePidlTable();
}
if(m_pPidlMgr)
delete m_pPidlMgr;
if(m_pMalloc)
m_pMalloc->Release();
//delete [] m_pFormatEtc;
delete m_pFormatEtc;
}
///////////////////////////////////////////////////////////////////////////
//
// IUnknown Implementation
//
/**************************************************************************
CDataObject::QueryInterface
**************************************************************************/
STDMETHODIMP CDataObject::QueryInterface( REFIID riid,
LPVOID *ppReturn)
{
*ppReturn = NULL;
if(IsEqualIID(riid, IID_IUnknown))
{
*ppReturn = (LPUNKNOWN)(LPCONTEXTMENU)this;
}
else if(IsEqualIID(riid, IID_IDataObject))
{
*ppReturn = (LPDATAOBJECT)this;
}
else if(IsEqualIID(riid, IID_IEnumFORMATETC))
{
*ppReturn = (LPENUMFORMATETC)this;
}
if(*ppReturn)
{
(*(LPUNKNOWN*)ppReturn)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
/**************************************************************************
CDataObject::AddRef
**************************************************************************/
STDMETHODIMP_(DWORD) CDataObject::AddRef()
{
return ++m_ObjRefCount;
}
/**************************************************************************
CDataObject::Release
**************************************************************************/
STDMETHODIMP_(DWORD) CDataObject::Release()
{
if(--m_ObjRefCount == 0)
delete this;
return m_ObjRefCount;
}
///////////////////////////////////////////////////////////////////////////
//
// IDataObject Implementation
//
/**************************************************************************
CDataObject::GetData()
**************************************************************************/
STDMETHODIMP CDataObject::GetData(LPFORMATETC pFE, LPSTGMEDIUM pStgMedium)
{
if(pFE->cfFormat == m_cfPrivateData)
{
LPITEMIDLIST pidlParent;
pidlParent = m_psfParent->CreateFQPidl(NULL);
if(pidlParent)
{
pStgMedium->hGlobal = CreatePrivateClipboardData(pidlParent, m_aPidls, m_uItemCount, FALSE);
m_pPidlMgr->Delete(pidlParent);
if(pStgMedium->hGlobal)
{
pStgMedium->tymed = TYMED_HGLOBAL;
return S_OK;
}
}
return E_OUTOFMEMORY;
}
else if(pFE->cfFormat == m_cfShellIDList)
{
LPITEMIDLIST pidlParent;
pidlParent = m_psfParent->CreateFQPidl(NULL);
if(pidlParent)
{
pStgMedium->hGlobal = CreateShellIDList(pidlParent, m_aPidls, m_uItemCount);
m_pPidlMgr->Delete(pidlParent);
if(pStgMedium->hGlobal)
{
pStgMedium->tymed = TYMED_HGLOBAL;
return S_OK;
}
}
return E_OUTOFMEMORY;
}
return E_INVALIDARG;
}
/**************************************************************************
CDataObject::GetDataHere()
**************************************************************************/
STDMETHODIMP CDataObject::GetDataHere (LPFORMATETC pFE, LPSTGMEDIUM pStgMedium)
{
return E_NOTIMPL;
}
/**************************************************************************
CDataObject::QueryGetData()
**************************************************************************/
STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC pFE)
{
BOOL fReturn = FALSE;
/*
Check the aspects we support. Implementations of this object will only
support DVASPECT_CONTENT.
*/
if(!(DVASPECT_CONTENT & pFE->dwAspect))
return DV_E_DVASPECT;
if(pFE->cfFormat == m_cfPrivateData)
{
//
// Now check for an appropriate TYMED.
//
for(UINT i = 0; i < m_cFormatEtc; i++)
{
fReturn |= m_pFormatEtc[i].tymed & pFE->tymed;
}
}
if(pFE->cfFormat == m_cfShellIDList)
{
//
// Now check for an appropriate TYMED.
//
for(UINT i = 0; i < m_cFormatEtc; i++)
{
fReturn |= m_pFormatEtc[i].tymed & pFE->tymed;
}
}
return (fReturn ? S_OK : DV_E_TYMED);
}
/**************************************************************************
CDataObject::GetCanonicalFormatEtc()
**************************************************************************/
STDMETHODIMP CDataObject::GetCanonicalFormatEtc(LPFORMATETC pFEIn, LPFORMATETC pFEOut)
{
if(NULL == pFEOut)
return E_INVALIDARG;
pFEOut->ptd = NULL;
return DATA_S_SAMEFORMATETC;
}
/**************************************************************************
CDataObject::EnumFormatEtc()
**************************************************************************/
STDMETHODIMP CDataObject::EnumFormatEtc( DWORD dwDirection,
IEnumFORMATETC** ppEFE)
{
*ppEFE = NULL;
if(DATADIR_GET == dwDirection)
{
return this->QueryInterface(IID_IEnumFORMATETC, (LPVOID*)ppEFE);
}
return E_NOTIMPL;
}
/**************************************************************************
CDataObject::SetData()
**************************************************************************/
STDMETHODIMP CDataObject::SetData( LPFORMATETC pFE,
LPSTGMEDIUM pStgMedium,
BOOL fRelease)
{
return E_NOTIMPL;
}
/**************************************************************************
CDataObject::DAdvise()
**************************************************************************/
STDMETHODIMP CDataObject::DAdvise( LPFORMATETC pFE,
DWORD advf,
IAdviseSink *ppAdviseSink,
LPDWORD pdwConnection)
{
return E_NOTIMPL;
}
/**************************************************************************
CDataObject::DUnadvise()
**************************************************************************/
STDMETHODIMP CDataObject::DUnadvise(DWORD dwConnection)
{
return E_NOTIMPL;
}
/**************************************************************************
CDataObject::EnumDAdvise()
**************************************************************************/
STDMETHODIMP CDataObject::EnumDAdvise(IEnumSTATDATA** ppEnumAdvise)
{
return E_NOTIMPL;
}
///////////////////////////////////////////////////////////////////////////
//
// IEnumFORMATETC Implementation
//
STDMETHODIMP CDataObject::Next(ULONG uRequested, LPFORMATETC pFormatEtc, ULONG* pulFetched)
{
if(NULL == m_pFormatEtc)
return S_FALSE;
if(NULL != pulFetched)
*pulFetched = 0L;
if(NULL == pFormatEtc)
return E_INVALIDARG;
ULONG uFetched;
for(uFetched = 0; m_iCurrent < m_cFormatEtc && uRequested > uFetched; uFetched++)
{
*pFormatEtc++ = m_pFormatEtc[m_iCurrent++];
}
if(NULL != pulFetched)
*pulFetched = uFetched;
return ((uFetched == uRequested) ? S_OK : S_FALSE);
}
/**************************************************************************
CDataObject::Skip()
**************************************************************************/
STDMETHODIMP CDataObject::Skip(ULONG cSkip)
{
if((m_iCurrent + cSkip) >= m_cFormatEtc)
return S_FALSE;
m_iCurrent += cSkip;
return S_OK;
}
/**************************************************************************
CDataObject::Reset()
**************************************************************************/
STDMETHODIMP CDataObject::Reset(void)
{
m_iCurrent = 0;
return S_OK;
}
/**************************************************************************
CDataObject::Clone()
**************************************************************************/
STDMETHODIMP CDataObject::Clone(LPENUMFORMATETC* ppEnum)
{
CDataObject* pNew;
*ppEnum = NULL;
// Create the clone.
pNew = new CDataObject(m_psfParent, (LPCITEMIDLIST*)m_aPidls, m_uItemCount);
if (NULL == pNew)
return E_OUTOFMEMORY;
pNew->m_iCurrent = m_iCurrent;
*ppEnum = pNew;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////
//
// private and utility methods
//
/**************************************************************************
CDataObject::AllocPidlTable()
**************************************************************************/
BOOL CDataObject::AllocPidlTable(DWORD dwEntries)
{
m_aPidls = (LPITEMIDLIST*)m_pMalloc->Alloc(dwEntries * sizeof(LPITEMIDLIST));
if(m_aPidls)
{
//set all of the entries to NULL
ZeroMemory(m_aPidls, dwEntries * sizeof(LPITEMIDLIST));
}
return (m_aPidls != NULL);
}
/**************************************************************************
CDataObject::FreePidlTable()
**************************************************************************/
VOID CDataObject::FreePidlTable(VOID)
{
if(m_aPidls && m_pPidlMgr)
{
UINT i;
for(i = 0; i < m_uItemCount; i++)
m_pPidlMgr->Delete(m_aPidls[i]);
m_pMalloc->Free(m_aPidls);
m_aPidls = NULL;
}
}
/**************************************************************************
CDataObject::FillPidlTable()
**************************************************************************/
BOOL CDataObject::FillPidlTable(LPCITEMIDLIST *aPidls, UINT uItemCount)
{
if(m_aPidls)
{
if(m_pPidlMgr)
{
UINT i;
for(i = 0; i < uItemCount; i++)
{
m_aPidls[i] = m_pPidlMgr->Copy(aPidls[i]);
}
return TRUE;
}
}
return FALSE;
}