reactos/dll/win32/shell32/CIDLDataObj.cpp
Joachim Henze 93ccb203ef [0.4.10][SHELL32] Backport format+logging-trivia, ARRAYSIZE/_countof
Picks various trivial improvements from newer branches, does not fix specific JIRA-tickets and also doesn't
*entirely* cover a specific PR, therefore none of those are mentioned here.
Main motivation is to reduce large scale white-noise diff between the branches, to make
future commits diffs (with some fixes that actually matter) smaller in size and therefore easier to review.

Specifically:
- large-scale formatting & logging improvements, including but not limited to 0.4.15-dev-7653-g 6f91b6c0fe
- strip trailing whitespace
- also typos like 'unkown', missing \n as it was
  part of 0.4.15-dev-6323-g 3854a5d8e9 and
  0.4.15-dev-4492-g 03422451b3
  (I left out the MOUSE_MOVE-one from that, because I consider the missing \n there intentional)
- ports back many usages of ARRAYSIZE/_countof as it was added as part of some commits from Hermes, e.g.:
  *partial* pick of 0.4.13-dev-622-g 8a30801516 and
  *partial* pick of 0.4.15-dev-3642-g 83be315abf (I left out the literals here for now, ...
    I *might* pick them later on their own, but not now. I first want to verify their isolated impact on all compilers generated file-sizes.
    Some of those changes would even increase the binary size, especially those where the same literal is used multiple times,
    because string-pooling is currently not enabled for all toolchains and configurations.)
- COpenWithMenu.cpp: strip double-semicolon
- COpenWithMenu.cpp && folder_options.cpp: add \n to some dbg-prints without increasing their length
- CFSDropTarget.cpp: add \n to some dbg-prints, strip some good-path-traces that are no longer present in master in return to avoid size increase, fix indentation
- CShellLink.cpp: add \n to some dbg-prints without increasing their length
- iconcache.cpp: fix wrong indentation
- shlfileop.cpp: partially pick 0.4.15-dev-7388-g d689cfe158 just the stripping of #ifdef __REACTOS__ but NOT the actual fix! (the ifdefs were only present in 0.4.14)
- 0.4.10 and lower: shellpath.c Strip some TRACEs with wrong format-strings, strip unused string my_DocumentsW

binary size of shell32.dll has tendency to shrink slightly, which is caused solely by the logging changes:

master          RosBEWin2.2.2 GCC8.4.0 dbg x86               10.538.496 (0.4.15-dev-7640-gbdcfc6b)
releases/0.4.14 RosBEWin2.2.2 GCC8.4.0 dbg x86  9.317.888 ->  9.316.684
releases/0.4.14 RosBEWin2.1.6 GCC4.7.2 dbg x86  9.345.024 ->  9.345.024
releases/0.4.13 RosBEWin2.1.6 GCC4.7.2 dbg x86  9.201.152 ->  9.200.640
releases/0.4.12 RosBEWin2.1.6 GCC4.7.2 dbg x86  9.146.880 ->  9.146.880
releases/0.4.11 RosBEWin2.1.6 GCC4.7.2 dbg x86  9.077.760 ->  9.077.248
releases/0.4.10 RosBEWin2.1.6 GCC4.7.2 dbg x86  9.074.176 ->  9.072.128
releases/0.4. 9 RosBEWin2.1.6 GCC4.7.2 dbg x86  8.825.856 ->  8.824.832
releases/0.4. 8 RosBEWin2.1.6 GCC4.7.2 dbg x86  8.740.864 ->  8.738.816
releases/0.4. 7 RosBEWin2.1.6 GCC4.7.2 dbg x86  8.668.160 ->  8.666.624
2024-02-25 01:50:03 +01:00

410 lines
11 KiB
C++

// LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
// COPYRIGHT: 1998-1999 <juergen.schmied@metronet.de>
#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/***********************************************************************
* IEnumFORMATETC implementation
*/
class IEnumFORMATETCImpl :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IEnumFORMATETC
{
private:
UINT posFmt;
UINT countFmt;
LPFORMATETC pFmt;
public:
IEnumFORMATETCImpl();
~IEnumFORMATETCImpl();
HRESULT WINAPI Initialize(UINT cfmt, const FORMATETC afmt[]);
// *****************
virtual HRESULT WINAPI Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed);
virtual HRESULT WINAPI Skip(ULONG celt);
virtual HRESULT WINAPI Reset();
virtual HRESULT WINAPI Clone(LPENUMFORMATETC* ppenum);
BEGIN_COM_MAP(IEnumFORMATETCImpl)
COM_INTERFACE_ENTRY_IID(IID_IEnumFORMATETC, IEnumFORMATETC)
END_COM_MAP()
};
IEnumFORMATETCImpl::IEnumFORMATETCImpl()
{
posFmt = 0;
countFmt = 0;
pFmt = NULL;
}
IEnumFORMATETCImpl::~IEnumFORMATETCImpl()
{
}
HRESULT WINAPI IEnumFORMATETCImpl::Initialize(UINT cfmt, const FORMATETC afmt[])
{
DWORD size;
size = cfmt * sizeof(FORMATETC);
countFmt = cfmt;
pFmt = (LPFORMATETC)SHAlloc(size);
if (pFmt == NULL)
return E_OUTOFMEMORY;
memcpy(pFmt, afmt, size);
return S_OK;
}
HRESULT WINAPI IEnumFORMATETCImpl::Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed)
{
UINT i;
TRACE("(%p)->(%u,%p)\n", this, celt, rgelt);
if(!pFmt)return S_FALSE;
if(!rgelt) return E_INVALIDARG;
if (pceltFethed) *pceltFethed = 0;
for(i = 0; posFmt < countFmt && celt > i; i++)
{
*rgelt++ = pFmt[posFmt++];
}
if (pceltFethed) *pceltFethed = i;
return ((i == celt) ? S_OK : S_FALSE);
}
HRESULT WINAPI IEnumFORMATETCImpl::Skip(ULONG celt)
{
TRACE("(%p)->(num=%u)\n", this, celt);
if (posFmt + celt >= countFmt) return S_FALSE;
posFmt += celt;
return S_OK;
}
HRESULT WINAPI IEnumFORMATETCImpl::Reset()
{
TRACE("(%p)->()\n", this);
posFmt = 0;
return S_OK;
}
HRESULT WINAPI IEnumFORMATETCImpl::Clone(LPENUMFORMATETC* ppenum)
{
HRESULT hResult;
TRACE("(%p)->(ppenum=%p)\n", this, ppenum);
if (!ppenum) return E_INVALIDARG;
hResult = IEnumFORMATETC_Constructor(countFmt, pFmt, ppenum);
if (FAILED (hResult))
return hResult;
return (*ppenum)->Skip(posFmt);
}
HRESULT IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[], IEnumFORMATETC **ppFormat)
{
return ShellObjectCreatorInit<IEnumFORMATETCImpl>(cfmt, afmt, IID_PPV_ARG(IEnumFORMATETC, ppFormat));
}
/***********************************************************************
* IDataObject implementation
*/
/* number of supported formats */
#define MAX_FORMATS 5
class CIDLDataObj :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDataObject,
public IAsyncOperation
{
private:
LPITEMIDLIST pidl;
PIDLIST_RELATIVE *apidl;
UINT cidl;
DWORD dropeffect;
FORMATETC pFormatEtc[MAX_FORMATS];
UINT cfShellIDList;
UINT cfFileNameA;
UINT cfFileNameW;
UINT cfPreferredDropEffect;
BOOL doasync;
public:
CIDLDataObj();
~CIDLDataObj();
HRESULT WINAPI Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx);
///////////
virtual HRESULT WINAPI GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium);
virtual HRESULT WINAPI GetDataHere(LPFORMATETC pformatetc, STGMEDIUM *pmedium);
virtual HRESULT WINAPI QueryGetData(LPFORMATETC pformatetc);
virtual HRESULT WINAPI GetCanonicalFormatEtc(LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut);
virtual HRESULT WINAPI SetData(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease);
virtual HRESULT WINAPI EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
virtual HRESULT WINAPI DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
virtual HRESULT WINAPI DUnadvise(DWORD dwConnection);
virtual HRESULT WINAPI EnumDAdvise(IEnumSTATDATA **ppenumAdvise);
virtual HRESULT WINAPI GetAsyncMode(BOOL *pfIsOpAsync);
virtual HRESULT WINAPI InOperation(BOOL *pfInAsyncOp);
virtual HRESULT WINAPI SetAsyncMode(BOOL fDoOpAsync);
virtual HRESULT WINAPI StartOperation(IBindCtx *pbcReserved);
virtual HRESULT WINAPI EndOperation(HRESULT hResult, IBindCtx *pbcReserved, DWORD dwEffects);
BEGIN_COM_MAP(CIDLDataObj)
COM_INTERFACE_ENTRY_IID(IID_IDataObject, IDataObject)
COM_INTERFACE_ENTRY_IID(IID_IAsyncOperation, IAsyncOperation)
END_COM_MAP()
};
CIDLDataObj::CIDLDataObj()
{
pidl = NULL;
apidl = NULL;
cidl = 0;
dropeffect = 0;
cfShellIDList = 0;
cfFileNameA = 0;
cfFileNameW = 0;
cfPreferredDropEffect = 0;
doasync = FALSE;
}
CIDLDataObj::~CIDLDataObj()
{
TRACE(" destroying IDataObject(%p)\n",this);
_ILFreeaPidl(apidl, cidl);
ILFree(pidl);
}
HRESULT WINAPI CIDLDataObj::Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx)
{
pidl = ILClone(pMyPidl);
apidl = _ILCopyaPidl(apidlx, cidlx);
if (pidl == NULL || apidl == NULL)
return E_OUTOFMEMORY;
cidl = cidlx;
dropeffect = DROPEFFECT_COPY;
cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA);
cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW);
cfPreferredDropEffect = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW);
InitFormatEtc(pFormatEtc[0], cfShellIDList, TYMED_HGLOBAL);
InitFormatEtc(pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL);
InitFormatEtc(pFormatEtc[2], cfFileNameA, TYMED_HGLOBAL);
InitFormatEtc(pFormatEtc[3], cfFileNameW, TYMED_HGLOBAL);
InitFormatEtc(pFormatEtc[4], cfPreferredDropEffect, TYMED_HGLOBAL);
return S_OK;
}
static HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags)
{
DWORD * pdwFlag;
HGLOBAL hGlobal;
TRACE("(0x%08x)\n", dwFlags);
hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
if(!hGlobal) return hGlobal;
pdwFlag = (DWORD*)GlobalLock(hGlobal);
*pdwFlag = dwFlags;
GlobalUnlock(hGlobal);
return hGlobal;
}
/**************************************************************************
* IDataObject_fnGetData
*/
HRESULT WINAPI CIDLDataObj::GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
{
char szTemp[256];
szTemp[0] = 0;
GetClipboardFormatNameA (pformatetcIn->cfFormat, szTemp, 256);
TRACE("(%p)->(%p %p format=%s)\n", this, pformatetcIn, pmedium, szTemp);
if (pformatetcIn->cfFormat == cfShellIDList)
{
if (cidl < 1) return(E_UNEXPECTED);
pmedium->hGlobal = RenderSHELLIDLIST(pidl, apidl, cidl);
}
else if (pformatetcIn->cfFormat == CF_HDROP)
{
if (cidl < 1) return(E_UNEXPECTED);
pmedium->hGlobal = RenderHDROP(pidl, apidl, cidl);
}
else if (pformatetcIn->cfFormat == cfFileNameA)
{
if (cidl < 1) return(E_UNEXPECTED);
pmedium->hGlobal = RenderFILENAMEA(pidl, apidl, cidl);
}
else if (pformatetcIn->cfFormat == cfFileNameW)
{
if (cidl < 1) return(E_UNEXPECTED);
pmedium->hGlobal = RenderFILENAMEW(pidl, apidl, cidl);
}
else if (pformatetcIn->cfFormat == cfPreferredDropEffect)
{
pmedium->hGlobal = RenderPREFEREDDROPEFFECT(dropeffect);
}
else
{
FIXME("-- expected clipformat not implemented\n");
return (E_INVALIDARG);
}
if (pmedium->hGlobal)
{
pmedium->tymed = TYMED_HGLOBAL;
pmedium->pUnkForRelease = NULL;
return S_OK;
}
return E_OUTOFMEMORY;
}
HRESULT WINAPI CIDLDataObj::GetDataHere(LPFORMATETC pformatetc, STGMEDIUM *pmedium)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CIDLDataObj::QueryGetData(LPFORMATETC pformatetc)
{
UINT i;
TRACE("(%p)->(fmt=0x%08x tym=0x%08x)\n", this, pformatetc->cfFormat, pformatetc->tymed);
if(!(DVASPECT_CONTENT & pformatetc->dwAspect))
return DV_E_DVASPECT;
/* check our formats table what we have */
for (i=0; i<MAX_FORMATS; i++)
{
if ((pFormatEtc[i].cfFormat == pformatetc->cfFormat)
&& (pFormatEtc[i].tymed == pformatetc->tymed))
{
return S_OK;
}
}
return DV_E_TYMED;
}
HRESULT WINAPI CIDLDataObj::GetCanonicalFormatEtc(LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CIDLDataObj::SetData(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
{
if (pformatetc->cfFormat == cfPreferredDropEffect)
{
const DWORD *src = (const DWORD *)GlobalLock(pmedium->hGlobal);
if (src != 0)
{
dropeffect = *src;
GlobalUnlock(pmedium->hGlobal);
return S_OK;
}
FIXME("Error setting data");
return E_FAIL;
}
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CIDLDataObj::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
{
TRACE("(%p)->()\n", this);
*ppenumFormatEtc = NULL;
/* only get data */
if (DATADIR_GET == dwDirection)
{
return IEnumFORMATETC_Constructor(MAX_FORMATS, pFormatEtc, ppenumFormatEtc);
}
return E_NOTIMPL;
}
HRESULT WINAPI CIDLDataObj::DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CIDLDataObj::DUnadvise(DWORD dwConnection)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CIDLDataObj::EnumDAdvise(IEnumSTATDATA **ppenumAdvise)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CIDLDataObj::GetAsyncMode(BOOL *pfIsOpAsync)
{
TRACE("(%p)->()\n", this);
*pfIsOpAsync = doasync;
return S_OK;
}
HRESULT WINAPI CIDLDataObj::InOperation(BOOL *pfInAsyncOp)
{
FIXME("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CIDLDataObj::SetAsyncMode(BOOL fDoOpAsync)
{
TRACE("(%p)->()\n", this);
doasync = fDoOpAsync;
return S_OK;
}
HRESULT WINAPI CIDLDataObj::StartOperation(IBindCtx *pbcReserved)
{
TRACE("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CIDLDataObj::EndOperation(HRESULT hResult, IBindCtx *pbcReserved, DWORD dwEffects)
{
TRACE("(%p)->()\n", this);
return E_NOTIMPL;
}
/**************************************************************************
* IDataObject_Constructor
*/
HRESULT IDataObject_Constructor(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidl, UINT cidl, IDataObject **dataObject)
{
return ShellObjectCreatorInit<CIDLDataObj>(hwndOwner, pMyPidl, apidl, cidl, IID_PPV_ARG(IDataObject, dataObject));
}
/*************************************************************************
* SHCreateDataObject [SHELL32.@]
*
*/
HRESULT WINAPI SHCreateDataObject(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IDataObject *pdtInner, REFIID riid, void **ppv)
{
if (IsEqualIID(riid, IID_IDataObject))
{
return CIDLData_CreateFromIDArray(pidlFolder, cidl, apidl, (IDataObject **)ppv);
}
return E_FAIL;
}