Added DebugBreak.
[wine] / dlls / shell32 / dataobject.c
1 /*
2  *      IEnumFORMATETC, IDataObject
3  *
4  * selecting and droping objects within the shell and/or common dialogs
5  *
6  *      Copyright 1998  <juergen.schmied@metronet.de>
7  */
8 #include <string.h>
9
10 #include "oleidl.h"
11 #include "pidl.h"
12 #include "winerror.h"
13 #include "shell32_main.h"
14 #include "debugtools.h"
15
16 DEFAULT_DEBUG_CHANNEL(shell)
17
18 UINT cfShellIDList=0;
19 UINT cfFileGroupDesc=0;
20 UINT cfFileContents=0;
21
22 /***********************************************************************
23 *   IEnumFORMATETC implementation
24 */
25 typedef struct 
26 {
27     /* IUnknown fields */
28     ICOM_VTABLE(IEnumFORMATETC)* lpvtbl;
29     DWORD                        ref;
30     /* IEnumFORMATETC fields */
31     UINT        posFmt;
32     UINT        countFmt;
33     LPFORMATETC pFmt;
34 } IEnumFORMATETCImpl;
35
36 static HRESULT WINAPI IEnumFORMATETC_fnQueryInterface(LPENUMFORMATETC iface, REFIID riid, LPVOID* ppvObj);
37 static ULONG WINAPI IEnumFORMATETC_fnAddRef(LPENUMFORMATETC iface);
38 static ULONG WINAPI IEnumFORMATETC_fnRelease(LPENUMFORMATETC iface);
39 static HRESULT WINAPI IEnumFORMATETC_fnNext(LPENUMFORMATETC iface, ULONG celt, FORMATETC* rgelt, ULONG* pceltFethed);
40 static HRESULT WINAPI IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface, ULONG celt);
41 static HRESULT WINAPI IEnumFORMATETC_fnReset(LPENUMFORMATETC iface);
42 static HRESULT WINAPI IEnumFORMATETC_fnClone(LPENUMFORMATETC iface, LPENUMFORMATETC* ppenum);
43
44 static struct ICOM_VTABLE(IEnumFORMATETC) efvt = 
45 {
46     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
47         IEnumFORMATETC_fnQueryInterface,
48         IEnumFORMATETC_fnAddRef,
49     IEnumFORMATETC_fnRelease,
50     IEnumFORMATETC_fnNext,
51     IEnumFORMATETC_fnSkip,
52     IEnumFORMATETC_fnReset,
53     IEnumFORMATETC_fnClone
54 };
55
56 LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[])
57 {
58         IEnumFORMATETCImpl* ef;
59         DWORD size=cfmt * sizeof(FORMATETC);
60         
61         ef=(IEnumFORMATETCImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumFORMATETCImpl));
62         ef->ref=1;
63         ef->lpvtbl=&efvt;
64
65         ef->posFmt = 0;
66         ef->countFmt = cfmt;
67         ef->pFmt = SHAlloc (size);
68
69         if (ef->pFmt)
70         { memcpy(ef->pFmt, afmt, size);
71         }
72
73         TRACE("(%p)->()\n",ef);
74         shell32_ObjCount++;
75         return (LPENUMFORMATETC)ef;
76 }
77 static HRESULT WINAPI IEnumFORMATETC_fnQueryInterface(LPENUMFORMATETC iface, REFIID riid, LPVOID* ppvObj)
78 {
79         ICOM_THIS(IEnumFORMATETCImpl,iface);
80         char    xriid[50];
81         WINE_StringFromCLSID((LPCLSID)riid,xriid);
82         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
83
84                         *ppvObj = NULL;
85
86         if(IsEqualIID(riid, &IID_IUnknown))
87         { *ppvObj = This; 
88         }
89         else if(IsEqualIID(riid, &IID_IEnumFORMATETC))
90         { *ppvObj = (IDataObject*)This;
91         }   
92
93         if(*ppvObj)
94         { IEnumFORMATETC_AddRef((IEnumFORMATETC*)*ppvObj);
95           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
96           return S_OK;
97         }
98         TRACE("-- Interface: E_NOINTERFACE\n");
99         return E_NOINTERFACE;
100
101 }
102 static ULONG WINAPI IEnumFORMATETC_fnAddRef(LPENUMFORMATETC iface)
103 {
104         ICOM_THIS(IEnumFORMATETCImpl,iface);
105         TRACE("(%p)->(count=%lu)\n",This, This->ref);
106         shell32_ObjCount++;
107         return ++(This->ref);
108 }
109 static ULONG WINAPI IEnumFORMATETC_fnRelease(LPENUMFORMATETC iface)
110 {
111         ICOM_THIS(IEnumFORMATETCImpl,iface);
112         TRACE("(%p)->()\n",This);
113
114         shell32_ObjCount--;
115
116         if (!--(This->ref)) 
117         { TRACE(" destroying IEnumFORMATETC(%p)\n",This);
118           if (This->pFmt)
119           { SHFree (This->pFmt);
120           }
121           HeapFree(GetProcessHeap(),0,This);
122           return 0;
123         }
124         return This->ref;
125 }
126 static HRESULT WINAPI IEnumFORMATETC_fnNext(LPENUMFORMATETC iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed)
127 {
128         ICOM_THIS(IEnumFORMATETCImpl,iface);
129         UINT cfetch;
130         HRESULT hres = S_FALSE;
131
132         TRACE("(%p)->()\n", This);
133
134         if (This->posFmt < This->countFmt)
135         { cfetch = This->countFmt - This->posFmt;
136           if (cfetch >= celt)
137           { cfetch = celt;
138             hres = S_OK;
139           }
140           memcpy(rgelt, &This->pFmt[This->posFmt], cfetch * sizeof(FORMATETC));
141           This->posFmt += cfetch;
142         }
143         else
144         { cfetch = 0;
145         }
146
147         if (pceltFethed)
148         { *pceltFethed = cfetch;
149         }
150
151         return hres;
152 }
153 static HRESULT WINAPI IEnumFORMATETC_fnSkip(LPENUMFORMATETC iface, ULONG celt)
154 {
155         ICOM_THIS(IEnumFORMATETCImpl,iface);
156         FIXME("(%p)->(num=%lu)\n", This, celt);
157
158         This->posFmt += celt;
159         if (This->posFmt > This->countFmt)
160         { This->posFmt = This->countFmt;
161           return S_FALSE;
162         }
163         return S_OK;
164 }
165 static HRESULT WINAPI IEnumFORMATETC_fnReset(LPENUMFORMATETC iface)
166 {
167         ICOM_THIS(IEnumFORMATETCImpl,iface);
168         FIXME("(%p)->()\n", This);
169
170         This->posFmt = 0;
171         return S_OK;
172 }
173 static HRESULT WINAPI IEnumFORMATETC_fnClone(LPENUMFORMATETC iface, LPENUMFORMATETC* ppenum)
174 {
175         ICOM_THIS(IEnumFORMATETCImpl,iface);
176         FIXME("(%p)->(ppenum=%p)\n", This, ppenum);
177         return E_NOTIMPL;
178 }
179
180 /**************************************************************************
181  *  IDLList "Item ID List List"
182  *
183  *  NOTES
184  *   interal data holder for IDataObject
185  */
186 #define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn)
187 #define STDMETHOD_(type,xfn) type (CALLBACK *fn##xfn)
188 #define THIS_ THIS,
189
190 typedef struct tagLPIDLLIST *LPIDLLIST, IDLList;
191
192 #define THIS LPIDLLIST me
193 typedef enum
194 { State_UnInit=1,
195   State_Init=2,
196   State_OutOfMem=3
197 } IDLListState;
198
199 typedef struct IDLList_VTable
200 { STDMETHOD_(UINT, GetState)(THIS);
201   STDMETHOD_(LPITEMIDLIST, GetElement)(THIS_ UINT nIndex);
202   STDMETHOD_(UINT, GetCount)(THIS);
203   STDMETHOD_(BOOL, StoreItem)(THIS_ LPITEMIDLIST pidl);
204   STDMETHOD_(BOOL, AddItems)(THIS_ LPITEMIDLIST *apidl, UINT cidl);
205   STDMETHOD_(BOOL, InitList)(THIS);
206   STDMETHOD_(void, CleanList)(THIS);
207 } IDLList_VTable,*LPIDLLIST_VTABLE;
208
209 struct tagLPIDLLIST
210 { LPIDLLIST_VTABLE  lpvtbl;
211   HDPA  dpa;
212   UINT  uStep;
213 };
214
215 extern LPIDLLIST IDLList_Constructor (UINT uStep);
216 extern void IDLList_Destructor(LPIDLLIST me);
217 #undef THIS
218
219
220
221 /**************************************************************************
222  *  IDLList "Item ID List List"
223  * 
224  */
225 static UINT WINAPI IDLList_GetState(LPIDLLIST this);
226 static LPITEMIDLIST WINAPI IDLList_GetElement(LPIDLLIST this, UINT nIndex);
227 static UINT WINAPI IDLList_GetCount(LPIDLLIST this);
228 static BOOL WINAPI IDLList_StoreItem(LPIDLLIST this, LPITEMIDLIST pidl);
229 static BOOL WINAPI IDLList_AddItems(LPIDLLIST this, LPITEMIDLIST *apidl, UINT cidl);
230 static BOOL WINAPI IDLList_InitList(LPIDLLIST this);
231 static void WINAPI IDLList_CleanList(LPIDLLIST this);
232
233 static IDLList_VTable idllvt = 
234 {       IDLList_GetState,
235         IDLList_GetElement,
236         IDLList_GetCount,
237         IDLList_StoreItem,
238         IDLList_AddItems,
239         IDLList_InitList,
240         IDLList_CleanList
241 };
242
243 LPIDLLIST IDLList_Constructor (UINT uStep)
244 {       LPIDLLIST lpidll;
245         if (!(lpidll = (LPIDLLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IDLList))))
246           return NULL;
247
248         lpidll->lpvtbl=&idllvt;
249         lpidll->uStep=uStep;
250         lpidll->dpa=NULL;
251
252         TRACE("(%p)\n",lpidll);
253         return lpidll;
254 }
255 void IDLList_Destructor(LPIDLLIST this)
256 {       TRACE("(%p)\n",this);
257         IDLList_CleanList(this);
258 }
259  
260 static UINT WINAPI IDLList_GetState(LPIDLLIST this)
261 {       TRACE("(%p)->(uStep=%u dpa=%p)\n",this, this->uStep, this->dpa);
262
263         if (this->uStep == 0)
264         { if (this->dpa)
265             return(State_Init);
266           return(State_OutOfMem);
267         }
268         return(State_UnInit);
269 }
270 static LPITEMIDLIST WINAPI IDLList_GetElement(LPIDLLIST this, UINT nIndex)
271 {       TRACE("(%p)->(index=%u)\n",this, nIndex);
272         return((LPITEMIDLIST)pDPA_GetPtr(this->dpa, nIndex));
273 }
274 static UINT WINAPI IDLList_GetCount(LPIDLLIST this)
275 {       TRACE("(%p)\n",this);
276         return(IDLList_GetState(this)==State_Init ? DPA_GetPtrCount(this->dpa) : 0);
277 }
278 static BOOL WINAPI IDLList_StoreItem(LPIDLLIST this, LPITEMIDLIST pidl)
279 {       TRACE("(%p)->(pidl=%p)\n",this, pidl);
280         if (pidl)
281         { if (IDLList_InitList(this) && pDPA_InsertPtr(this->dpa, 0x7fff, (LPSTR)pidl)>=0)
282             return(TRUE);
283           ILFree(pidl);
284         }
285         IDLList_CleanList(this);
286         return(FALSE);
287 }
288 static BOOL WINAPI IDLList_AddItems(LPIDLLIST this, LPITEMIDLIST *apidl, UINT cidl)
289 {       INT i;
290         TRACE("(%p)->(apidl=%p cidl=%u)\n",this, apidl, cidl);
291
292         for (i=0; i<cidl; ++i)
293         { if (!IDLList_StoreItem(this, ILClone((LPCITEMIDLIST)apidl[i])))
294             return(FALSE);
295         }
296         return(TRUE);
297 }
298 static BOOL WINAPI IDLList_InitList(LPIDLLIST this)
299 {       TRACE("(%p)\n",this);
300         switch (IDLList_GetState(this))
301         { case State_Init:
302             return(TRUE);
303
304           case State_OutOfMem:
305             return(FALSE);
306
307           case State_UnInit:
308           default:
309             this->dpa = pDPA_Create(this->uStep);
310             this->uStep = 0;
311             return(IDLList_InitList(this));
312         }
313 }
314 static void WINAPI IDLList_CleanList(LPIDLLIST this)
315 {       INT i;
316         TRACE("(%p)\n",this);
317
318         if (this->uStep != 0)
319         { this->dpa = NULL;
320           this->uStep = 0;
321           return;
322         }
323
324         if (!this->dpa)
325         { return;
326         }
327
328         for (i=DPA_GetPtrCount(this->dpa)-1; i>=0; --i)
329         { ILFree(IDLList_GetElement(this,i));
330         }
331
332         pDPA_Destroy(this->dpa);
333         this->dpa=NULL;
334 }        
335
336
337 /***********************************************************************
338 *   IDataObject implementation
339 */
340
341 typedef struct
342 {
343     /* IUnknown fields */
344     ICOM_VTABLE(IDataObject)* lpvtbl;
345     DWORD                     ref;
346     /* IDataObject fields */
347     LPSHELLFOLDER psf;
348     LPIDLLIST     lpill;       /* the data of the dataobject */
349     LPITEMIDLIST  pidl;     
350 } IDataObjectImpl;
351
352 static HRESULT WINAPI IDataObject_fnQueryInterface(LPDATAOBJECT iface, REFIID riid, LPVOID* ppvObj);
353 static ULONG WINAPI IDataObject_fnAddRef(LPDATAOBJECT iface);
354 static ULONG WINAPI IDataObject_fnRelease(LPDATAOBJECT iface);
355 static HRESULT WINAPI IDataObject_fnGetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM* pmedium);
356 static HRESULT WINAPI IDataObject_fnGetDataHere(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM* pmedium);
357 static HRESULT WINAPI IDataObject_fnQueryGetData(LPDATAOBJECT iface, LPFORMATETC pformatetc);
358 static HRESULT WINAPI IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface, LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut);
359 static HRESULT WINAPI IDataObject_fnSetData(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM* pmedium, BOOL fRelease);
360 static HRESULT WINAPI IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface, DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc);
361 static HRESULT WINAPI IDataObject_fnDAdvise(LPDATAOBJECT iface, FORMATETC* pformatetc, DWORD advf, IAdviseSink* pAdvSink, DWORD* pdwConnection);
362 static HRESULT WINAPI IDataObject_fnDUnadvise(LPDATAOBJECT iface, DWORD dwConnection);
363 static HRESULT WINAPI IDataObject_fnEnumDAdvise(LPDATAOBJECT iface, IEnumSTATDATA **ppenumAdvise);
364
365 static struct ICOM_VTABLE(IDataObject) dtovt = 
366 {
367     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
368         IDataObject_fnQueryInterface,
369         IDataObject_fnAddRef,
370     IDataObject_fnRelease,
371     IDataObject_fnGetData,
372     IDataObject_fnGetDataHere,
373     IDataObject_fnQueryGetData,
374     IDataObject_fnGetCanonicalFormatEtc,
375     IDataObject_fnSetData,
376     IDataObject_fnEnumFormatEtc,
377     IDataObject_fnDAdvise,
378     IDataObject_fnDUnadvise,
379     IDataObject_fnEnumDAdvise
380 };
381
382 /**************************************************************************
383 *  IDataObject_Constructor
384 */
385 LPDATAOBJECT IDataObject_Constructor(HWND hwndOwner, LPSHELLFOLDER psf, LPITEMIDLIST * apidl, UINT cidl)
386 {
387         IDataObjectImpl* dto;
388         if (!(dto = (IDataObjectImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDataObjectImpl))))
389           return NULL;
390           
391         dto->ref=1;
392         dto->lpvtbl=&dtovt;
393         dto->psf=psf;
394         dto->pidl=ILClone(((IGenericSFImpl*)psf)->pMyPidl); /* FIXME:add a reference and don't copy*/
395
396         /* fill the ItemID List List */
397         dto->lpill = IDLList_Constructor (8);
398         if (! dto->lpill )
399           return NULL;
400           
401         dto->lpill->lpvtbl->fnAddItems(dto->lpill, apidl, cidl); 
402         
403         TRACE("(%p)->(sf=%p apidl=%p cidl=%u)\n",dto, psf, apidl, cidl);
404         shell32_ObjCount++;
405         return (LPDATAOBJECT)dto;
406 }
407 /***************************************************************************
408 *  IDataObject_QueryInterface
409 */
410 static HRESULT WINAPI IDataObject_fnQueryInterface(LPDATAOBJECT iface, REFIID riid, LPVOID * ppvObj)
411 {
412         ICOM_THIS(IDataObjectImpl,iface);
413         char    xriid[50];
414         WINE_StringFromCLSID((LPCLSID)riid,xriid);
415         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
416
417         *ppvObj = NULL;
418
419         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
420         { *ppvObj = This; 
421         }
422         else if(IsEqualIID(riid, &IID_IDataObject))  /*IDataObject*/
423         { *ppvObj = (IDataObject*)This;
424         }   
425
426         if(*ppvObj)
427         { IDataObject_AddRef((IDataObject*)*ppvObj);      
428           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
429           return S_OK;
430         }
431         TRACE("-- Interface: E_NOINTERFACE\n");
432         return E_NOINTERFACE;
433 }   
434 /**************************************************************************
435 *  IDataObject_AddRef
436 */
437 static ULONG WINAPI IDataObject_fnAddRef(LPDATAOBJECT iface)
438 {
439         ICOM_THIS(IDataObjectImpl,iface);
440
441         TRACE("(%p)->(count=%lu)\n",This, This->ref);
442
443         shell32_ObjCount++;
444         return ++(This->ref);
445 }
446 /**************************************************************************
447 *  IDataObject_Release
448 */
449 static ULONG WINAPI IDataObject_fnRelease(LPDATAOBJECT iface)
450 {
451         ICOM_THIS(IDataObjectImpl,iface);
452         TRACE("(%p)->()\n",This);
453
454         shell32_ObjCount--;
455
456         if (!--(This->ref)) 
457         { TRACE(" destroying IDataObject(%p)\n",This);
458           IDLList_Destructor(This->lpill);
459           HeapFree(GetProcessHeap(),0,This);
460           return 0;
461         }
462         return This->ref;
463 }
464 /**************************************************************************
465 * DATAOBJECT_InitShellIDList (internal)
466 *
467 * NOTES
468 *  get or register the "Shell IDList Array" clipformat
469 */
470 static BOOL DATAOBJECT_InitShellIDList(void)
471 {       if (cfShellIDList)
472         { return(TRUE);
473         }
474
475         cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
476         return(cfShellIDList != 0);
477 }
478
479 /**************************************************************************
480 * DATAOBJECT_InitFileGroupDesc (internal)
481 *
482 * NOTES
483 *  get or register the "FileGroupDescriptor" clipformat
484 */
485 /* FIXME: DATAOBJECT_InitFileGroupDesc is not used (19981226)
486 static BOOL32 DATAOBJECT_InitFileGroupDesc(void)
487 {       if (cfFileGroupDesc)
488         { return(TRUE);
489         }
490
491         cfFileGroupDesc = RegisterClipboardFormatA(CFSTR_FILEDESCRIPTORA);
492         return(cfFileGroupDesc != 0);
493 }
494 */
495 /**************************************************************************
496 * DATAOBJECT_InitFileContents (internal)
497
498 * NOTES
499  * get or register the "FileContents" clipformat
500 */
501 /* FIXME: DATAOBJECT_InitFileContents is not used (19981226)
502 static BOOL32 DATAOBJECT_InitFileContents(void)
503 {       if (cfFileContents)
504         { return(TRUE);
505         }
506
507         cfFileContents = RegisterClipboardFormatA(CFSTR_FILECONTENTS);
508         return(cfFileContents != 0);
509 }
510 */
511
512 /**************************************************************************
513 * interface implementation
514 */
515 static HRESULT WINAPI IDataObject_fnGetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
516 {
517         ICOM_THIS(IDataObjectImpl,iface);
518         char    temp[256];
519         UINT    cItems;
520         DWORD   size, size1, size2;
521         LPITEMIDLIST pidl;
522         LPCIDA pcida;
523         HGLOBAL hmem;
524         
525         GetClipboardFormatNameA (pformatetcIn->cfFormat, temp, 256);
526         WARN("(%p)->(%p %p format=%s)semi-stub\n", This, pformatetcIn, pmedium, temp);
527
528         if (!DATAOBJECT_InitShellIDList())      /* is the clipformat registred? */
529         { return(E_UNEXPECTED);
530         }
531         
532         if (pformatetcIn->cfFormat == cfShellIDList)
533         { if (pformatetcIn->ptd==NULL 
534                 && (pformatetcIn->dwAspect & DVASPECT_CONTENT) 
535                 && pformatetcIn->lindex==-1
536                 && (pformatetcIn->tymed&TYMED_HGLOBAL))
537           { cItems = This->lpill->lpvtbl->fnGetCount(This->lpill);
538             if (cItems < 1)
539             { return(E_UNEXPECTED);
540             }
541             pidl = This->lpill->lpvtbl->fnGetElement(This->lpill, 0);
542
543             pdump(This->pidl);
544             pdump(pidl);
545             
546             /*hack consider only the first item*/
547             cItems = 2;
548             size = sizeof(CIDA) + sizeof (UINT)*(cItems-1);
549             size1 = ILGetSize (This->pidl);
550             size2 = ILGetSize (pidl);
551             hmem = GlobalAlloc(GMEM_FIXED, size+size1+size2);
552             pcida = GlobalLock (hmem);
553             if (!pcida)
554             { return(E_OUTOFMEMORY);
555             }
556
557             pcida->cidl = 1;
558             pcida->aoffset[0] = size;
559             pcida->aoffset[1] = size+size1;
560
561             TRACE("-- %lu %lu %lu\n",size, size1, size2 );
562             TRACE("-- %p %p\n",This->pidl, pidl);
563             TRACE("-- %p %p %p\n",pcida, (LPBYTE)pcida+size,(LPBYTE)pcida+size+size1);
564             
565             memcpy ((LPBYTE)pcida+size, This->pidl, size1);
566             memcpy ((LPBYTE)pcida+size+size1, pidl, size2);
567             TRACE("-- after copy\n");
568
569             GlobalUnlock(hmem);
570             
571             pmedium->tymed = TYMED_HGLOBAL;
572             pmedium->u.hGlobal = (HGLOBAL)pcida;
573             pmedium->pUnkForRelease = NULL;
574             TRACE("-- ready\n");
575             return(NOERROR);
576           }
577         }
578         FIXME("-- clipformat not implemented\n");
579         return (E_INVALIDARG);
580 }
581 static HRESULT WINAPI IDataObject_fnGetDataHere(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium)
582 {
583         ICOM_THIS(IDataObjectImpl,iface);
584         FIXME("(%p)->()\n", This);
585         return E_NOTIMPL;
586 }
587 static HRESULT WINAPI IDataObject_fnQueryGetData(LPDATAOBJECT iface, LPFORMATETC pformatetc)
588 {
589         ICOM_THIS(IDataObjectImpl,iface);
590         FIXME("(%p)->()\n", This);
591         return E_NOTIMPL;
592 }
593 static HRESULT WINAPI IDataObject_fnGetCanonicalFormatEtc(LPDATAOBJECT iface, LPFORMATETC pformatectIn, LPFORMATETC pformatetcOut)
594 {
595         ICOM_THIS(IDataObjectImpl,iface);
596         FIXME("(%p)->()\n", This);
597         return E_NOTIMPL;
598 }
599 static HRESULT WINAPI IDataObject_fnSetData(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
600 {
601         ICOM_THIS(IDataObjectImpl,iface);
602         FIXME("(%p)->()\n", This);
603         return E_NOTIMPL;
604 }
605 static HRESULT WINAPI IDataObject_fnEnumFormatEtc(LPDATAOBJECT iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
606 {
607         ICOM_THIS(IDataObjectImpl,iface);
608         FIXME("(%p)->()\n", This);
609         return E_NOTIMPL;
610 }
611 static HRESULT WINAPI IDataObject_fnDAdvise(LPDATAOBJECT iface, FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection)
612 {
613         ICOM_THIS(IDataObjectImpl,iface);
614         FIXME("(%p)->()\n", This);
615         return E_NOTIMPL;
616 }
617 static HRESULT WINAPI IDataObject_fnDUnadvise(LPDATAOBJECT iface, DWORD dwConnection)
618 {
619         ICOM_THIS(IDataObjectImpl,iface);
620         FIXME("(%p)->()\n", This);
621         return E_NOTIMPL;
622 }
623 static HRESULT WINAPI IDataObject_fnEnumDAdvise(LPDATAOBJECT iface, IEnumSTATDATA **ppenumAdvise)
624 {
625         ICOM_THIS(IDataObjectImpl,iface);
626         FIXME("(%p)->()\n", This);
627         return E_NOTIMPL;
628 }