On NE process creation, move major part of NE EXE module loading and
[wine.git] / ole / datacache.c
blobed461d67dcf0df6f29c7ab13f2d961848e7e579e
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 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
358 DataCache_NDIUnknown_QueryInterface,
359 DataCache_NDIUnknown_AddRef,
360 DataCache_NDIUnknown_Release
363 static ICOM_VTABLE(IDataObject) DataCache_IDataObject_VTable =
365 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
366 DataCache_IDataObject_QueryInterface,
367 DataCache_IDataObject_AddRef,
368 DataCache_IDataObject_Release,
369 DataCache_GetData,
370 DataCache_GetDataHere,
371 DataCache_QueryGetData,
372 DataCache_GetCanonicalFormatEtc,
373 DataCache_IDataObject_SetData,
374 DataCache_EnumFormatEtc,
375 DataCache_DAdvise,
376 DataCache_DUnadvise,
377 DataCache_EnumDAdvise
380 static ICOM_VTABLE(IPersistStorage) DataCache_IPersistStorage_VTable =
382 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
383 DataCache_IPersistStorage_QueryInterface,
384 DataCache_IPersistStorage_AddRef,
385 DataCache_IPersistStorage_Release,
386 DataCache_GetClassID,
387 DataCache_IsDirty,
388 DataCache_InitNew,
389 DataCache_Load,
390 DataCache_Save,
391 DataCache_SaveCompleted,
392 DataCache_HandsOffStorage
395 static ICOM_VTABLE(IViewObject2) DataCache_IViewObject2_VTable =
397 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
398 DataCache_IViewObject2_QueryInterface,
399 DataCache_IViewObject2_AddRef,
400 DataCache_IViewObject2_Release,
401 DataCache_Draw,
402 DataCache_GetColorSet,
403 DataCache_Freeze,
404 DataCache_Unfreeze,
405 DataCache_SetAdvise,
406 DataCache_GetAdvise,
407 DataCache_GetExtent
410 static ICOM_VTABLE(IOleCache2) DataCache_IOleCache2_VTable =
412 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
413 DataCache_IOleCache2_QueryInterface,
414 DataCache_IOleCache2_AddRef,
415 DataCache_IOleCache2_Release,
416 DataCache_Cache,
417 DataCache_Uncache,
418 DataCache_EnumCache,
419 DataCache_InitCache,
420 DataCache_IOleCache2_SetData,
421 DataCache_UpdateCache,
422 DataCache_DiscardCache
425 static ICOM_VTABLE(IOleCacheControl) DataCache_IOleCacheControl_VTable =
427 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
428 DataCache_IOleCacheControl_QueryInterface,
429 DataCache_IOleCacheControl_AddRef,
430 DataCache_IOleCacheControl_Release,
431 DataCache_OnRun,
432 DataCache_OnStop
435 /******************************************************************************
436 * CreateDataCache [OLE32.54]
438 HRESULT WINAPI CreateDataCache(
439 LPUNKNOWN pUnkOuter,
440 REFCLSID rclsid,
441 REFIID riid,
442 LPVOID* ppvObj)
444 DataCache* newCache = NULL;
445 HRESULT hr = S_OK;
446 char xclsid[50];
447 char xriid[50];
449 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
450 WINE_StringFromCLSID((LPCLSID)riid,xriid);
452 TRACE(ole, "(%s, %p, %s, %p)\n", xclsid, pUnkOuter, xriid, ppvObj);
455 * Sanity check
457 if (ppvObj==0)
458 return E_POINTER;
460 *ppvObj = 0;
463 * If this cache is constructed for aggregation, make sure
464 * the caller is requesting the IUnknown interface.
465 * This is necessary because it's the only time the non-delegating
466 * IUnknown pointer can be returned to the outside.
468 if ( (pUnkOuter!=NULL) &&
469 (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) )
470 return CLASS_E_NOAGGREGATION;
473 * Try to construct a new instance of the class.
475 newCache = DataCache_Construct(rclsid,
476 pUnkOuter);
478 if (newCache == 0)
479 return E_OUTOFMEMORY;
482 * Make sure it supports the interface required by the caller.
484 hr = IUnknown_QueryInterface((IUnknown*)&(newCache->lpvtbl2), riid, ppvObj);
487 * Release the reference obtained in the constructor. If
488 * the QueryInterface was unsuccessful, it will free the class.
490 IUnknown_Release((IUnknown*)&(newCache->lpvtbl2));
492 return hr;
495 /*********************************************************
496 * Method implementation for DataCache class.
498 static DataCache* DataCache_Construct(
499 REFCLSID clsid,
500 LPUNKNOWN pUnkOuter)
502 DataCache* newObject = 0;
505 * Allocate space for the object.
507 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DataCache));
509 if (newObject==0)
510 return newObject;
513 * Initialize the virtual function table.
515 newObject->lpvtbl1 = &DataCache_IDataObject_VTable;
516 newObject->lpvtbl2 = &DataCache_NDIUnknown_VTable;
517 newObject->lpvtbl3 = &DataCache_IPersistStorage_VTable;
518 newObject->lpvtbl4 = &DataCache_IViewObject2_VTable;
519 newObject->lpvtbl5 = &DataCache_IOleCache2_VTable;
520 newObject->lpvtbl6 = &DataCache_IOleCacheControl_VTable;
523 * Start with one reference count. The caller of this function
524 * must release the interface pointer when it is done.
526 newObject->ref = 1;
529 * Initialize the outer unknown
530 * We don't keep a reference on the outer unknown since, the way
531 * aggregation works, our lifetime is at least as large as it's
532 * lifetime.
534 if (pUnkOuter==NULL)
535 pUnkOuter = (IUnknown*)&(newObject->lpvtbl2);
537 newObject->outerUnknown = pUnkOuter;
540 * Initialize the other members of the structure.
542 newObject->presentationStorage = NULL;
543 newObject->sinkAspects = 0;
544 newObject->sinkAdviseFlag = 0;
545 newObject->sinkInterface = 0;
547 return newObject;
550 static void DataCache_Destroy(
551 DataCache* ptrToDestroy)
553 TRACE(ole, "()\n");
555 if (ptrToDestroy->sinkInterface != NULL)
557 IAdviseSink_Release(ptrToDestroy->sinkInterface);
558 ptrToDestroy->sinkInterface = NULL;
561 if (ptrToDestroy->presentationStorage != NULL)
563 IStorage_Release(ptrToDestroy->presentationStorage);
564 ptrToDestroy->presentationStorage = NULL;
568 * Free the datacache pointer.
570 HeapFree(GetProcessHeap(), 0, ptrToDestroy);
573 /************************************************************************
574 * DataCache_ReadPresentationData
576 * This method will read information for the requested presentation
577 * into the given structure.
579 * Param:
580 * this - Pointer to the DataCache object
581 * drawAspect - The aspect of the object that we wish to draw.
582 * header - The structure containing information about this
583 * aspect of the object.
585 static HRESULT DataCache_ReadPresentationData(
586 DataCache* this,
587 DWORD drawAspect,
588 PresentationDataHeader* header)
590 IStream* presStream = NULL;
591 OLECHAR streamName[20];
592 HRESULT hres;
595 * Get the name for the presentation stream.
597 hres = DataCache_FindPresStreamName(
598 this,
599 drawAspect,
600 streamName);
602 if (FAILED(hres))
603 return hres;
606 * Open the stream and read the header.
608 hres = IStorage_OpenStream(
609 this->presentationStorage,
610 streamName,
611 NULL,
612 STGM_READ | STGM_SHARE_EXCLUSIVE,
614 &presStream);
616 if (FAILED(hres))
617 return hres;
619 hres = IStream_Read(
620 presStream,
621 header,
622 sizeof(PresentationDataHeader),
623 NULL);
626 * Cleanup.
628 IStream_Release(presStream);
631 * We don't want to propagate any other error
632 * code than a failure.
634 if (hres!=S_OK)
635 hres = E_FAIL;
637 return hres;
640 /************************************************************************
641 * DataCache_FireOnViewChange
643 * This method will fire an OnViewChange notification to the advise
644 * sink registered with the datacache.
646 * See IAdviseSink::OnViewChange for more details.
648 static void DataCache_FireOnViewChange(
649 DataCache* this,
650 DWORD aspect,
651 LONG lindex)
653 TRACE(ole, "(%p, %lx, %ld)\n", this, aspect, lindex);
656 * The sink supplies a filter when it registers
657 * we make sure we only send the notifications when that
658 * filter matches.
660 if ((this->sinkAspects & aspect) != 0)
662 if (this->sinkInterface != NULL)
664 IAdviseSink_OnViewChange(this->sinkInterface,
665 aspect,
666 lindex);
669 * Some sinks want to be unregistered automatically when
670 * the first notification goes out.
672 if ( (this->sinkAdviseFlag & ADVF_ONLYONCE) != 0)
674 IAdviseSink_Release(this->sinkInterface);
676 this->sinkInterface = NULL;
677 this->sinkAspects = 0;
678 this->sinkAdviseFlag = 0;
684 /************************************************************************
685 * DataCache_ReadPresentationData
687 * This method will read information for the requested presentation
688 * into the given structure.
690 * Param:
691 * this - Pointer to the DataCache object
692 * drawAspect - The aspect of the object that we wish to draw.
693 * header - The structure containing information about this
694 * aspect of the object.
696 * NOTE:
697 * This method only supports the DVASPECT_CONTENT aspect.
699 static HRESULT DataCache_FindPresStreamName(
700 DataCache* this,
701 DWORD drawAspect,
702 OLECHAR* buffer)
704 OLECHAR name[]={ 2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
706 if (drawAspect!=DVASPECT_CONTENT)
707 return E_FAIL;
709 memcpy(buffer, name, sizeof(name));
711 return S_OK;
714 /************************************************************************
715 * DataCache_ReadPresentationData
717 * This method will read information for the requested presentation
718 * into the given structure.
720 * Param:
721 * this - Pointer to the DataCache object
722 * drawAspect - The aspect of the object that we wish to draw.
724 * Returns:
725 * This method returns a metafile handle if it is successful.
726 * it will return 0 if not.
728 static HMETAFILE DataCache_ReadPresMetafile(
729 DataCache* this,
730 DWORD drawAspect)
732 LARGE_INTEGER offset;
733 IStream* presStream = NULL;
734 OLECHAR streamName[20];
735 HRESULT hres;
736 void* metafileBits;
737 STATSTG streamInfo;
738 HMETAFILE newMetafile = 0;
741 * Get the name for the presentation stream.
743 hres = DataCache_FindPresStreamName(
744 this,
745 drawAspect,
746 streamName);
748 if (FAILED(hres))
749 return hres;
752 * Open the stream and read the header.
754 hres = IStorage_OpenStream(
755 this->presentationStorage,
756 streamName,
757 NULL,
758 STGM_READ | STGM_SHARE_EXCLUSIVE,
760 &presStream);
762 if (FAILED(hres))
763 return hres;
766 * Get the size of the stream.
768 hres = IStream_Stat(presStream,
769 &streamInfo,
770 STATFLAG_NONAME);
773 * Skip the header
775 offset.HighPart = 0;
776 offset.LowPart = sizeof(PresentationDataHeader);
778 hres = IStream_Seek(
779 presStream,
780 offset,
781 STREAM_SEEK_SET,
782 NULL);
785 * Allocate a buffer for the metafile bits.
787 metafileBits = HeapAlloc(GetProcessHeap(),
789 streamInfo.cbSize.LowPart);
792 * Read the metafile bits.
794 hres = IStream_Read(
795 presStream,
796 metafileBits,
797 streamInfo.cbSize.LowPart,
798 NULL);
801 * Create a metafile with those bits.
803 if (SUCCEEDED(hres))
805 newMetafile = SetMetaFileBitsEx(streamInfo.cbSize.LowPart, metafileBits);
809 * Cleanup.
811 HeapFree(GetProcessHeap(), 0, metafileBits);
812 IStream_Release(presStream);
814 if (newMetafile==0)
815 hres = E_FAIL;
817 return newMetafile;
820 /*********************************************************
821 * Method implementation for the non delegating IUnknown
822 * part of the DataCache class.
825 /************************************************************************
826 * DataCache_NDIUnknown_QueryInterface (IUnknown)
828 * See Windows documentation for more details on IUnknown methods.
830 * This version of QueryInterface will not delegate it's implementation
831 * to the outer unknown.
833 static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
834 IUnknown* iface,
835 REFIID riid,
836 void** ppvObject)
838 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
841 * Perform a sanity check on the parameters.
843 if ( (this==0) || (ppvObject==0) )
844 return E_INVALIDARG;
847 * Initialize the return parameter.
849 *ppvObject = 0;
852 * Compare the riid with the interface IDs implemented by this object.
854 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
856 *ppvObject = iface;
858 else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0)
860 *ppvObject = (IDataObject*)&(this->lpvtbl1);
862 else if ( (memcmp(&IID_IPersistStorage, riid, sizeof(IID_IPersistStorage)) == 0) ||
863 (memcmp(&IID_IPersist, riid, sizeof(IID_IPersist)) == 0) )
865 *ppvObject = (IPersistStorage*)&(this->lpvtbl3);
867 else if ( (memcmp(&IID_IViewObject, riid, sizeof(IID_IViewObject)) == 0) ||
868 (memcmp(&IID_IViewObject2, riid, sizeof(IID_IViewObject2)) == 0) )
870 *ppvObject = (IViewObject2*)&(this->lpvtbl4);
872 else if ( (memcmp(&IID_IOleCache, riid, sizeof(IID_IOleCache)) == 0) ||
873 (memcmp(&IID_IOleCache2, riid, sizeof(IID_IOleCache2)) == 0) )
875 *ppvObject = (IOleCache2*)&(this->lpvtbl5);
877 else if (memcmp(&IID_IOleCacheControl, riid, sizeof(IID_IOleCacheControl)) == 0)
879 *ppvObject = (IOleCacheControl*)&(this->lpvtbl6);
883 * Check that we obtained an interface.
885 if ((*ppvObject)==0)
887 char clsid[50];
889 WINE_StringFromCLSID((LPCLSID)riid,clsid);
891 WARN(ole,
892 "() : asking for un supported interface %s\n",
893 clsid);
895 return E_NOINTERFACE;
899 * Query Interface always increases the reference count by one when it is
900 * successful.
902 IUnknown_AddRef((IUnknown*)*ppvObject);
904 return S_OK;;
907 /************************************************************************
908 * DataCache_NDIUnknown_AddRef (IUnknown)
910 * See Windows documentation for more details on IUnknown methods.
912 * This version of QueryInterface will not delegate it's implementation
913 * to the outer unknown.
915 static ULONG WINAPI DataCache_NDIUnknown_AddRef(
916 IUnknown* iface)
918 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
920 this->ref++;
922 return this->ref;
925 /************************************************************************
926 * DataCache_NDIUnknown_Release (IUnknown)
928 * See Windows documentation for more details on IUnknown methods.
930 * This version of QueryInterface will not delegate it's implementation
931 * to the outer unknown.
933 static ULONG WINAPI DataCache_NDIUnknown_Release(
934 IUnknown* iface)
936 _ICOM_THIS_From_NDIUnknown(DataCache, iface);
939 * Decrease the reference count on this object.
941 this->ref--;
944 * If the reference count goes down to 0, perform suicide.
946 if (this->ref==0)
948 DataCache_Destroy(this);
950 return 0;
953 return this->ref;
956 /*********************************************************
957 * Method implementation for the IDataObject
958 * part of the DataCache class.
961 /************************************************************************
962 * DataCache_IDataObject_QueryInterface (IUnknown)
964 * See Windows documentation for more details on IUnknown methods.
966 static HRESULT WINAPI DataCache_IDataObject_QueryInterface(
967 IDataObject* iface,
968 REFIID riid,
969 void** ppvObject)
971 _ICOM_THIS_From_IDataObject(DataCache, iface);
973 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
976 /************************************************************************
977 * DataCache_IDataObject_AddRef (IUnknown)
979 * See Windows documentation for more details on IUnknown methods.
981 static ULONG WINAPI DataCache_IDataObject_AddRef(
982 IDataObject* iface)
984 _ICOM_THIS_From_IDataObject(DataCache, iface);
986 return IUnknown_AddRef(this->outerUnknown);
989 /************************************************************************
990 * DataCache_IDataObject_Release (IUnknown)
992 * See Windows documentation for more details on IUnknown methods.
994 static ULONG WINAPI DataCache_IDataObject_Release(
995 IDataObject* iface)
997 _ICOM_THIS_From_IDataObject(DataCache, iface);
999 return IUnknown_Release(this->outerUnknown);
1002 static HRESULT WINAPI DataCache_GetData(
1003 IDataObject* iface,
1004 LPFORMATETC pformatetcIn,
1005 STGMEDIUM* pmedium)
1007 FIXME(ole,"stub\n");
1008 return E_NOTIMPL;
1011 static HRESULT WINAPI DataCache_GetDataHere(
1012 IDataObject* iface,
1013 LPFORMATETC pformatetc,
1014 STGMEDIUM* pmedium)
1016 FIXME(ole,"stub\n");
1017 return E_NOTIMPL;
1020 static HRESULT WINAPI DataCache_QueryGetData(
1021 IDataObject* iface,
1022 LPFORMATETC pformatetc)
1024 FIXME(ole,"stub\n");
1025 return E_NOTIMPL;
1028 /************************************************************************
1029 * DataCache_EnumFormatEtc (IDataObject)
1031 * The data cache doesn't implement this method.
1033 * See Windows documentation for more details on IDataObject methods.
1035 static HRESULT WINAPI DataCache_GetCanonicalFormatEtc(
1036 IDataObject* iface,
1037 LPFORMATETC pformatectIn,
1038 LPFORMATETC pformatetcOut)
1040 TRACE(ole,"()\n");
1041 return E_NOTIMPL;
1044 /************************************************************************
1045 * DataCache_IDataObject_SetData (IDataObject)
1047 * This method is delegated to the IOleCache2 implementation.
1049 * See Windows documentation for more details on IDataObject methods.
1051 static HRESULT WINAPI DataCache_IDataObject_SetData(
1052 IDataObject* iface,
1053 LPFORMATETC pformatetc,
1054 STGMEDIUM* pmedium,
1055 BOOL fRelease)
1057 IOleCache2* oleCache = NULL;
1058 HRESULT hres;
1060 TRACE(ole,"(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
1062 hres = IDataObject_QueryInterface(iface, &IID_IOleCache2, (void**)&oleCache);
1064 if (FAILED(hres))
1065 return E_UNEXPECTED;
1067 hres = IOleCache2_SetData(oleCache, pformatetc, pmedium, fRelease);
1069 IOleCache2_Release(oleCache);
1071 return hres;;
1074 /************************************************************************
1075 * DataCache_EnumFormatEtc (IDataObject)
1077 * The data cache doesn't implement this method.
1079 * See Windows documentation for more details on IDataObject methods.
1081 static HRESULT WINAPI DataCache_EnumFormatEtc(
1082 IDataObject* iface,
1083 DWORD dwDirection,
1084 IEnumFORMATETC** ppenumFormatEtc)
1086 TRACE(ole,"()\n");
1087 return E_NOTIMPL;
1090 /************************************************************************
1091 * DataCache_DAdvise (IDataObject)
1093 * The data cache doesn't support connections.
1095 * See Windows documentation for more details on IDataObject methods.
1097 static HRESULT WINAPI DataCache_DAdvise(
1098 IDataObject* iface,
1099 FORMATETC* pformatetc,
1100 DWORD advf,
1101 IAdviseSink* pAdvSink,
1102 DWORD* pdwConnection)
1104 TRACE(ole,"()\n");
1105 return OLE_E_ADVISENOTSUPPORTED;
1108 /************************************************************************
1109 * DataCache_DUnadvise (IDataObject)
1111 * The data cache doesn't support connections.
1113 * See Windows documentation for more details on IDataObject methods.
1115 static HRESULT WINAPI DataCache_DUnadvise(
1116 IDataObject* iface,
1117 DWORD dwConnection)
1119 TRACE(ole,"()\n");
1120 return OLE_E_NOCONNECTION;
1123 /************************************************************************
1124 * DataCache_EnumDAdvise (IDataObject)
1126 * The data cache doesn't support connections.
1128 * See Windows documentation for more details on IDataObject methods.
1130 static HRESULT WINAPI DataCache_EnumDAdvise(
1131 IDataObject* iface,
1132 IEnumSTATDATA** ppenumAdvise)
1134 TRACE(ole,"()\n");
1135 return OLE_E_ADVISENOTSUPPORTED;
1138 /*********************************************************
1139 * Method implementation for the IDataObject
1140 * part of the DataCache class.
1143 /************************************************************************
1144 * DataCache_IPersistStorage_QueryInterface (IUnknown)
1146 * See Windows documentation for more details on IUnknown methods.
1148 static HRESULT WINAPI DataCache_IPersistStorage_QueryInterface(
1149 IPersistStorage* iface,
1150 REFIID riid,
1151 void** ppvObject)
1153 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1155 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1158 /************************************************************************
1159 * DataCache_IPersistStorage_AddRef (IUnknown)
1161 * See Windows documentation for more details on IUnknown methods.
1163 static ULONG WINAPI DataCache_IPersistStorage_AddRef(
1164 IPersistStorage* iface)
1166 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1168 return IUnknown_AddRef(this->outerUnknown);
1171 /************************************************************************
1172 * DataCache_IPersistStorage_Release (IUnknown)
1174 * See Windows documentation for more details on IUnknown methods.
1176 static ULONG WINAPI DataCache_IPersistStorage_Release(
1177 IPersistStorage* iface)
1179 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1181 return IUnknown_Release(this->outerUnknown);
1184 /************************************************************************
1185 * DataCache_GetClassID (IPersistStorage)
1187 * The data cache doesn't implement this method.
1189 * See Windows documentation for more details on IPersistStorage methods.
1191 static HRESULT WINAPI DataCache_GetClassID(
1192 const IPersistStorage* iface,
1193 CLSID* pClassID)
1195 TRACE(ole,"(%p, %p)\n", iface, pClassID);
1196 return E_NOTIMPL;
1199 /************************************************************************
1200 * DataCache_IsDirty (IPersistStorage)
1202 * Until we actully connect to a running object and retrieve new
1203 * information to it, we never get dirty.
1205 * See Windows documentation for more details on IPersistStorage methods.
1207 static HRESULT WINAPI DataCache_IsDirty(
1208 IPersistStorage* iface)
1210 TRACE(ole,"(%p)\n", iface);
1212 return S_FALSE;
1215 /************************************************************************
1216 * DataCache_InitNew (IPersistStorage)
1218 * The data cache implementation of IPersistStorage_InitNew simply stores
1219 * the storage pointer.
1221 * See Windows documentation for more details on IPersistStorage methods.
1223 static HRESULT WINAPI DataCache_InitNew(
1224 IPersistStorage* iface,
1225 IStorage* pStg)
1227 TRACE(ole, "(%p, %p)\n", iface, pStg);
1229 return DataCache_Load(iface, pStg);
1232 /************************************************************************
1233 * DataCache_Load (IPersistStorage)
1235 * The data cache implementation of IPersistStorage_Load doesn't
1236 * actually load anything. Instead, it holds on to the storage pointer
1237 * and it will load the presentation information when the
1238 * IDataObject_GetData or IViewObject2_Draw methods are called.
1240 * See Windows documentation for more details on IPersistStorage methods.
1242 static HRESULT WINAPI DataCache_Load(
1243 IPersistStorage* iface,
1244 IStorage* pStg)
1246 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1248 TRACE(ole, "(%p, %p)\n", iface, pStg);
1250 if (this->presentationStorage != NULL)
1252 IStorage_Release(this->presentationStorage);
1255 this->presentationStorage = pStg;
1257 if (this->presentationStorage != NULL)
1259 IStorage_AddRef(this->presentationStorage);
1262 return S_OK;
1265 /************************************************************************
1266 * DataCache_Save (IPersistStorage)
1268 * Until we actully connect to a running object and retrieve new
1269 * information to it, we never have to save anything. However, it is
1270 * our responsability to copy the information when saving to a new
1271 * storage.
1273 * See Windows documentation for more details on IPersistStorage methods.
1275 static HRESULT WINAPI DataCache_Save(
1276 IPersistStorage* iface,
1277 IStorage* pStg,
1278 BOOL fSameAsLoad)
1280 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1282 TRACE(ole, "(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
1284 if ( (!fSameAsLoad) &&
1285 (this->presentationStorage!=NULL) )
1287 return IStorage_CopyTo(this->presentationStorage,
1289 NULL,
1290 NULL,
1291 pStg);
1294 return S_OK;
1297 /************************************************************************
1298 * DataCache_SaveCompleted (IPersistStorage)
1300 * This method is called to tell the cache to release the storage
1301 * pointer it's currentlu holding.
1303 * See Windows documentation for more details on IPersistStorage methods.
1305 static HRESULT WINAPI DataCache_SaveCompleted(
1306 IPersistStorage* iface,
1307 IStorage* pStgNew)
1309 TRACE(ole, "(%p, %p)\n", iface, pStgNew);
1312 * First, make sure we get our hands off any storage we have.
1314 DataCache_HandsOffStorage(iface);
1317 * Then, attach to the new storage.
1319 DataCache_Load(iface, pStgNew);
1321 return S_OK;
1324 /************************************************************************
1325 * DataCache_HandsOffStorage (IPersistStorage)
1327 * This method is called to tell the cache to release the storage
1328 * pointer it's currentlu holding.
1330 * See Windows documentation for more details on IPersistStorage methods.
1332 static HRESULT WINAPI DataCache_HandsOffStorage(
1333 IPersistStorage* iface)
1335 _ICOM_THIS_From_IPersistStorage(DataCache, iface);
1337 TRACE(ole,"(%p)\n", iface);
1339 if (this->presentationStorage != NULL)
1341 IStorage_Release(this->presentationStorage);
1342 this->presentationStorage = NULL;
1345 return S_OK;
1348 /*********************************************************
1349 * Method implementation for the IViewObject2
1350 * part of the DataCache class.
1353 /************************************************************************
1354 * DataCache_IViewObject2_QueryInterface (IUnknown)
1356 * See Windows documentation for more details on IUnknown methods.
1358 static HRESULT WINAPI DataCache_IViewObject2_QueryInterface(
1359 IViewObject2* iface,
1360 REFIID riid,
1361 void** ppvObject)
1363 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1365 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1368 /************************************************************************
1369 * DataCache_IViewObject2_AddRef (IUnknown)
1371 * See Windows documentation for more details on IUnknown methods.
1373 static ULONG WINAPI DataCache_IViewObject2_AddRef(
1374 IViewObject2* iface)
1376 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1378 return IUnknown_AddRef(this->outerUnknown);
1381 /************************************************************************
1382 * DataCache_IViewObject2_Release (IUnknown)
1384 * See Windows documentation for more details on IUnknown methods.
1386 static ULONG WINAPI DataCache_IViewObject2_Release(
1387 IViewObject2* iface)
1389 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1391 return IUnknown_Release(this->outerUnknown);
1394 /************************************************************************
1395 * DataCache_Draw (IViewObject2)
1397 * This method will draw the cached representation of the object
1398 * to the given device context.
1400 * See Windows documentation for more details on IViewObject2 methods.
1402 static HRESULT WINAPI DataCache_Draw(
1403 IViewObject2* iface,
1404 DWORD dwDrawAspect,
1405 LONG lindex,
1406 void* pvAspect,
1407 DVTARGETDEVICE* ptd,
1408 HDC hdcTargetDev,
1409 HDC hdcDraw,
1410 LPCRECTL lprcBounds,
1411 LPCRECTL lprcWBounds,
1412 IVO_ContCallback pfnContinue,
1413 DWORD dwContinue)
1415 PresentationDataHeader presData;
1416 HMETAFILE presMetafile = 0;
1417 HRESULT hres;
1419 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1421 TRACE(ole,"(%p, %lx, %ld, %p, %x, %x, %p, %p, %p, %lx)\n",
1422 iface,
1423 dwDrawAspect,
1424 lindex,
1425 pvAspect,
1426 hdcTargetDev,
1427 hdcDraw,
1428 lprcBounds,
1429 lprcWBounds,
1430 pfnContinue,
1431 dwContinue);
1434 * Sanity check
1436 if (lprcBounds==NULL)
1437 return E_INVALIDARG;
1440 * First, we need to retrieve the dimensions of the
1441 * image in the metafile.
1443 hres = DataCache_ReadPresentationData(this,
1444 dwDrawAspect,
1445 &presData);
1447 if (FAILED(hres))
1448 return hres;
1451 * Then, we can extract the metafile itself from the cached
1452 * data.
1454 presMetafile = DataCache_ReadPresMetafile(this,
1455 dwDrawAspect);
1458 * If we have a metafile, just draw baby...
1459 * We have to be careful not to modify the state of the
1460 * DC.
1462 if (presMetafile!=0)
1464 INT prevMapMode = SetMapMode(hdcDraw, MM_ANISOTROPIC);
1465 SIZE oldWindowExt;
1466 SIZE oldViewportExt;
1467 POINT oldViewportOrg;
1469 SetWindowExtEx(hdcDraw,
1470 presData.objectExtentX,
1471 presData.objectExtentY,
1472 &oldWindowExt);
1474 SetViewportExtEx(hdcDraw,
1475 lprcBounds->right - lprcBounds->left,
1476 lprcBounds->bottom - lprcBounds->top,
1477 &oldViewportExt);
1479 SetViewportOrgEx(hdcDraw,
1480 lprcBounds->left,
1481 lprcBounds->top,
1482 &oldViewportOrg);
1484 PlayMetaFile(hdcDraw, presMetafile);
1486 SetWindowExtEx(hdcDraw,
1487 oldWindowExt.cx,
1488 oldWindowExt.cy,
1489 NULL);
1491 SetViewportExtEx(hdcDraw,
1492 oldViewportExt.cx,
1493 oldViewportExt.cy,
1494 NULL);
1496 SetViewportOrgEx(hdcDraw,
1497 oldViewportOrg.x,
1498 oldViewportOrg.y,
1499 NULL);
1501 SetMapMode(hdcDraw, prevMapMode);
1503 DeleteMetaFile(presMetafile);
1506 return S_OK;
1509 static HRESULT WINAPI DataCache_GetColorSet(
1510 IViewObject2* iface,
1511 DWORD dwDrawAspect,
1512 LONG lindex,
1513 void* pvAspect,
1514 DVTARGETDEVICE* ptd,
1515 HDC hicTargetDevice,
1516 LOGPALETTE** ppColorSet)
1518 FIXME(ole,"stub\n");
1519 return E_NOTIMPL;
1522 static HRESULT WINAPI DataCache_Freeze(
1523 IViewObject2* iface,
1524 DWORD dwDrawAspect,
1525 LONG lindex,
1526 void* pvAspect,
1527 DWORD* pdwFreeze)
1529 FIXME(ole,"stub\n");
1530 return E_NOTIMPL;
1533 static HRESULT WINAPI DataCache_Unfreeze(
1534 IViewObject2* iface,
1535 DWORD dwFreeze)
1537 FIXME(ole,"stub\n");
1538 return E_NOTIMPL;
1541 /************************************************************************
1542 * DataCache_SetAdvise (IViewObject2)
1544 * This sets-up an advisory sink with the data cache. When the object's
1545 * view changes, this sink is called.
1547 * See Windows documentation for more details on IViewObject2 methods.
1549 static HRESULT WINAPI DataCache_SetAdvise(
1550 IViewObject2* iface,
1551 DWORD aspects,
1552 DWORD advf,
1553 IAdviseSink* pAdvSink)
1555 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1557 TRACE(ole,"(%p, %lx, %lx, %p)\n", iface, aspects, advf, pAdvSink);
1560 * A call to this function removes the previous sink
1562 if (this->sinkInterface != NULL)
1564 IAdviseSink_Release(this->sinkInterface);
1565 this->sinkInterface = NULL;
1566 this->sinkAspects = 0;
1567 this->sinkAdviseFlag = 0;
1571 * Now, setup the new one.
1573 if (pAdvSink!=NULL)
1575 this->sinkInterface = pAdvSink;
1576 this->sinkAspects = aspects;
1577 this->sinkAdviseFlag = advf;
1579 IAdviseSink_AddRef(this->sinkInterface);
1583 * When the ADVF_PRIMEFIRST flag is set, we have to advise the
1584 * sink immediately.
1586 if (advf & ADVF_PRIMEFIRST)
1588 DataCache_FireOnViewChange(this,
1589 DVASPECT_CONTENT,
1590 -1);
1593 return S_OK;
1596 /************************************************************************
1597 * DataCache_GetAdvise (IViewObject2)
1599 * This method queries the current state of the advise sink
1600 * installed on the data cache.
1602 * See Windows documentation for more details on IViewObject2 methods.
1604 static HRESULT WINAPI DataCache_GetAdvise(
1605 IViewObject2* iface,
1606 DWORD* pAspects,
1607 DWORD* pAdvf,
1608 IAdviseSink** ppAdvSink)
1610 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1612 TRACE(ole,"(%p, %p, %p, %p)\n", iface, pAspects, pAdvf, ppAdvSink);
1615 * Just copy all the requested values.
1617 if (pAspects!=NULL)
1618 *pAspects = this->sinkAspects;
1620 if (pAdvf!=NULL)
1621 *pAdvf = this->sinkAdviseFlag;
1623 if (ppAdvSink!=NULL)
1625 IAdviseSink_QueryInterface(this->sinkInterface,
1626 &IID_IAdviseSink,
1627 (void**)ppAdvSink);
1630 return S_OK;
1633 /************************************************************************
1634 * DataCache_GetExtent (IViewObject2)
1636 * This method retrieves the "natural" size of this cached object.
1638 * See Windows documentation for more details on IViewObject2 methods.
1640 static HRESULT WINAPI DataCache_GetExtent(
1641 IViewObject2* iface,
1642 DWORD dwDrawAspect,
1643 LONG lindex,
1644 DVTARGETDEVICE* ptd,
1645 LPSIZEL lpsizel)
1647 PresentationDataHeader presData;
1648 HRESULT hres = E_FAIL;
1650 _ICOM_THIS_From_IViewObject2(DataCache, iface);
1652 TRACE(ole, "(%p, %lx, %ld, %p, %p)\n",
1653 iface, dwDrawAspect, lindex, ptd, lpsizel);
1656 * Sanity check
1658 if (lpsizel==NULL)
1659 return E_POINTER;
1662 * Initialize the out parameter.
1664 lpsizel->cx = 0;
1665 lpsizel->cy = 0;
1668 * This flag should be set to -1.
1670 if (lindex!=-1)
1671 FIXME(ole, "Unimplemented flag lindex = %ld\n", lindex);
1674 * Right now, we suport only the callback from
1675 * the default handler.
1677 if (ptd!=NULL)
1678 FIXME(ole, "Unimplemented ptd = %p\n", ptd);
1681 * Get the presentation information from the
1682 * cache.
1684 hres = DataCache_ReadPresentationData(this,
1685 dwDrawAspect,
1686 &presData);
1688 if (SUCCEEDED(hres))
1690 lpsizel->cx = presData.objectExtentX;
1691 lpsizel->cy = presData.objectExtentY;
1695 * This method returns OLE_E_BLANK when it fails.
1697 if (FAILED(hres))
1698 hres = OLE_E_BLANK;
1700 return hres;
1704 /*********************************************************
1705 * Method implementation for the IOleCache2
1706 * part of the DataCache class.
1709 /************************************************************************
1710 * DataCache_IOleCache2_QueryInterface (IUnknown)
1712 * See Windows documentation for more details on IUnknown methods.
1714 static HRESULT WINAPI DataCache_IOleCache2_QueryInterface(
1715 IOleCache2* iface,
1716 REFIID riid,
1717 void** ppvObject)
1719 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1721 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1724 /************************************************************************
1725 * DataCache_IOleCache2_AddRef (IUnknown)
1727 * See Windows documentation for more details on IUnknown methods.
1729 static ULONG WINAPI DataCache_IOleCache2_AddRef(
1730 IOleCache2* iface)
1732 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1734 return IUnknown_AddRef(this->outerUnknown);
1737 /************************************************************************
1738 * DataCache_IOleCache2_Release (IUnknown)
1740 * See Windows documentation for more details on IUnknown methods.
1742 static ULONG WINAPI DataCache_IOleCache2_Release(
1743 IOleCache2* iface)
1745 _ICOM_THIS_From_IOleCache2(DataCache, iface);
1747 return IUnknown_Release(this->outerUnknown);
1750 static HRESULT WINAPI DataCache_Cache(
1751 IOleCache2* iface,
1752 FORMATETC* pformatetc,
1753 DWORD advf,
1754 DWORD* pdwConnection)
1756 FIXME(ole,"stub\n");
1757 return E_NOTIMPL;
1760 static HRESULT WINAPI DataCache_Uncache(
1761 IOleCache2* iface,
1762 DWORD dwConnection)
1764 FIXME(ole,"stub\n");
1765 return E_NOTIMPL;
1768 static HRESULT WINAPI DataCache_EnumCache(
1769 IOleCache2* iface,
1770 IEnumSTATDATA** ppenumSTATDATA)
1772 FIXME(ole,"stub\n");
1773 return E_NOTIMPL;
1776 static HRESULT WINAPI DataCache_InitCache(
1777 IOleCache2* iface,
1778 IDataObject* pDataObject)
1780 FIXME(ole,"stub\n");
1781 return E_NOTIMPL;
1784 static HRESULT WINAPI DataCache_IOleCache2_SetData(
1785 IOleCache2* iface,
1786 FORMATETC* pformatetc,
1787 STGMEDIUM* pmedium,
1788 BOOL fRelease)
1790 FIXME(ole,"stub\n");
1791 return E_NOTIMPL;
1794 static HRESULT WINAPI DataCache_UpdateCache(
1795 IOleCache2* iface,
1796 LPDATAOBJECT pDataObject,
1797 DWORD grfUpdf,
1798 LPVOID pReserved)
1800 FIXME(ole,"stub\n");
1801 return E_NOTIMPL;
1804 static HRESULT WINAPI DataCache_DiscardCache(
1805 IOleCache2* iface,
1806 DWORD dwDiscardOptions)
1808 FIXME(ole,"stub\n");
1809 return E_NOTIMPL;
1813 /*********************************************************
1814 * Method implementation for the IOleCacheControl
1815 * part of the DataCache class.
1818 /************************************************************************
1819 * DataCache_IOleCacheControl_QueryInterface (IUnknown)
1821 * See Windows documentation for more details on IUnknown methods.
1823 static HRESULT WINAPI DataCache_IOleCacheControl_QueryInterface(
1824 IOleCacheControl* iface,
1825 REFIID riid,
1826 void** ppvObject)
1828 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1830 return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
1833 /************************************************************************
1834 * DataCache_IOleCacheControl_AddRef (IUnknown)
1836 * See Windows documentation for more details on IUnknown methods.
1838 static ULONG WINAPI DataCache_IOleCacheControl_AddRef(
1839 IOleCacheControl* iface)
1841 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1843 return IUnknown_AddRef(this->outerUnknown);
1846 /************************************************************************
1847 * DataCache_IOleCacheControl_Release (IUnknown)
1849 * See Windows documentation for more details on IUnknown methods.
1851 static ULONG WINAPI DataCache_IOleCacheControl_Release(
1852 IOleCacheControl* iface)
1854 _ICOM_THIS_From_IOleCacheControl(DataCache, iface);
1856 return IUnknown_Release(this->outerUnknown);
1859 static HRESULT WINAPI DataCache_OnRun(
1860 IOleCacheControl* iface,
1861 LPDATAOBJECT pDataObject)
1863 FIXME(ole,"stub\n");
1864 return E_NOTIMPL;
1867 static HRESULT WINAPI DataCache_OnStop(
1868 IOleCacheControl* iface)
1870 FIXME(ole,"stub\n");
1871 return E_NOTIMPL;