Added RtlUnwind in ntdll, and made kernel32 spec entry a forward to
[wine/testsucceed.git] / ole / datacache.c
blob365878d79369c1c14ffcc6441abfc68aeac8c321
1 /*
2 * OLE 2 Data cache
4 * Copyright 1999 Francis Beaudet
6 * NOTES:
7 * The OLE2 data cache supports a whole whack of
8 * interfaces including:
9 * IDataObject, IPersistStorage, IViewObject2,
10 * IOleCache2 and IOleCacheControl.
12 * Most of the implementation details are taken from: Inside OLE
13 * second edition by Kraig Brockschmidt,
15 * NOTES
16 * - This implementation of the datacache will let your application
17 * load documents that have embedded OLE objects in them and it will
18 * also retrieve the metafile representation of those objects.
19 * - This implementation of the datacache will also allow your
20 * application to save new documents with OLE objects in them.
21 * - The main thing that it doesn't do is allow you to activate
22 * or modify the OLE objects in any way.
23 * - I haven't found any good documentation on the real usage of
24 * the streams created by the data cache. In particular, How to
25 * determine what the XXX stands for in the stream name
26 * "\002OlePresXXX". I have an intuition that this is related to
27 * the cached aspect of the object but I'm not sure it could
28 * just be a counter.
29 * - Also, I don't know the real content of the presentation stream
30 * header. I was able to figure-out where the extent of the object
31 * was stored but that's about it.
33 #include <assert.h>
35 #include "winuser.h"
36 #include "winerror.h"
37 #include "ole2.h"
38 #include "debug.h"
40 DEFAULT_DEBUG_CHANNEL(ole)
42 /****************************************************************************
43 * PresentationDataHeader
45 * This structure represents the header of the \002OlePresXXX stream in
46 * the OLE object strorage.
48 * Most fields are still unknown.
50 typedef struct PresentationDataHeader
52 DWORD unknown1;
53 DWORD unknown2;
54 DWORD unknown3;
55 DWORD unknown4;
56 DWORD unknown5;
58 DWORD unknown6;
59 DWORD unknown7;
60 DWORD objectExtentX;
61 DWORD objectExtentY;
62 DWORD unknown8;
63 } PresentationDataHeader;
65 /****************************************************************************
66 * DataCache
68 struct DataCache
71 * List all interface VTables here
73 ICOM_VTABLE(IDataObject)* lpvtbl1;
74 ICOM_VTABLE(IUnknown)* lpvtbl2;
75 ICOM_VTABLE(IPersistStorage)* lpvtbl3;
76 ICOM_VTABLE(IViewObject2)* lpvtbl4;
77 ICOM_VTABLE(IOleCache2)* lpvtbl5;
78 ICOM_VTABLE(IOleCacheControl)* lpvtbl6;
81 * Reference count of this object
83 ULONG ref;
86 * IUnknown implementation of the outer object.
88 IUnknown* outerUnknown;
91 * This storage pointer is set through a call to
92 * IPersistStorage_Load. This is where the visual
93 * representation of the object is stored.
95 IStorage* presentationStorage;
98 * The user of this object can setup ONE advise sink
99 * connection with the object. These parameters describe
100 * that connection.
102 DWORD sinkAspects;
103 DWORD sinkAdviseFlag;
104 IAdviseSink* sinkInterface;
108 typedef struct DataCache DataCache;
111 * Here, I define utility macros to help with the casting of the
112 * "this" parameter.
113 * There is a version to accomodate all of the VTables implemented
114 * by this object.
116 #define _ICOM_THIS_From_IDataObject(class,name) class* this = (class*)name;
117 #define _ICOM_THIS_From_NDIUnknown(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
118 #define _ICOM_THIS_From_IPersistStorage(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
119 #define _ICOM_THIS_From_IViewObject2(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
120 #define _ICOM_THIS_From_IOleCache2(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*));
121 #define _ICOM_THIS_From_IOleCacheControl(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*));
124 * Prototypes for the methods of the DataCache class.
126 static DataCache* DataCache_Construct(REFCLSID clsid,
127 LPUNKNOWN pUnkOuter);
128 static void DataCache_Destroy(DataCache* ptrToDestroy);
129 static HRESULT DataCache_ReadPresentationData(DataCache* this,
130 DWORD drawAspect,
131 PresentationDataHeader* header);
132 static HRESULT DataCache_FindPresStreamName(DataCache* this,
133 DWORD drawAspect,
134 OLECHAR* buffer);
135 static HMETAFILE DataCache_ReadPresMetafile(DataCache* this,
136 DWORD drawAspect);
137 static void DataCache_FireOnViewChange(DataCache* this,
138 DWORD aspect,
139 LONG lindex);
142 * Prototypes for the methods of the DataCache class
143 * that implement non delegating IUnknown methods.
145 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
146 IUnknown* iface,
147 REFIID riid,
148 void** ppvObject);
149 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
150 IUnknown* iface);
151 static ULONG WINAPI DataCache_NDIUnknown_Release(
152 IUnknown* iface);
155 * Prototypes for the methods of the DataCache class
156 * that implement IDataObject methods.
158 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
159 IDataObject* iface,
160 REFIID riid,
161 void** ppvObject);
162 static ULONG WINAPI DataCache_IDataObject_AddRef(
163 IDataObject* iface);
164 static ULONG WINAPI DataCache_IDataObject_Release(
165 IDataObject* iface);
166 static HRESULT WINAPI DataCache_GetData(
167 IDataObject* iface,
168 LPFORMATETC pformatetcIn,
169 STGMEDIUM* pmedium);
170 static HRESULT WINAPI DataCache_GetDataHere(
171 IDataObject* iface,
172 LPFORMATETC pformatetc,
173 STGMEDIUM* pmedium);
174 static HRESULT WINAPI DataCache_QueryGetData(
175 IDataObject* iface,
176 LPFORMATETC pformatetc);
177 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
178 IDataObject* iface,
179 LPFORMATETC pformatectIn,
180 LPFORMATETC pformatetcOut);
181 static HRESULT WINAPI DataCache_IDataObject_SetData(
182 IDataObject* iface,
183 LPFORMATETC pformatetc,
184 STGMEDIUM* pmedium,
185 BOOL fRelease);
186 static HRESULT WINAPI DataCache_EnumFormatEtc(
187 IDataObject* iface,
188 DWORD dwDirection,
189 IEnumFORMATETC** ppenumFormatEtc);
190 static HRESULT WINAPI DataCache_DAdvise(
191 IDataObject* iface,
192 FORMATETC* pformatetc,
193 DWORD advf,
194 IAdviseSink* pAdvSink,
195 DWORD* pdwConnection);
196 static HRESULT WINAPI DataCache_DUnadvise(
197 IDataObject* iface,
198 DWORD dwConnection);
199 static HRESULT WINAPI DataCache_EnumDAdvise(
200 IDataObject* iface,
201 IEnumSTATDATA** ppenumAdvise);
204 * Prototypes for the methods of the DataCache class
205 * that implement IPersistStorage methods.
207 static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
208 IPersistStorage* iface,
209 REFIID riid,
210 void** ppvObject);
211 static ULONG WINAPI DataCache_IPersistStorage_AddRef(
212 IPersistStorage* iface);
213 static ULONG WINAPI DataCache_IPersistStorage_Release(
214 IPersistStorage* iface);
215 static HRESULT WINAPI DataCache_GetClassID(
216 const IPersistStorage* iface,
217 CLSID* pClassID);
218 static HRESULT WINAPI DataCache_IsDirty(
219 IPersistStorage* iface);
220 static HRESULT WINAPI DataCache_InitNew(
221 IPersistStorage* iface,
222 IStorage* pStg);
223 static HRESULT WINAPI DataCache_Load(
224 IPersistStorage* iface,
225 IStorage* pStg);
226 static HRESULT WINAPI DataCache_Save(
227 IPersistStorage* iface,
228 IStorage* pStg,
229 BOOL fSameAsLoad);
230 static HRESULT WINAPI DataCache_SaveCompleted(
231 IPersistStorage* iface,
232 IStorage* pStgNew);
233 static HRESULT WINAPI DataCache_HandsOffStorage(
234 IPersistStorage* iface);
237 * Prototypes for the methods of the DataCache class
238 * that implement IViewObject2 methods.
240 static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
241 IViewObject2* iface,
242 REFIID riid,
243 void** ppvObject);
244 static ULONG WINAPI DataCache_IViewObject2_AddRef(
245 IViewObject2* iface);
246 static ULONG WINAPI DataCache_IViewObject2_Release(
247 IViewObject2* iface);
248 static HRESULT WINAPI DataCache_Draw(
249 IViewObject2* iface,
250 DWORD dwDrawAspect,
251 LONG lindex,
252 void* pvAspect,
253 DVTARGETDEVICE* ptd,
254 HDC hdcTargetDev,
255 HDC hdcDraw,
256 LPCRECTL lprcBounds,
257 LPCRECTL lprcWBounds,
258 IVO_ContCallback pfnContinue,
259 DWORD dwContinue);
260 static HRESULT WINAPI DataCache_GetColorSet(
261 IViewObject2* iface,
262 DWORD dwDrawAspect,
263 LONG lindex,
264 void* pvAspect,
265 DVTARGETDEVICE* ptd,
266 HDC hicTargetDevice,
267 LOGPALETTE** ppColorSet);
268 static HRESULT WINAPI DataCache_Freeze(
269 IViewObject2* iface,
270 DWORD dwDrawAspect,
271 LONG lindex,
272 void* pvAspect,
273 DWORD* pdwFreeze);
274 static HRESULT WINAPI DataCache_Unfreeze(
275 IViewObject2* iface,
276 DWORD dwFreeze);
277 static HRESULT WINAPI DataCache_SetAdvise(
278 IViewObject2* iface,
279 DWORD aspects,
280 DWORD advf,
281 IAdviseSink* pAdvSink);
282 static HRESULT WINAPI DataCache_GetAdvise(
283 IViewObject2* iface,
284 DWORD* pAspects,
285 DWORD* pAdvf,
286 IAdviseSink** ppAdvSink);
287 static HRESULT WINAPI DataCache_GetExtent(
288 IViewObject2* iface,
289 DWORD dwDrawAspect,
290 LONG lindex,
291 DVTARGETDEVICE* ptd,
292 LPSIZEL lpsizel);
295 * Prototypes for the methods of the DataCache class
296 * that implement IOleCache2 methods.
298 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
299 IOleCache2* iface,
300 REFIID riid,
301 void** ppvObject);
302 static ULONG WINAPI DataCache_IOleCache2_AddRef(
303 IOleCache2* iface);
304 static ULONG WINAPI DataCache_IOleCache2_Release(
305 IOleCache2* iface);
306 static HRESULT WINAPI DataCache_Cache(
307 IOleCache2* iface,
308 FORMATETC* pformatetc,
309 DWORD advf,
310 DWORD* pdwConnection);
311 static HRESULT WINAPI DataCache_Uncache(
312 IOleCache2* iface,
313 DWORD dwConnection);
314 static HRESULT WINAPI DataCache_EnumCache(
315 IOleCache2* iface,
316 IEnumSTATDATA** ppenumSTATDATA);
317 static HRESULT WINAPI DataCache_InitCache(
318 IOleCache2* iface,
319 IDataObject* pDataObject);
320 static HRESULT WINAPI DataCache_IOleCache2_SetData(
321 IOleCache2* iface,
322 FORMATETC* pformatetc,
323 STGMEDIUM* pmedium,
324 BOOL fRelease);
325 static HRESULT WINAPI DataCache_UpdateCache(
326 IOleCache2* iface,
327 LPDATAOBJECT pDataObject,
328 DWORD grfUpdf,
329 LPVOID pReserved);
330 static HRESULT WINAPI DataCache_DiscardCache(
331 IOleCache2* iface,
332 DWORD dwDiscardOptions);
335 * Prototypes for the methods of the DataCache class
336 * that implement IOleCacheControl methods.
338 static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
339 IOleCacheControl* iface,
340 REFIID riid,
341 void** ppvObject);
342 static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
343 IOleCacheControl* iface);
344 static ULONG WINAPI DataCache_IOleCacheControl_Release(
345 IOleCacheControl* iface);
346 static HRESULT WINAPI DataCache_OnRun(
347 IOleCacheControl* iface,
348 LPDATAOBJECT pDataObject);
349 static HRESULT WINAPI DataCache_OnStop(
350 IOleCacheControl* iface);
353 * Virtual function tables for the DataCache class.
355 static ICOM_VTABLE(IUnknown) DataCache_NDIUnknown_VTable =
357 DataCache_NDIUnknown_QueryInterface,
358 DataCache_NDIUnknown_AddRef,
359 DataCache_NDIUnknown_Release
362 static ICOM_VTABLE(IDataObject) DataCache_IDataObject_VTable =
364 DataCache_IDataObject_QueryInterface,
365 DataCache_IDataObject_AddRef,
366 DataCache_IDataObject_Release,
367 DataCache_GetData,
368 DataCache_GetDataHere,
369 DataCache_QueryGetData,
370 DataCache_GetCanonicalFormatEtc,
371 DataCache_IDataObject_SetData,
372 DataCache_EnumFormatEtc,
373 DataCache_DAdvise,
374 DataCache_DUnadvise,
375 DataCache_EnumDAdvise
378 static ICOM_VTABLE(IPersistStorage) DataCache_IPersistStorage_VTable =
380 DataCache_IPersistStorage_QueryInterface,
381 DataCache_IPersistStorage_AddRef,
382 DataCache_IPersistStorage_Release,
383 DataCache_GetClassID,
384 DataCache_IsDirty,
385 DataCache_InitNew,
386 DataCache_Load,
387 DataCache_Save,
388 DataCache_SaveCompleted,
389 DataCache_HandsOffStorage
392 static ICOM_VTABLE(IViewObject2) DataCache_IViewObject2_VTable =
394 DataCache_IViewObject2_QueryInterface,
395 DataCache_IViewObject2_AddRef,
396 DataCache_IViewObject2_Release,
397 DataCache_Draw,
398 DataCache_GetColorSet,
399 DataCache_Freeze,
400 DataCache_Unfreeze,
401 DataCache_SetAdvise,
402 DataCache_GetAdvise,
403 DataCache_GetExtent
406 static ICOM_VTABLE(IOleCache2) DataCache_IOleCache2_VTable =
408 DataCache_IOleCache2_QueryInterface,
409 DataCache_IOleCache2_AddRef,
410 DataCache_IOleCache2_Release,
411 DataCache_Cache,
412 DataCache_Uncache,
413 DataCache_EnumCache,
414 DataCache_InitCache,
415 DataCache_IOleCache2_SetData,
416 DataCache_UpdateCache,
417 DataCache_DiscardCache
420 static ICOM_VTABLE(IOleCacheControl) DataCache_IOleCacheControl_VTable =
422 DataCache_IOleCacheControl_QueryInterface,
423 DataCache_IOleCacheControl_AddRef,
424 DataCache_IOleCacheControl_Release,
425 DataCache_OnRun,
426 DataCache_OnStop
429 /******************************************************************************
430 * CreateDataCache [OLE32.54]
432 HRESULT WINAPI CreateDataCache(
433 LPUNKNOWN pUnkOuter,
434 REFCLSID rclsid,
435 REFIID riid,
436 LPVOID* ppvObj)
438 DataCache* newCache = NULL;
439 HRESULT hr = S_OK;
440 char xclsid[50];
441 char xriid[50];
443 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
444 WINE_StringFromCLSID((LPCLSID)riid,xriid);
446 TRACE(ole, "(%s, %p, %s, %p)\n", xclsid, pUnkOuter, xriid, ppvObj);
449 * Sanity check
451 if (ppvObj==0)
452 return E_POINTER;
454 *ppvObj = 0;
457 * If this cache is constructed for aggregation, make sure
458 * the caller is requesting the IUnknown interface.
459 * This is necessary because it's the only time the non-delegating
460 * IUnknown pointer can be returned to the outside.
462 if ( (pUnkOuter!=NULL) &&
463 (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) )
464 return CLASS_E_NOAGGREGATION;
467 * Try to construct a new instance of the class.
469 newCache = DataCache_Construct(rclsid,
470 pUnkOuter);
472 if (newCache == 0)
473 return E_OUTOFMEMORY;
476 * Make sure it supports the interface required by the caller.
478 hr = IUnknown_QueryInterface((IUnknown*)&(newCache->lpvtbl2), riid, ppvObj);
481 * Release the reference obtained in the constructor. If
482 * the QueryInterface was unsuccessful, it will free the class.
484 IUnknown_Release((IUnknown*)&(newCache->lpvtbl2));
486 return hr;
489 /*********************************************************
490 * Method implementation for DataCache class.
492 static DataCache* DataCache_Construct(
493 REFCLSID clsid,
494 LPUNKNOWN pUnkOuter)
496 DataCache* newObject = 0;
499 * Allocate space for the object.
501 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache));
503 if (newObject==0)
504 return newObject;
507 * Initialize the virtual function table.
509 newObject->lpvtbl1 = &DataCache_IDataObject_VTable;
510 newObject->lpvtbl2 = &DataCache_NDIUnknown_VTable;
511 newObject->lpvtbl3 = &DataCache_IPersistStorage_VTable;
512 newObject->lpvtbl4 = &DataCache_IViewObject2_VTable;
513 newObject->lpvtbl5 = &DataCache_IOleCache2_VTable;
514 newObject->lpvtbl6 = &DataCache_IOleCacheControl_VTable;
517 * Start with one reference count. The caller of this function
518 * must release the interface pointer when it is done.
520 newObject->ref = 1;
523 * Initialize the outer unknown
524 * We don't keep a reference on the outer unknown since, the way
525 * aggregation works, our lifetime is at least as large as it's
526 * lifetime.
528 if (pUnkOuter==NULL)
529 pUnkOuter = (IUnknown*)&(newObject->lpvtbl2);
531 newObject->outerUnknown = pUnkOuter;
534 * Initialize the other members of the structure.
536 newObject->presentationStorage = NULL;
537 newObject->sinkAspects = 0;
538 newObject->sinkAdviseFlag = 0;
539 newObject->sinkInterface = 0;
541 return newObject;
544 static void DataCache_Destroy(
545 DataCache* ptrToDestroy)
547 TRACE(ole, "()\n");
549 if (ptrToDestroy->sinkInterface != NULL)
551 IAdviseSink_Release(ptrToDestroy->sinkInterface);
552 ptrToDestroy->sinkInterface = NULL;
555 if (ptrToDestroy->presentationStorage != NULL)
557 IStorage_Release(ptrToDestroy->presentationStorage);
558 ptrToDestroy->presentationStorage = NULL;
562 * Free the datacache pointer.
564 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
567 /************************************************************************
568 * DataCache_ReadPresentationData
570 * This method will read information for the requested presentation
571 * into the given structure.
573 * Param:
574 * this - Pointer to the DataCache object
575 * drawAspect - The aspect of the object that we wish to draw.
576 * header - The structure containing information about this
577 * aspect of the object.
579 static HRESULT DataCache_ReadPresentationData(
580 DataCache* this,
581 DWORD drawAspect,
582 PresentationDataHeader* header)
584 IStream* presStream = NULL;
585 OLECHAR streamName[20];
586 HRESULT hres;
589 * Get the name for the presentation stream.
591 hres = DataCache_FindPresStreamName(
592 this,
593 drawAspect,
594 streamName);
596 if (FAILED(hres))
597 return hres;
600 * Open the stream and read the header.
602 hres = IStorage_OpenStream(
603 this->presentationStorage,
604 streamName,
605 NULL,
606 STGM_READ | STGM_SHARE_EXCLUSIVE,
608 &presStream);
610 if (FAILED(hres))
611 return hres;
613 hres = IStream_Read(
614 presStream,
615 header,
616 sizeof(PresentationDataHeader),
617 NULL);
620 * Cleanup.
622 IStream_Release(presStream);
625 * We don't want to propagate any other error
626 * code than a failure.
628 if (hres!=S_OK)
629 hres = E_FAIL;
631 return hres;
634 /************************************************************************
635 * DataCache_FireOnViewChange
637 * This method will fire an OnViewChange notification to the advise
638 * sink registered with the datacache.
640 * See IAdviseSink::OnViewChange for more details.
642 static void DataCache_FireOnViewChange(
643 DataCache* this,
644 DWORD aspect,
645 LONG lindex)
647 TRACE(ole, "(%p, %lx, %ld)\n", this, aspect, lindex);
650 * The sink supplies a filter when it registers
651 * we make sure we only send the notifications when that
652 * filter matches.
654 if ((this->sinkAspects & aspect) != 0)
656 if (this->sinkInterface != NULL)
658 IAdviseSink_OnViewChange(this->sinkInterface,
659 aspect,
660 lindex);
663 * Some sinks want to be unregistered automatically when
664 * the first notification goes out.
666 if ( (this->sinkAdviseFlag & ADVF_ONLYONCE) != 0)
668 IAdviseSink_Release(this->sinkInterface);
670 this->sinkInterface = NULL;
671 this->sinkAspects = 0;
672 this->sinkAdviseFlag = 0;
678 /************************************************************************
679 * DataCache_ReadPresentationData
681 * This method will read information for the requested presentation
682 * into the given structure.
684 * Param:
685 * this - Pointer to the DataCache object
686 * drawAspect - The aspect of the object that we wish to draw.
687 * header - The structure containing information about this
688 * aspect of the object.
690 * NOTE:
691 * This method only supports the DVASPECT_CONTENT aspect.
693 static HRESULT DataCache_FindPresStreamName(
694 DataCache* this,
695 DWORD drawAspect,
696 OLECHAR* buffer)
698 OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
700 if (drawAspect!=DVASPECT_CONTENT)
701 return E_FAIL;
703 memcpy(buffer, name, sizeof(name));
705 return S_OK;
708 /************************************************************************
709 * DataCache_ReadPresentationData
711 * This method will read information for the requested presentation
712 * into the given structure.
714 * Param:
715 * this - Pointer to the DataCache object
716 * drawAspect - The aspect of the object that we wish to draw.
718 * Returns:
719 * This method returns a metafile handle if it is successful.
720 * it will return 0 if not.
722 static HMETAFILE DataCache_ReadPresMetafile(
723 DataCache* this,
724 DWORD drawAspect)
726 LARGE_INTEGER offset;
727 IStream* presStream = NULL;
728 OLECHAR streamName[20];
729 HRESULT hres;
730 void* metafileBits;
731 STATSTG streamInfo;
732 HMETAFILE newMetafile = 0;
735 * Get the name for the presentation stream.
737 hres = DataCache_FindPresStreamName(
738 this,
739 drawAspect,
740 streamName);
742 if (FAILED(hres))
743 return hres;
746 * Open the stream and read the header.
748 hres = IStorage_OpenStream(
749 this->presentationStorage,
750 streamName,
751 NULL,
752 STGM_READ | STGM_SHARE_EXCLUSIVE,
754 &presStream);
756 if (FAILED(hres))
757 return hres;
760 * Get the size of the stream.
762 hres = IStream_Stat(presStream,
763 &streamInfo,
764 STATFLAG_NONAME);
767 * Skip the header
769 offset.HighPart = 0;
770 offset.LowPart = sizeof(PresentationDataHeader);
772 hres = IStream_Seek(
773 presStream,
774 offset,
775 STREAM_SEEK_SET,
776 NULL);
779 * Allocate a buffer for the metafile bits.
781 metafileBits = HeapAlloc(GetProcessHeap(),
783 streamInfo.cbSize.LowPart);
786 * Read the metafile bits.
788 hres = IStream_Read(
789 presStream,
790 metafileBits,
791 streamInfo.cbSize.LowPart,
792 NULL);
795 * Create a metafile with those bits.
797 if (SUCCEEDED(hres))
799 newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.LowPart, metafileBits);
803 * Cleanup.
805 HeapFree(GetProcessHeap(), 0, metafileBits);
806 IStream_Release(presStream);
808 if (newMetafile==0)
809 hres = E_FAIL;
811 return newMetafile;
814 /*********************************************************
815 * Method implementation for the non delegating IUnknown
816 * part of the DataCache class.
819 /************************************************************************
820 * DataCache_NDIUnknown_QueryInterface (IUnknown)
822 * See Windows documentation for more details on IUnknown methods.
824 * This version of QueryInterface will not delegate it's implementation
825 * to the outer unknown.
827 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
828 IUnknown* iface,
829 REFIID riid,
830 void** ppvObject)
832 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
835 * Perform a sanity check on the parameters.
837 if ( (this==0) || (ppvObject==0) )
838 return E_INVALIDARG;
841 * Initialize the return parameter.
843 *ppvObject = 0;
846 * Compare the riid with the interface IDs implemented by this object.
848 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
850 *ppvObject = iface;
852 else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0)
854 *ppvObject = (IDataObject*)&(this->lpvtbl1);
856 else if ( (memcmp(&IID_IPersistStorage, riid, sizeof(IID_IPersistStorage)) == 0) ||
857 (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0) )
859 *ppvObject = (IPersistStorage*)&(this->lpvtbl3);
861 else if ( (memcmp(&IID_IViewObject, riid, sizeof(IID_IViewObject)) == 0) ||
862 (memcmp(&IID_IViewObject2, riid, sizeof(IID_IViewObject2)) == 0) )
864 *ppvObject = (IViewObject2*)&(this->lpvtbl4);
866 else if ( (memcmp(&IID_IOleCache, riid, sizeof(IID_IOleCache)) == 0) ||
867 (memcmp(&IID_IOleCache2, riid, sizeof(IID_IOleCache2)) == 0) )
869 *ppvObject = (IOleCache2*)&(this->lpvtbl5);
871 else if (memcmp(&IID_IOleCacheControl, riid, sizeof(IID_IOleCacheControl)) == 0)
873 *ppvObject = (IOleCacheControl*)&(this->lpvtbl6);
877 * Check that we obtained an interface.
879 if ((*ppvObject)==0)
881 char clsid[50];
883 WINE_StringFromCLSID((LPCLSID)riid,clsid);
885 WARN(ole,
886 "() : asking for un supported interface %s\n",
887 clsid);
889 return E_NOINTERFACE;
893 * Query Interface always increases the reference count by one when it is
894 * successful.
896 IUnknown_AddRef((IUnknown*)*ppvObject);
898 return S_OK;;
901 /************************************************************************
902 * DataCache_NDIUnknown_AddRef (IUnknown)
904 * See Windows documentation for more details on IUnknown methods.
906 * This version of QueryInterface will not delegate it's implementation
907 * to the outer unknown.
909 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
910 IUnknown* iface)
912 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
914 this->ref++;
916 return this->ref;
919 /************************************************************************
920 * DataCache_NDIUnknown_Release (IUnknown)
922 * See Windows documentation for more details on IUnknown methods.
924 * This version of QueryInterface will not delegate it's implementation
925 * to the outer unknown.
927 static ULONG WINAPI DataCache_NDIUnknown_Release(
928 IUnknown* iface)
930 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
933 * Decrease the reference count on this object.
935 this->ref--;
938 * If the reference count goes down to 0, perform suicide.
940 if (this->ref==0)
942 DataCache_Destroy(this);
944 return 0;
947 return this->ref;
950 /*********************************************************
951 * Method implementation for the IDataObject
952 * part of the DataCache class.
955 /************************************************************************
956 * DataCache_IDataObject_QueryInterface (IUnknown)
958 * See Windows documentation for more details on IUnknown methods.
960 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
961 IDataObject* iface,
962 REFIID riid,
963 void** ppvObject)
965 _ICOM_THIS_From_IDataObject(DataCache, iface);
967 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
970 /************************************************************************
971 * DataCache_IDataObject_AddRef (IUnknown)
973 * See Windows documentation for more details on IUnknown methods.
975 static ULONG WINAPI DataCache_IDataObject_AddRef(
976 IDataObject* iface)
978 _ICOM_THIS_From_IDataObject(DataCache, iface);
980 return IUnknown_AddRef(this->outerUnknown);
983 /************************************************************************
984 * DataCache_IDataObject_Release (IUnknown)
986 * See Windows documentation for more details on IUnknown methods.
988 static ULONG WINAPI DataCache_IDataObject_Release(
989 IDataObject* iface)
991 _ICOM_THIS_From_IDataObject(DataCache, iface);
993 return IUnknown_Release(this->outerUnknown);
996 static HRESULT WINAPI DataCache_GetData(
997 IDataObject* iface,
998 LPFORMATETC pformatetcIn,
999 STGMEDIUM* pmedium)
1001 FIXME(ole,"stub\n");
1002 return E_NOTIMPL;
1005 static HRESULT WINAPI DataCache_GetDataHere(
1006 IDataObject* iface,
1007 LPFORMATETC pformatetc,
1008 STGMEDIUM* pmedium)
1010 FIXME(ole,"stub\n");
1011 return E_NOTIMPL;
1014 static HRESULT WINAPI DataCache_QueryGetData(
1015 IDataObject* iface,
1016 LPFORMATETC pformatetc)
1018 FIXME(ole,"stub\n");
1019 return E_NOTIMPL;
1022 /************************************************************************
1023 * DataCache_EnumFormatEtc (IDataObject)
1025 * The data cache doesn't implement this method.
1027 * See Windows documentation for more details on IDataObject methods.
1029 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
1030 IDataObject* iface,
1031 LPFORMATETC pformatectIn,
1032 LPFORMATETC pformatetcOut)
1034 TRACE(ole,"()\n");
1035 return E_NOTIMPL;
1038 /************************************************************************
1039 * DataCache_IDataObject_SetData (IDataObject)
1041 * This method is delegated to the IOleCache2 implementation.
1043 * See Windows documentation for more details on IDataObject methods.
1045 static HRESULT WINAPI DataCache_IDataObject_SetData(
1046 IDataObject* iface,
1047 LPFORMATETC pformatetc,
1048 STGMEDIUM* pmedium,
1049 BOOL fRelease)
1051 IOleCache2* oleCache = NULL;
1052 HRESULT hres;
1054 TRACE(ole,"(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1056 hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
1058 if (FAILED(hres))
1059 return E_UNEXPECTED;
1061 hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
1063 IOleCache2_Release(oleCache);
1065 return hres;;
1068 /************************************************************************
1069 * DataCache_EnumFormatEtc (IDataObject)
1071 * The data cache doesn't implement this method.
1073 * See Windows documentation for more details on IDataObject methods.
1075 static HRESULT WINAPI DataCache_EnumFormatEtc(
1076 IDataObject* iface,
1077 DWORD dwDirection,
1078 IEnumFORMATETC** ppenumFormatEtc)
1080 TRACE(ole,"()\n");
1081 return E_NOTIMPL;
1084 /************************************************************************
1085 * DataCache_DAdvise (IDataObject)
1087 * The data cache doesn't support connections.
1089 * See Windows documentation for more details on IDataObject methods.
1091 static HRESULT WINAPI DataCache_DAdvise(
1092 IDataObject* iface,
1093 FORMATETC* pformatetc,
1094 DWORD advf,
1095 IAdviseSink* pAdvSink,
1096 DWORD* pdwConnection)
1098 TRACE(ole,"()\n");
1099 return OLE_E_ADVISENOTSUPPORTED;
1102 /************************************************************************
1103 * DataCache_DUnadvise (IDataObject)
1105 * The data cache doesn't support connections.
1107 * See Windows documentation for more details on IDataObject methods.
1109 static HRESULT WINAPI DataCache_DUnadvise(
1110 IDataObject* iface,
1111 DWORD dwConnection)
1113 TRACE(ole,"()\n");
1114 return OLE_E_NOCONNECTION;
1117 /************************************************************************
1118 * DataCache_EnumDAdvise (IDataObject)
1120 * The data cache doesn't support connections.
1122 * See Windows documentation for more details on IDataObject methods.
1124 static HRESULT WINAPI DataCache_EnumDAdvise(
1125 IDataObject* iface,
1126 IEnumSTATDATA** ppenumAdvise)
1128 TRACE(ole,"()\n");
1129 return OLE_E_ADVISENOTSUPPORTED;
1132 /*********************************************************
1133 * Method implementation for the IDataObject
1134 * part of the DataCache class.
1137 /************************************************************************
1138 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1140 * See Windows documentation for more details on IUnknown methods.
1142 static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
1143 IPersistStorage* iface,
1144 REFIID riid,
1145 void** ppvObject)
1147 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1149 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1152 /************************************************************************
1153 * DataCache_IPersistStorage_AddRef (IUnknown)
1155 * See Windows documentation for more details on IUnknown methods.
1157 static ULONG WINAPI DataCache_IPersistStorage_AddRef(
1158 IPersistStorage* iface)
1160 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1162 return IUnknown_AddRef(this->outerUnknown);
1165 /************************************************************************
1166 * DataCache_IPersistStorage_Release (IUnknown)
1168 * See Windows documentation for more details on IUnknown methods.
1170 static ULONG WINAPI DataCache_IPersistStorage_Release(
1171 IPersistStorage* iface)
1173 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1175 return IUnknown_Release(this->outerUnknown);
1178 /************************************************************************
1179 * DataCache_GetClassID (IPersistStorage)
1181 * The data cache doesn't implement this method.
1183 * See Windows documentation for more details on IPersistStorage methods.
1185 static HRESULT WINAPI DataCache_GetClassID(
1186 const IPersistStorage* iface,
1187 CLSID* pClassID)
1189 TRACE(ole,"(%p, %p)\n", iface, pClassID);
1190 return E_NOTIMPL;
1193 /************************************************************************
1194 * DataCache_IsDirty (IPersistStorage)
1196 * Until we actully connect to a running object and retrieve new
1197 * information to it, we never get dirty.
1199 * See Windows documentation for more details on IPersistStorage methods.
1201 static HRESULT WINAPI DataCache_IsDirty(
1202 IPersistStorage* iface)
1204 TRACE(ole,"(%p)\n", iface);
1206 return S_FALSE;
1209 /************************************************************************
1210 * DataCache_InitNew (IPersistStorage)
1212 * The data cache implementation of IPersistStorage_InitNew simply stores
1213 * the storage pointer.
1215 * See Windows documentation for more details on IPersistStorage methods.
1217 static HRESULT WINAPI DataCache_InitNew(
1218 IPersistStorage* iface,
1219 IStorage* pStg)
1221 TRACE(ole, "(%p, %p)\n", iface, pStg);
1223 return DataCache_Load(iface, pStg);
1226 /************************************************************************
1227 * DataCache_Load (IPersistStorage)
1229 * The data cache implementation of IPersistStorage_Load doesn't
1230 * actually load anything. Instead, it holds on to the storage pointer
1231 * and it will load the presentation information when the
1232 * IDataObject_GetData or IViewObject2_Draw methods are called.
1234 * See Windows documentation for more details on IPersistStorage methods.
1236 static HRESULT WINAPI DataCache_Load(
1237 IPersistStorage* iface,
1238 IStorage* pStg)
1240 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1242 TRACE(ole, "(%p, %p)\n", iface, pStg);
1244 if (this->presentationStorage != NULL)
1246 IStorage_Release(this->presentationStorage);
1249 this->presentationStorage = pStg;
1251 if (this->presentationStorage != NULL)
1253 IStorage_AddRef(this->presentationStorage);
1256 return S_OK;
1259 /************************************************************************
1260 * DataCache_Save (IPersistStorage)
1262 * Until we actully connect to a running object and retrieve new
1263 * information to it, we never have to save anything. However, it is
1264 * our responsability to copy the information when saving to a new
1265 * storage.
1267 * See Windows documentation for more details on IPersistStorage methods.
1269 static HRESULT WINAPI DataCache_Save(
1270 IPersistStorage* iface,
1271 IStorage* pStg,
1272 BOOL fSameAsLoad)
1274 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1276 TRACE(ole, "(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
1278 if ( (!fSameAsLoad) &&
1279 (this->presentationStorage!=NULL) )
1281 return IStorage_CopyTo(this->presentationStorage,
1283 NULL,
1284 NULL,
1285 pStg);
1288 return S_OK;
1291 /************************************************************************
1292 * DataCache_SaveCompleted (IPersistStorage)
1294 * This method is called to tell the cache to release the storage
1295 * pointer it's currentlu holding.
1297 * See Windows documentation for more details on IPersistStorage methods.
1299 static HRESULT WINAPI DataCache_SaveCompleted(
1300 IPersistStorage* iface,
1301 IStorage* pStgNew)
1303 TRACE(ole, "(%p, %p)\n", iface, pStgNew);
1306 * First, make sure we get our hands off any storage we have.
1308 DataCache_HandsOffStorage(iface);
1311 * Then, attach to the new storage.
1313 DataCache_Load(iface, pStgNew);
1315 return S_OK;
1318 /************************************************************************
1319 * DataCache_HandsOffStorage (IPersistStorage)
1321 * This method is called to tell the cache to release the storage
1322 * pointer it's currentlu holding.
1324 * See Windows documentation for more details on IPersistStorage methods.
1326 static HRESULT WINAPI DataCache_HandsOffStorage(
1327 IPersistStorage* iface)
1329 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1331 TRACE(ole,"(%p)\n", iface);
1333 if (this->presentationStorage != NULL)
1335 IStorage_Release(this->presentationStorage);
1336 this->presentationStorage = NULL;
1339 return S_OK;
1342 /*********************************************************
1343 * Method implementation for the IViewObject2
1344 * part of the DataCache class.
1347 /************************************************************************
1348 * DataCache_IViewObject2_QueryInterface (IUnknown)
1350 * See Windows documentation for more details on IUnknown methods.
1352 static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
1353 IViewObject2* iface,
1354 REFIID riid,
1355 void** ppvObject)
1357 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1359 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1362 /************************************************************************
1363 * DataCache_IViewObject2_AddRef (IUnknown)
1365 * See Windows documentation for more details on IUnknown methods.
1367 static ULONG WINAPI DataCache_IViewObject2_AddRef(
1368 IViewObject2* iface)
1370 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1372 return IUnknown_AddRef(this->outerUnknown);
1375 /************************************************************************
1376 * DataCache_IViewObject2_Release (IUnknown)
1378 * See Windows documentation for more details on IUnknown methods.
1380 static ULONG WINAPI DataCache_IViewObject2_Release(
1381 IViewObject2* iface)
1383 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1385 return IUnknown_Release(this->outerUnknown);
1388 /************************************************************************
1389 * DataCache_Draw (IViewObject2)
1391 * This method will draw the cached representation of the object
1392 * to the given device context.
1394 * See Windows documentation for more details on IViewObject2 methods.
1396 static HRESULT WINAPI DataCache_Draw(
1397 IViewObject2* iface,
1398 DWORD dwDrawAspect,
1399 LONG lindex,
1400 void* pvAspect,
1401 DVTARGETDEVICE* ptd,
1402 HDC hdcTargetDev,
1403 HDC hdcDraw,
1404 LPCRECTL lprcBounds,
1405 LPCRECTL lprcWBounds,
1406 IVO_ContCallback pfnContinue,
1407 DWORD dwContinue)
1409 PresentationDataHeader presData;
1410 HMETAFILE presMetafile = 0;
1411 HRESULT hres;
1413 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1415 TRACE(ole,"(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1416 iface,
1417 dwDrawAspect,
1418 lindex,
1419 pvAspect,
1420 hdcTargetDev,
1421 hdcDraw,
1422 lprcBounds,
1423 lprcWBounds,
1424 pfnContinue,
1425 dwContinue);
1428 * Sanity check
1430 if (lprcBounds==NULL)
1431 return E_INVALIDARG;
1434 * First, we need to retrieve the dimensions of the
1435 * image in the metafile.
1437 hres = DataCache_ReadPresentationData(this,
1438 dwDrawAspect,
1439 &presData);
1441 if (FAILED(hres))
1442 return hres;
1445 * Then, we can extract the metafile itself from the cached
1446 * data.
1448 presMetafile = DataCache_ReadPresMetafile(this,
1449 dwDrawAspect);
1452 * If we have a metafile, just draw baby...
1453 * We have to be careful not to modify the state of the
1454 * DC.
1456 if (presMetafile!=0)
1458 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1459 SIZE oldWindowExt;
1460 SIZE oldViewportExt;
1461 POINT oldViewportOrg;
1463 SetWindowExtEx(hdcDraw,
1464 presData.objectExtentX,
1465 presData.objectExtentY,
1466 &oldWindowExt);
1468 SetViewportExtEx(hdcDraw,
1469 lprcBounds->right - lprcBounds->left,
1470 lprcBounds->bottom - lprcBounds->top,
1471 &oldViewportExt);
1473 SetViewportOrgEx(hdcDraw,
1474 lprcBounds->left,
1475 lprcBounds->top,
1476 &oldViewportOrg);
1478 PlayMetaFile(hdcDraw, presMetafile);
1480 SetWindowExtEx(hdcDraw,
1481 oldWindowExt.cx,
1482 oldWindowExt.cy,
1483 NULL);
1485 SetViewportExtEx(hdcDraw,
1486 oldViewportExt.cx,
1487 oldViewportExt.cy,
1488 NULL);
1490 SetViewportOrgEx(hdcDraw,
1491 oldViewportOrg.x,
1492 oldViewportOrg.y,
1493 NULL);
1495 SetMapMode(hdcDraw, prevMapMode);
1497 DeleteMetaFile(presMetafile);
1500 return S_OK;
1503 static HRESULT WINAPI DataCache_GetColorSet(
1504 IViewObject2* iface,
1505 DWORD dwDrawAspect,
1506 LONG lindex,
1507 void* pvAspect,
1508 DVTARGETDEVICE* ptd,
1509 HDC hicTargetDevice,
1510 LOGPALETTE** ppColorSet)
1512 FIXME(ole,"stub\n");
1513 return E_NOTIMPL;
1516 static HRESULT WINAPI DataCache_Freeze(
1517 IViewObject2* iface,
1518 DWORD dwDrawAspect,
1519 LONG lindex,
1520 void* pvAspect,
1521 DWORD* pdwFreeze)
1523 FIXME(ole,"stub\n");
1524 return E_NOTIMPL;
1527 static HRESULT WINAPI DataCache_Unfreeze(
1528 IViewObject2* iface,
1529 DWORD dwFreeze)
1531 FIXME(ole,"stub\n");
1532 return E_NOTIMPL;
1535 /************************************************************************
1536 * DataCache_SetAdvise (IViewObject2)
1538 * This sets-up an advisory sink with the data cache. When the object's
1539 * view changes, this sink is called.
1541 * See Windows documentation for more details on IViewObject2 methods.
1543 static HRESULT WINAPI DataCache_SetAdvise(
1544 IViewObject2* iface,
1545 DWORD aspects,
1546 DWORD advf,
1547 IAdviseSink* pAdvSink)
1549 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1551 TRACE(ole,"(%p, %lx, %lx, %p)\n", iface, aspects, advf, pAdvSink);
1554 * A call to this function removes the previous sink
1556 if (this->sinkInterface != NULL)
1558 IAdviseSink_Release(this->sinkInterface);
1559 this->sinkInterface = NULL;
1560 this->sinkAspects = 0;
1561 this->sinkAdviseFlag = 0;
1565 * Now, setup the new one.
1567 if (pAdvSink!=NULL)
1569 this->sinkInterface = pAdvSink;
1570 this->sinkAspects = aspects;
1571 this->sinkAdviseFlag = advf;
1573 IAdviseSink_AddRef(this->sinkInterface);
1577 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1578 * sink immediately.
1580 if (advf & ADVF_PRIMEFIRST)
1582 DataCache_FireOnViewChange(this,
1583 DVASPECT_CONTENT,
1584 -1);
1587 return S_OK;
1590 /************************************************************************
1591 * DataCache_GetAdvise (IViewObject2)
1593 * This method queries the current state of the advise sink
1594 * installed on the data cache.
1596 * See Windows documentation for more details on IViewObject2 methods.
1598 static HRESULT WINAPI DataCache_GetAdvise(
1599 IViewObject2* iface,
1600 DWORD* pAspects,
1601 DWORD* pAdvf,
1602 IAdviseSink** ppAdvSink)
1604 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1606 TRACE(ole,"(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink);
1609 * Just copy all the requested values.
1611 if (pAspects!=NULL)
1612 *pAspects = this->sinkAspects;
1614 if (pAdvf!=NULL)
1615 *pAdvf = this->sinkAdviseFlag;
1617 if (ppAdvSink!=NULL)
1619 IAdviseSink_QueryInterface(this->sinkInterface,
1620 &IID_IAdviseSink,
1621 (void**)ppAdvSink);
1624 return S_OK;
1627 /************************************************************************
1628 * DataCache_GetExtent (IViewObject2)
1630 * This method retrieves the "natural" size of this cached object.
1632 * See Windows documentation for more details on IViewObject2 methods.
1634 static HRESULT WINAPI DataCache_GetExtent(
1635 IViewObject2* iface,
1636 DWORD dwDrawAspect,
1637 LONG lindex,
1638 DVTARGETDEVICE* ptd,
1639 LPSIZEL lpsizel)
1641 PresentationDataHeader presData;
1642 HRESULT hres = E_FAIL;
1644 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1646 TRACE(ole, "(%p, %lx, %ld, %p, %p)\n",
1647 iface, dwDrawAspect, lindex, ptd, lpsizel);
1650 * Sanity check
1652 if (lpsizel==NULL)
1653 return E_POINTER;
1656 * Initialize the out parameter.
1658 lpsizel->cx = 0;
1659 lpsizel->cy = 0;
1662 * This flag should be set to -1.
1664 if (lindex!=-1)
1665 FIXME(ole, "Unimplemented flag lindex = %ld\n", lindex);
1668 * Right now, we suport only the callback from
1669 * the default handler.
1671 if (ptd!=NULL)
1672 FIXME(ole, "Unimplemented ptd = %p\n", ptd);
1675 * Get the presentation information from the
1676 * cache.
1678 hres = DataCache_ReadPresentationData(this,
1679 dwDrawAspect,
1680 &presData);
1682 if (SUCCEEDED(hres))
1684 lpsizel->cx = presData.objectExtentX;
1685 lpsizel->cy = presData.objectExtentY;
1689 * This method returns OLE_E_BLANK when it fails.
1691 if (FAILED(hres))
1692 hres = OLE_E_BLANK;
1694 return hres;
1698 /*********************************************************
1699 * Method implementation for the IOleCache2
1700 * part of the DataCache class.
1703 /************************************************************************
1704 * DataCache_IOleCache2_QueryInterface (IUnknown)
1706 * See Windows documentation for more details on IUnknown methods.
1708 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
1709 IOleCache2* iface,
1710 REFIID riid,
1711 void** ppvObject)
1713 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1715 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1718 /************************************************************************
1719 * DataCache_IOleCache2_AddRef (IUnknown)
1721 * See Windows documentation for more details on IUnknown methods.
1723 static ULONG WINAPI DataCache_IOleCache2_AddRef(
1724 IOleCache2* iface)
1726 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1728 return IUnknown_AddRef(this->outerUnknown);
1731 /************************************************************************
1732 * DataCache_IOleCache2_Release (IUnknown)
1734 * See Windows documentation for more details on IUnknown methods.
1736 static ULONG WINAPI DataCache_IOleCache2_Release(
1737 IOleCache2* iface)
1739 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1741 return IUnknown_Release(this->outerUnknown);
1744 static HRESULT WINAPI DataCache_Cache(
1745 IOleCache2* iface,
1746 FORMATETC* pformatetc,
1747 DWORD advf,
1748 DWORD* pdwConnection)
1750 FIXME(ole,"stub\n");
1751 return E_NOTIMPL;
1754 static HRESULT WINAPI DataCache_Uncache(
1755 IOleCache2* iface,
1756 DWORD dwConnection)
1758 FIXME(ole,"stub\n");
1759 return E_NOTIMPL;
1762 static HRESULT WINAPI DataCache_EnumCache(
1763 IOleCache2* iface,
1764 IEnumSTATDATA** ppenumSTATDATA)
1766 FIXME(ole,"stub\n");
1767 return E_NOTIMPL;
1770 static HRESULT WINAPI DataCache_InitCache(
1771 IOleCache2* iface,
1772 IDataObject* pDataObject)
1774 FIXME(ole,"stub\n");
1775 return E_NOTIMPL;
1778 static HRESULT WINAPI DataCache_IOleCache2_SetData(
1779 IOleCache2* iface,
1780 FORMATETC* pformatetc,
1781 STGMEDIUM* pmedium,
1782 BOOL fRelease)
1784 FIXME(ole,"stub\n");
1785 return E_NOTIMPL;
1788 static HRESULT WINAPI DataCache_UpdateCache(
1789 IOleCache2* iface,
1790 LPDATAOBJECT pDataObject,
1791 DWORD grfUpdf,
1792 LPVOID pReserved)
1794 FIXME(ole,"stub\n");
1795 return E_NOTIMPL;
1798 static HRESULT WINAPI DataCache_DiscardCache(
1799 IOleCache2* iface,
1800 DWORD dwDiscardOptions)
1802 FIXME(ole,"stub\n");
1803 return E_NOTIMPL;
1807 /*********************************************************
1808 * Method implementation for the IOleCacheControl
1809 * part of the DataCache class.
1812 /************************************************************************
1813 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1815 * See Windows documentation for more details on IUnknown methods.
1817 static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
1818 IOleCacheControl* iface,
1819 REFIID riid,
1820 void** ppvObject)
1822 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1824 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1827 /************************************************************************
1828 * DataCache_IOleCacheControl_AddRef (IUnknown)
1830 * See Windows documentation for more details on IUnknown methods.
1832 static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
1833 IOleCacheControl* iface)
1835 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1837 return IUnknown_AddRef(this->outerUnknown);
1840 /************************************************************************
1841 * DataCache_IOleCacheControl_Release (IUnknown)
1843 * See Windows documentation for more details on IUnknown methods.
1845 static ULONG WINAPI DataCache_IOleCacheControl_Release(
1846 IOleCacheControl* iface)
1848 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1850 return IUnknown_Release(this->outerUnknown);
1853 static HRESULT WINAPI DataCache_OnRun(
1854 IOleCacheControl* iface,
1855 LPDATAOBJECT pDataObject)
1857 FIXME(ole,"stub\n");
1858 return E_NOTIMPL;
1861 static HRESULT WINAPI DataCache_OnStop(
1862 IOleCacheControl* iface)
1864 FIXME(ole,"stub\n");
1865 return E_NOTIMPL;