ReactOS 0.4.15-dev-7918-g2a2556c
CIDLDataObj.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: shell32
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: IEnumFORMATETC, IDataObject implementation
5 * COPYRIGHT: Copyright 1998, 1999 <juergen.schmied@metronet.de>
6 * Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
7 */
8
9#include "precomp.h"
10
12
13/***********************************************************************
14* IEnumFORMATETC implementation
15*/
16
18 public CComObjectRootEx<CComMultiThreadModelNoCS>,
19 public IEnumFORMATETC
20{
21private:
25public:
28 HRESULT WINAPI Initialize(UINT cfmt, const FORMATETC afmt[]);
29
30 // *****************
31 STDMETHOD(Next)(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed) override;
32 STDMETHOD(Skip)(ULONG celt) override;
33 STDMETHOD(Reset)() override;
34 STDMETHOD(Clone)(LPENUMFORMATETC* ppenum) override;
35
39};
40
42{
43 posFmt = 0;
44 countFmt = 0;
45 pFmt = NULL;
46}
47
49{
50}
51
53{
54 DWORD size;
55
56 size = cfmt * sizeof(FORMATETC);
57 countFmt = cfmt;
59 if (pFmt == NULL)
60 return E_OUTOFMEMORY;
61
62 memcpy(pFmt, afmt, size);
63 return S_OK;
64}
65
67{
68 UINT i;
69
70 TRACE("(%p)->(%u,%p)\n", this, celt, rgelt);
71
72 if (!pFmt)
73 return S_FALSE;
74 if (!rgelt)
75 return E_INVALIDARG;
76 if (pceltFethed)
77 *pceltFethed = 0;
78
79 for (i = 0; posFmt < countFmt && celt > i; i++)
80 {
81 *rgelt++ = pFmt[posFmt++];
82 }
83
84 if (pceltFethed)
85 *pceltFethed = i;
86
87 return ((i == celt) ? S_OK : S_FALSE);
88}
89
91{
92 TRACE("(%p)->(num=%u)\n", this, celt);
93
94 if (posFmt + celt >= countFmt)
95 return S_FALSE;
96 posFmt += celt;
97 return S_OK;
98}
99
101{
102 TRACE("(%p)->()\n", this);
103
104 posFmt = 0;
105 return S_OK;
106}
107
109{
110 HRESULT hResult;
111
112 TRACE("(%p)->(ppenum=%p)\n", this, ppenum);
113
114 if (!ppenum) return E_INVALIDARG;
115 hResult = IEnumFORMATETC_Constructor(countFmt, pFmt, ppenum);
116 if (FAILED_UNEXPECTEDLY(hResult))
117 return hResult;
118 return (*ppenum)->Skip(posFmt);
119}
120
121HRESULT IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[], IEnumFORMATETC **ppFormat)
122{
123 return ShellObjectCreatorInit<IEnumFORMATETCImpl>(cfmt, afmt, IID_PPV_ARG(IEnumFORMATETC, ppFormat));
124}
125
126
127/***********************************************************************
128* IDataObject implementation
129* For now (2019-10-12) it's compatible with 2k3's data object
130* See shell32_apitest!CIDLData for changes between versions
131*/
132
134 public CComObjectRootEx<CComMultiThreadModelNoCS>,
135 public IDataObject,
136 public IAsyncOperation
137{
138private:
143public:
144 CIDLDataObj();
145 ~CIDLDataObj();
146 HRESULT WINAPI Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx, BOOL bAddAdditionalFormats);
147
148 // *** IDataObject methods ***
149 STDMETHOD(GetData)(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium) override;
150 STDMETHOD(GetDataHere)(LPFORMATETC pformatetc, STGMEDIUM *pmedium) override;
151 STDMETHOD(QueryGetData)(LPFORMATETC pformatetc) override;
152 STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut) override;
153 STDMETHOD(SetData)(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease) override;
154 STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc) override;
155 STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) override;
156 STDMETHOD(DUnadvise)(DWORD dwConnection) override;
157 STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise) override;
158
159 // *** IAsyncOperation methods ***
160 STDMETHOD(SetAsyncMode)(BOOL fDoOpAsync) override;
161 STDMETHOD(GetAsyncMode)(BOOL *pfIsOpAsync) override;
162 STDMETHOD(StartOperation)(IBindCtx *pbcReserved) override;
163 STDMETHOD(InOperation)(BOOL *pfInAsyncOp) override;
164 STDMETHOD(EndOperation)(HRESULT hResult, IBindCtx *pbcReserved, DWORD dwEffects) override;
165
168 COM_INTERFACE_ENTRY_IID(IID_IAsyncOperation, IAsyncOperation)
170};
171
173{
174 m_cfShellIDList = 0;
176}
177
179{
180 TRACE(" destroying IDataObject(%p)\n", this);
181
182 for (int n = 0; n < m_Storage.GetSize(); ++n)
183 {
185 }
188}
189
190HRESULT WINAPI CIDLDataObj::Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx, BOOL bAddAdditionalFormats)
191{
192 HGLOBAL hida = RenderSHELLIDLIST((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx);
193 if (!hida)
194 {
195 ERR("Failed to render " CFSTR_SHELLIDLISTA "\n");
196 return E_OUTOFMEMORY;
197 }
198
200
201 FORMATETC Format = { (CLIPFORMAT)m_cfShellIDList, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
202 STGMEDIUM medium = {0};
203 medium.tymed = TYMED_HGLOBAL;
204 medium.hGlobal = hida;
205 HRESULT hr = SetData(&Format, &medium, TRUE);
206 if (!FAILED_UNEXPECTEDLY(hr) && bAddAdditionalFormats)
207 {
208 Format.cfFormat = CF_HDROP;
209 medium.hGlobal = RenderHDROP((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx);
210 hr = SetData(&Format, &medium, TRUE);
212 return hr;
213
215 medium.hGlobal = RenderFILENAMEA((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx);
216 hr = SetData(&Format, &medium, TRUE);
218 return hr;
219
221 medium.hGlobal = RenderFILENAMEW((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx);
222 hr = SetData(&Format, &medium, TRUE);
224 return hr;
225 }
226
227 return hr;
228}
229
230
231HRESULT WINAPI CIDLDataObj::GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
232{
233 if (TRACE_ON(shell))
234 {
235 char szTemp[256] = {0};
236 GetClipboardFormatNameA (pformatetcIn->cfFormat, szTemp, 256);
237 TRACE("(%p)->(%p %p format=%s)\n", this, pformatetcIn, pmedium, szTemp);
238 }
239 pmedium->hGlobal = NULL;
240 pmedium->pUnkForRelease = NULL;
241 for (int n = 0; n < m_Formats.GetSize(); ++n)
242 {
243 const FORMATETC& fmt = m_Formats[n];
244 if (fmt.cfFormat == pformatetcIn->cfFormat &&
245 fmt.dwAspect == pformatetcIn->dwAspect &&
246 fmt.tymed == pformatetcIn->tymed)
247 {
248 if (pformatetcIn->tymed != TYMED_HGLOBAL)
249 {
251 return E_INVALIDARG;
252 }
253 else
254 {
255 *pmedium = m_Storage[n];
256 return QueryInterface(IID_PPV_ARG(IUnknown, &pmedium->pUnkForRelease));
257 }
258 }
259 }
260
261 return E_INVALIDARG;
262}
263
264HRESULT WINAPI CIDLDataObj::GetDataHere(LPFORMATETC pformatetc, STGMEDIUM *pmedium)
265{
266 FIXME("(%p)->()\n", this);
267 return E_NOTIMPL;
268}
269
271{
272 TRACE("(%p)->(fmt=0x%08x tym=0x%08x)\n", this, pformatetc->cfFormat, pformatetc->tymed);
273
274 for (int n = 0; n < m_Formats.GetSize(); ++n)
275 {
276 const FORMATETC& fmt = m_Formats[n];
277 if (fmt.cfFormat == pformatetc->cfFormat &&
278 fmt.dwAspect == pformatetc->dwAspect &&
279 fmt.tymed == pformatetc->tymed)
280 {
281 return S_OK;
282 }
283 }
284
285 return S_FALSE;
286}
287
288HRESULT WINAPI CIDLDataObj::GetCanonicalFormatEtc(LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut)
289{
290 //FIXME("(%p)->()\n", this);
292}
293
294HRESULT WINAPI CIDLDataObj::SetData(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
295{
296 if (!fRelease)
297 return E_INVALIDARG;
298
299 for (int n = 0; n < m_Formats.GetSize(); ++n)
300 {
301 const FORMATETC& fmt = m_Formats[n];
302 if (fmt.cfFormat == pformatetc->cfFormat &&
303 fmt.dwAspect == pformatetc->dwAspect &&
304 fmt.tymed == pformatetc->tymed)
305 {
307 m_Storage[n] = *pmedium;
308 return S_OK;
309 }
310 }
311
312 m_Formats.Add(*pformatetc);
313 m_Storage.Add(*pmedium);
314
315 return S_OK;
316}
317
319{
320 TRACE("(%p)->()\n", this);
321 *ppenumFormatEtc = NULL;
322
323 /* only get data */
324 if (DATADIR_GET == dwDirection)
325 {
326 return IEnumFORMATETC_Constructor(m_Formats.GetSize(), m_Formats.GetData(), ppenumFormatEtc);
327 }
328
329 return E_NOTIMPL;
330}
331
332HRESULT WINAPI CIDLDataObj::DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
333{
335}
336
338{
340}
341
343{
345}
346
348{
349 TRACE("(%p)->()\n", this);
350 *pfIsOpAsync = m_doasync;
351 return S_OK;
352}
354{
355 FIXME("(%p)->()\n", this);
356 return E_NOTIMPL;
357}
359{
360 TRACE("(%p)->()\n", this);
361 m_doasync = fDoOpAsync;
362 return S_OK;
363}
364
366{
367 TRACE("(%p)->()\n", this);
368 return E_NOTIMPL;
369}
371{
372 TRACE("(%p)->()\n", this);
373 return E_NOTIMPL;
374}
375
376
377
378/**************************************************************************
379 * IDataObject_Constructor
380 */
381HRESULT IDataObject_Constructor(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidl, UINT cidl, BOOL bExtendedObject, IDataObject **dataObject)
382{
383 if (!dataObject)
384 return E_INVALIDARG;
385 return ShellObjectCreatorInit<CIDLDataObj>(hwndOwner, pMyPidl, apidl, cidl, bExtendedObject, IID_PPV_ARG(IDataObject, dataObject));
386}
387
388/*************************************************************************
389 * SHCreateDataObject [SHELL32.@]
390 *
391 */
392
394{
396 {
397 if (pdtInner)
399 return IDataObject_Constructor(NULL, pidlFolder, apidl, cidl, TRUE, (IDataObject **)ppv);
400 }
401 return E_FAIL;
402}
403
404/*************************************************************************
405 * SHCreateFileDataObject [SHELL32.740]
406 *
407 */
408
410{
411 if (pDataInner)
413 return IDataObject_Constructor(NULL, pidlFolder, apidl, cidl, TRUE, ppDataObj);
414}
HRESULT IDataObject_Constructor(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidl, UINT cidl, BOOL bExtendedObject, IDataObject **dataObject)
HRESULT IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[], IEnumFORMATETC **ppFormat)
HRESULT WINAPI SHCreateDataObject(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IDataObject *pdtInner, REFIID riid, void **ppv)
HRESULT WINAPI SHCreateFileDataObject(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IDataObject *pDataInner, IDataObject **ppDataObj)
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define CF_HDROP
Definition: constants.h:410
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define STDMETHOD(m)
Definition: basetyps.h:62
#define FIXME(fmt,...)
Definition: debug.h:111
#define UNIMPLEMENTED
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:110
int GetSize() const
Definition: atlsimpcoll.h:104
BOOL Add(const T &t)
Definition: atlsimpcoll.h:58
STDMETHOD() SetAsyncMode(BOOL fDoOpAsync) override
STDMETHOD() SetData(LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease) override
UINT m_cfShellIDList
STDMETHOD() GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium) override
STDMETHOD() GetCanonicalFormatEtc(LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut) override
STDMETHOD() DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) override
STDMETHOD() EnumDAdvise(IEnumSTATDATA **ppenumAdvise) override
STDMETHOD() GetAsyncMode(BOOL *pfIsOpAsync) override
STDMETHOD() EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc) override
CSimpleArray< STGMEDIUM > m_Storage
STDMETHOD() EndOperation(HRESULT hResult, IBindCtx *pbcReserved, DWORD dwEffects) override
HRESULT WINAPI Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx, BOOL bAddAdditionalFormats)
STDMETHOD() DUnadvise(DWORD dwConnection) override
STDMETHOD() StartOperation(IBindCtx *pbcReserved) override
CSimpleArray< FORMATETC > m_Formats
STDMETHOD() GetDataHere(LPFORMATETC pformatetc, STGMEDIUM *pmedium) override
STDMETHOD() QueryGetData(LPFORMATETC pformatetc) override
STDMETHOD() InOperation(BOOL *pfInAsyncOp) override
HRESULT WINAPI Initialize(UINT cfmt, const FORMATETC afmt[])
Definition: CIDLDataObj.cpp:52
LPFORMATETC pFmt
Definition: CIDLDataObj.cpp:24
STDMETHOD() Reset() override
STDMETHOD() Clone(LPENUMFORMATETC *ppenum) override
STDMETHOD() Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed) override
Definition: CIDLDataObj.cpp:66
STDMETHOD() Skip(ULONG celt) override
Definition: CIDLDataObj.cpp:90
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define TRACE_ON(x)
Definition: compat.h:75
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
HGLOBAL RenderSHELLIDLIST(LPITEMIDLIST pidlRoot, LPITEMIDLIST *apidl, UINT cidl)
Definition: clipboard.c:148
HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST *apidl, UINT cidl)
Definition: clipboard.c:56
HGLOBAL RenderFILENAMEW(LPITEMIDLIST pidlRoot, LPITEMIDLIST *apidl, UINT cidl)
Definition: clipboard.c:222
HGLOBAL RenderFILENAMEA(LPITEMIDLIST pidlRoot, LPITEMIDLIST *apidl, UINT cidl)
Definition: clipboard.c:190
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
struct IEnumFORMATETC::tagFORMATETC * LPFORMATETC
struct IEnumFORMATETC::tagFORMATETC FORMATETC
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define S_OK
Definition: intsafe.h:52
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:581
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:601
#define END_COM_MAP()
Definition: atlcom.h:592
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned int UINT
Definition: ndis.h:50
const GUID IID_IEnumFORMATETC
const GUID IID_IDataObject
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
HRESULT hr
Definition: shlfolder.c:183
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:543
#define CFSTR_SHELLIDLISTA
Definition: shlobj.h:411
#define CFSTR_FILENAMEA
Definition: shlobj.h:418
static const WCHAR CFSTR_FILENAMEW[]
Definition: shlobj.h:509
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
const PCUIDLIST_RELATIVE * PCUIDLIST_RELATIVE_ARRAY
Definition: shtypes.idl:58
#define TRACE(s)
Definition: solgame.cpp:4
Definition: dsound.c:943
uint32_t ULONG
Definition: typedefs.h:59
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define OLE_E_ADVISENOTSUPPORTED
Definition: winerror.h:2617
#define DATA_S_SAMEFORMATETC
Definition: winerror.h:2674
int WINAPI GetClipboardFormatNameA(_In_ UINT format, _Out_writes_(cchMaxCount) LPSTR lpszFormatName, _In_ int cchMaxCount)
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
UINT WINAPI RegisterClipboardFormatA(_In_ LPCSTR)
static void Initialize()
Definition: xlate.c:212
#define IID_PPV_ARG(Itype, ppType)