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