ole32: The stream returned by StgStreamImpl_Clone should have one reference, so call...
[wine] / dlls / ole32 / tests / ole2.c
1 /*
2  * Object Linking and Embedding Tests
3  *
4  * Copyright 2005 Robert Shearman
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22 #define CONST_VTABLE
23
24 #include <stdarg.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "objbase.h"
29 #include "shlguid.h"
30
31 #include "wine/test.h"
32
33 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
34
35 static IPersistStorage OleObjectPersistStg;
36 static IOleCache *cache;
37 static IRunnableObject *runnable;
38
39 static const CLSID CLSID_WineTest =
40 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
41     0x9474ba1a,
42     0x258b,
43     0x490b,
44     {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
45 };
46
47 static char const * const *expected_method_list;
48
49 #define CHECK_EXPECTED_METHOD(method_name) \
50     do { \
51         trace("%s\n", method_name); \
52         ok(*expected_method_list != NULL, "Extra method %s called\n", method_name); \
53         if (*expected_method_list) \
54         { \
55             ok(!strcmp(*expected_method_list, method_name), "Expected %s to be called instead of %s\n", \
56                 *expected_method_list, method_name); \
57             expected_method_list++; \
58         } \
59     } while(0)
60
61 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
62 {
63     CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
64
65     *ppv = NULL;
66
67     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject))
68         *ppv = (void *)iface;
69     else if (IsEqualIID(riid, &IID_IPersistStorage))
70         *ppv = &OleObjectPersistStg;
71     else if (IsEqualIID(riid, &IID_IOleCache))
72         *ppv = cache;
73     else if (IsEqualIID(riid, &IID_IRunnableObject))
74         *ppv = runnable;
75
76     if(*ppv) {
77         IUnknown_AddRef((IUnknown*)*ppv);
78         return S_OK;
79     }
80
81     trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
82     return E_NOINTERFACE;
83 }
84
85 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
86 {
87     CHECK_EXPECTED_METHOD("OleObject_AddRef");
88     return 2;
89 }
90
91 static ULONG WINAPI OleObject_Release(IOleObject *iface)
92 {
93     CHECK_EXPECTED_METHOD("OleObject_Release");
94     return 1;
95 }
96
97 static HRESULT WINAPI OleObject_SetClientSite
98     (
99         IOleObject *iface,
100         IOleClientSite *pClientSite
101     )
102 {
103     CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
104     return S_OK;
105 }
106
107 static HRESULT WINAPI OleObject_GetClientSite
108     (
109         IOleObject *iface,
110         IOleClientSite **ppClientSite
111     )
112 {
113     CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
114     return E_NOTIMPL;
115 }
116
117 static HRESULT WINAPI OleObject_SetHostNames
118     (
119         IOleObject *iface,
120         LPCOLESTR szContainerApp,
121         LPCOLESTR szContainerObj
122     )
123 {
124     CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
125     return S_OK;
126 }
127
128 static HRESULT WINAPI OleObject_Close
129     (
130         IOleObject *iface,
131         DWORD dwSaveOption
132     )
133 {
134     CHECK_EXPECTED_METHOD("OleObject_Close");
135     return S_OK;
136 }
137
138 static HRESULT WINAPI OleObject_SetMoniker
139     (
140         IOleObject *iface,
141         DWORD dwWhichMoniker,
142         IMoniker *pmk
143     )
144 {
145     CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
146     return S_OK;
147 }
148
149 static HRESULT WINAPI OleObject_GetMoniker
150     (
151         IOleObject *iface,
152         DWORD dwAssign,
153         DWORD dwWhichMoniker,
154         IMoniker **ppmk
155     )
156 {
157     CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
158     return S_OK;
159 }
160
161 static HRESULT WINAPI OleObject_InitFromData
162     (
163         IOleObject *iface,
164         IDataObject *pDataObject,
165         BOOL fCreation,
166         DWORD dwReserved
167     )
168 {
169     CHECK_EXPECTED_METHOD("OleObject_InitFromData");
170     return S_OK;
171 }
172
173 static HRESULT WINAPI OleObject_GetClipboardData
174     (
175         IOleObject *iface,
176         DWORD dwReserved,
177         IDataObject **ppDataObject
178     )
179 {
180     CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
181     return E_NOTIMPL;
182 }
183
184 static HRESULT WINAPI OleObject_DoVerb
185     (
186         IOleObject *iface,
187         LONG iVerb,
188         LPMSG lpmsg,
189         IOleClientSite *pActiveSite,
190         LONG lindex,
191         HWND hwndParent,
192         LPCRECT lprcPosRect
193     )
194 {
195     CHECK_EXPECTED_METHOD("OleObject_DoVerb");
196     return S_OK;
197 }
198
199 static HRESULT WINAPI OleObject_EnumVerbs
200     (
201         IOleObject *iface,
202         IEnumOLEVERB **ppEnumOleVerb
203     )
204 {
205     CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
206     return E_NOTIMPL;
207 }
208
209 static HRESULT WINAPI OleObject_Update
210     (
211         IOleObject *iface
212     )
213 {
214     CHECK_EXPECTED_METHOD("OleObject_Update");
215     return S_OK;
216 }
217
218 static HRESULT WINAPI OleObject_IsUpToDate
219     (
220         IOleObject *iface
221     )
222 {
223     CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
224     return S_OK;
225 }
226
227 static HRESULT WINAPI OleObject_GetUserClassID
228 (
229     IOleObject *iface,
230     CLSID *pClsid
231 )
232 {
233     CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
234     return E_NOTIMPL;
235 }
236
237 static HRESULT WINAPI OleObject_GetUserType
238 (
239     IOleObject *iface,
240     DWORD dwFormOfType,
241     LPOLESTR *pszUserType
242 )
243 {
244     CHECK_EXPECTED_METHOD("OleObject_GetUserType");
245     return E_NOTIMPL;
246 }
247
248 static HRESULT WINAPI OleObject_SetExtent
249 (
250     IOleObject *iface,
251     DWORD dwDrawAspect,
252     SIZEL *psizel
253 )
254 {
255     CHECK_EXPECTED_METHOD("OleObject_SetExtent");
256     return S_OK;
257 }
258
259 static HRESULT WINAPI OleObject_GetExtent
260 (
261     IOleObject *iface,
262     DWORD dwDrawAspect,
263     SIZEL *psizel
264 )
265 {
266     CHECK_EXPECTED_METHOD("OleObject_GetExtent");
267     return E_NOTIMPL;
268 }
269
270 static HRESULT WINAPI OleObject_Advise
271 (
272     IOleObject *iface,
273     IAdviseSink *pAdvSink,
274     DWORD *pdwConnection
275 )
276 {
277     CHECK_EXPECTED_METHOD("OleObject_Advise");
278     return S_OK;
279 }
280
281 static HRESULT WINAPI OleObject_Unadvise
282 (
283     IOleObject *iface,
284     DWORD dwConnection
285 )
286 {
287     CHECK_EXPECTED_METHOD("OleObject_Unadvise");
288     return S_OK;
289 }
290
291 static HRESULT WINAPI OleObject_EnumAdvise
292 (
293     IOleObject *iface,
294     IEnumSTATDATA **ppenumAdvise
295 )
296 {
297     CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
298     return E_NOTIMPL;
299 }
300
301 static HRESULT WINAPI OleObject_GetMiscStatus
302 (
303     IOleObject *iface,
304     DWORD dwAspect,
305     DWORD *pdwStatus
306 )
307 {
308     CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
309     *pdwStatus = DVASPECT_CONTENT;
310     return S_OK;
311 }
312
313 static HRESULT WINAPI OleObject_SetColorScheme
314 (
315     IOleObject *iface,
316     LOGPALETTE *pLogpal
317 )
318 {
319     CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
320     return E_NOTIMPL;
321 }
322
323 static const IOleObjectVtbl OleObjectVtbl =
324 {
325     OleObject_QueryInterface,
326     OleObject_AddRef,
327     OleObject_Release,
328     OleObject_SetClientSite,
329     OleObject_GetClientSite,
330     OleObject_SetHostNames,
331     OleObject_Close,
332     OleObject_SetMoniker,
333     OleObject_GetMoniker,
334     OleObject_InitFromData,
335     OleObject_GetClipboardData,
336     OleObject_DoVerb,
337     OleObject_EnumVerbs,
338     OleObject_Update,
339     OleObject_IsUpToDate,
340     OleObject_GetUserClassID,
341     OleObject_GetUserType,
342     OleObject_SetExtent,
343     OleObject_GetExtent,
344     OleObject_Advise,
345     OleObject_Unadvise,
346     OleObject_EnumAdvise,
347     OleObject_GetMiscStatus,
348     OleObject_SetColorScheme
349 };
350
351 static IOleObject OleObject = { &OleObjectVtbl };
352
353 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv)
354 {
355     trace("OleObjectPersistStg_QueryInterface\n");
356     return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
357 }
358
359 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface)
360 {
361     CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
362     return 2;
363 }
364
365 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface)
366 {
367     CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
368     return 1;
369 }
370
371 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid)
372 {
373     CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
374     return E_NOTIMPL;
375 }
376
377 static HRESULT WINAPI OleObjectPersistStg_IsDirty
378 (
379     IPersistStorage *iface
380 )
381 {
382     CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
383     return S_OK;
384 }
385
386 static HRESULT WINAPI OleObjectPersistStg_InitNew
387 (
388     IPersistStorage *iface,
389     IStorage *pStg
390 )
391 {
392     CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
393     return S_OK;
394 }
395
396 static HRESULT WINAPI OleObjectPersistStg_Load
397 (
398     IPersistStorage *iface,
399     IStorage *pStg
400 )
401 {
402     CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
403     return S_OK;
404 }
405
406 static HRESULT WINAPI OleObjectPersistStg_Save
407 (
408     IPersistStorage *iface,
409     IStorage *pStgSave,
410     BOOL fSameAsLoad
411 )
412 {
413     CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
414     return S_OK;
415 }
416
417 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
418 (
419     IPersistStorage *iface,
420     IStorage *pStgNew
421 )
422 {
423     CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
424     return S_OK;
425 }
426
427 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
428 (
429     IPersistStorage *iface
430 )
431 {
432     CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
433     return S_OK;
434 }
435
436 static const IPersistStorageVtbl OleObjectPersistStgVtbl =
437 {
438     OleObjectPersistStg_QueryInterface,
439     OleObjectPersistStg_AddRef,
440     OleObjectPersistStg_Release,
441     OleObjectPersistStg_GetClassId,
442     OleObjectPersistStg_IsDirty,
443     OleObjectPersistStg_InitNew,
444     OleObjectPersistStg_Load,
445     OleObjectPersistStg_Save,
446     OleObjectPersistStg_SaveCompleted,
447     OleObjectPersistStg_HandsOffStorage
448 };
449
450 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl };
451
452 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv)
453 {
454     return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
455 }
456
457 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface)
458 {
459     CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
460     return 2;
461 }
462
463 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface)
464 {
465     CHECK_EXPECTED_METHOD("OleObjectCache_Release");
466     return 1;
467 }
468
469 static HRESULT WINAPI OleObjectCache_Cache
470 (
471     IOleCache *iface,
472     FORMATETC *pformatetc,
473     DWORD advf,
474     DWORD *pdwConnection
475 )
476 {
477     CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
478     return S_OK;
479 }
480
481 static HRESULT WINAPI OleObjectCache_Uncache
482 (
483     IOleCache *iface,
484     DWORD dwConnection
485 )
486 {
487     CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
488     return S_OK;
489 }
490
491 static HRESULT WINAPI OleObjectCache_EnumCache
492 (
493     IOleCache *iface,
494     IEnumSTATDATA **ppenumSTATDATA
495 )
496 {
497     CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
498     return S_OK;
499 }
500
501
502 static HRESULT WINAPI OleObjectCache_InitCache
503 (
504     IOleCache *iface,
505     IDataObject *pDataObject
506 )
507 {
508     CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
509     return S_OK;
510 }
511
512
513 static HRESULT WINAPI OleObjectCache_SetData
514 (
515     IOleCache *iface,
516     FORMATETC *pformatetc,
517     STGMEDIUM *pmedium,
518     BOOL fRelease
519 )
520 {
521     CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
522     return S_OK;
523 }
524
525
526 static const IOleCacheVtbl OleObjectCacheVtbl =
527 {
528     OleObjectCache_QueryInterface,
529     OleObjectCache_AddRef,
530     OleObjectCache_Release,
531     OleObjectCache_Cache,
532     OleObjectCache_Uncache,
533     OleObjectCache_EnumCache,
534     OleObjectCache_InitCache,
535     OleObjectCache_SetData
536 };
537
538 static IOleCache OleObjectCache = { &OleObjectCacheVtbl };
539
540 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
541 {
542     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
543     {
544         *ppv = iface;
545         IUnknown_AddRef(iface);
546         return S_OK;
547     }
548     *ppv = NULL;
549     return E_NOINTERFACE;
550 }
551
552 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface)
553 {
554     return 2;
555 }
556
557 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface)
558 {
559     return 1;
560 }
561
562 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv)
563 {
564     return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
565 }
566
567 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock)
568 {
569     return S_OK;
570 }
571
572 static const IClassFactoryVtbl OleObjectCFVtbl =
573 {
574     OleObjectCF_QueryInterface,
575     OleObjectCF_AddRef,
576     OleObjectCF_Release,
577     OleObjectCF_CreateInstance,
578     OleObjectCF_LockServer
579 };
580
581 static IClassFactory OleObjectCF = { &OleObjectCFVtbl };
582
583 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
584 {
585     return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
586 }
587
588 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface)
589 {
590     CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
591     return 2;
592 }
593
594 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface)
595 {
596     CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
597     return 1;
598 }
599
600 static HRESULT WINAPI OleObjectRunnable_GetRunningClass(
601     IRunnableObject *iface,
602     LPCLSID lpClsid)
603 {
604     CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
605     return E_NOTIMPL;
606 }
607
608 static HRESULT WINAPI OleObjectRunnable_Run(
609     IRunnableObject *iface,
610     LPBINDCTX pbc)
611 {
612     CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
613     return S_OK;
614 }
615
616 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface)
617 {
618     CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
619     return TRUE;
620 }
621
622 static HRESULT WINAPI OleObjectRunnable_LockRunning(
623     IRunnableObject *iface,
624     BOOL fLock,
625     BOOL fLastUnlockCloses)
626 {
627     CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
628     return S_OK;
629 }
630
631 static HRESULT WINAPI OleObjectRunnable_SetContainedObject(
632     IRunnableObject *iface,
633     BOOL fContained)
634 {
635     CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
636     return S_OK;
637 }
638
639 static const IRunnableObjectVtbl OleObjectRunnableVtbl =
640 {
641     OleObjectRunnable_QueryInterface,
642     OleObjectRunnable_AddRef,
643     OleObjectRunnable_Release,
644     OleObjectRunnable_GetRunningClass,
645     OleObjectRunnable_Run,
646     OleObjectRunnable_IsRunning,
647     OleObjectRunnable_LockRunning,
648     OleObjectRunnable_SetContainedObject
649 };
650
651 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl };
652
653 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
654
655 static void test_OleCreate(IStorage *pStorage)
656 {
657     HRESULT hr;
658     IOleObject *pObject;
659     FORMATETC formatetc;
660     static const char *methods_olerender_none[] =
661     {
662         "OleObject_QueryInterface",
663         "OleObject_AddRef",
664         "OleObject_QueryInterface",
665         "OleObjectPersistStg_AddRef",
666         "OleObjectPersistStg_InitNew",
667         "OleObjectPersistStg_Release",
668         "OleObject_Release",
669         NULL
670     };
671     static const char *methods_olerender_draw[] =
672     {
673         "OleObject_QueryInterface",
674         "OleObject_AddRef",
675         "OleObject_QueryInterface",
676         "OleObjectPersistStg_AddRef",
677         "OleObjectPersistStg_InitNew",
678         "OleObjectPersistStg_Release",
679         "OleObject_QueryInterface",
680         "OleObjectRunnable_AddRef",
681         "OleObjectRunnable_Run",
682         "OleObjectRunnable_Release",
683         "OleObject_QueryInterface",
684         "OleObjectCache_AddRef",
685         "OleObjectCache_Cache",
686         "OleObjectCache_Release",
687         "OleObject_Release",
688         NULL
689     };
690     static const char *methods_olerender_format[] =
691     {
692         "OleObject_QueryInterface",
693         "OleObject_AddRef",
694         "OleObject_QueryInterface",
695         "OleObject_AddRef",
696         "OleObject_GetMiscStatus",
697         "OleObject_QueryInterface",
698         "OleObjectPersistStg_AddRef",
699         "OleObjectPersistStg_InitNew",
700         "OleObjectPersistStg_Release",
701         "OleObject_SetClientSite",
702         "OleObject_Release",
703         "OleObject_QueryInterface",
704         "OleObjectRunnable_AddRef",
705         "OleObjectRunnable_Run",
706         "OleObjectRunnable_Release",
707         "OleObject_QueryInterface",
708         "OleObjectCache_AddRef",
709         "OleObjectCache_Cache",
710         "OleObjectCache_Release",
711         "OleObject_Release",
712         NULL
713     };
714     static const char *methods_olerender_asis[] =
715     {
716         "OleObject_QueryInterface",
717         "OleObject_AddRef",
718         "OleObject_QueryInterface",
719         "OleObjectPersistStg_AddRef",
720         "OleObjectPersistStg_InitNew",
721         "OleObjectPersistStg_Release",
722         "OleObject_Release",
723         NULL
724     };
725     static const char *methods_olerender_draw_no_runnable[] =
726     {
727         "OleObject_QueryInterface",
728         "OleObject_AddRef",
729         "OleObject_QueryInterface",
730         "OleObjectPersistStg_AddRef",
731         "OleObjectPersistStg_InitNew",
732         "OleObjectPersistStg_Release",
733         "OleObject_QueryInterface",
734         "OleObject_QueryInterface",
735         "OleObjectCache_AddRef",
736         "OleObjectCache_Cache",
737         "OleObjectCache_Release",
738         "OleObject_Release",
739         NULL
740     };
741     static const char *methods_olerender_draw_no_cache[] =
742     {
743         "OleObject_QueryInterface",
744         "OleObject_AddRef",
745         "OleObject_QueryInterface",
746         "OleObjectPersistStg_AddRef",
747         "OleObjectPersistStg_InitNew",
748         "OleObjectPersistStg_Release",
749         "OleObject_QueryInterface",
750         "OleObjectRunnable_AddRef",
751         "OleObjectRunnable_Run",
752         "OleObjectRunnable_Release",
753         "OleObject_QueryInterface",
754         "OleObject_Release",
755         NULL
756     };
757
758     runnable = &OleObjectRunnable;
759     cache = &OleObjectCache;
760     expected_method_list = methods_olerender_none;
761     trace("OleCreate with OLERENDER_NONE:\n");
762     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject);
763     ok_ole_success(hr, "OleCreate");
764     IOleObject_Release(pObject);
765     ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
766
767     expected_method_list = methods_olerender_draw;
768     trace("OleCreate with OLERENDER_DRAW:\n");
769     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
770     ok_ole_success(hr, "OleCreate");
771     IOleObject_Release(pObject);
772     ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
773
774     formatetc.cfFormat = CF_TEXT;
775     formatetc.ptd = NULL;
776     formatetc.dwAspect = DVASPECT_CONTENT;
777     formatetc.lindex = -1;
778     formatetc.tymed = TYMED_HGLOBAL;
779     expected_method_list = methods_olerender_format;
780     trace("OleCreate with OLERENDER_FORMAT:\n");
781     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject);
782     ok_ole_success(hr, "OleCreate");
783     IOleObject_Release(pObject);
784     ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
785
786     expected_method_list = methods_olerender_asis;
787     trace("OleCreate with OLERENDER_ASIS:\n");
788     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject);
789     ok_ole_success(hr, "OleCreate");
790     IOleObject_Release(pObject);
791     ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
792
793     runnable = NULL;
794     expected_method_list = methods_olerender_draw_no_runnable;
795     trace("OleCreate with OLERENDER_DRAW (no IOlObjectRunnable):\n");
796     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
797     ok_ole_success(hr, "OleCreate");
798     IOleObject_Release(pObject);
799     ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
800
801     runnable = &OleObjectRunnable;
802     cache = NULL;
803     expected_method_list = methods_olerender_draw_no_cache;
804     trace("OleCreate with OLERENDER_DRAW (no IOlObjectRunnable):\n");
805     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
806     ok_ole_success(hr, "OleCreate");
807     IOleObject_Release(pObject);
808     ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
809     trace("end\n");
810 }
811
812 static void test_OleLoad(IStorage *pStorage)
813 {
814     HRESULT hr;
815     IOleObject *pObject;
816
817     static const char *methods_oleload[] =
818     {
819         "OleObject_QueryInterface",
820         "OleObject_AddRef",
821         "OleObject_QueryInterface",
822         "OleObject_AddRef",
823         "OleObject_GetMiscStatus",
824         "OleObject_QueryInterface",
825         "OleObjectPersistStg_AddRef",
826         "OleObjectPersistStg_Load",
827         "OleObjectPersistStg_Release",
828         "OleObject_SetClientSite",
829         "OleObject_Release",
830         "OleObject_QueryInterface",
831         "OleObject_Release",
832         NULL
833     };
834
835     expected_method_list = methods_oleload;
836     trace("OleLoad:\n");
837     hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
838     ok_ole_success(hr, "OleLoad");
839     IOleObject_Release(pObject);
840     ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
841 }
842
843 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param)
844 {
845     CHECK_EXPECTED_METHOD("draw_continue");
846     return TRUE;
847 }
848
849 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv)
850 {
851     if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown))
852     {
853         *ppv = iface;
854         IUnknown_AddRef(iface);
855         return S_OK;
856     }
857     *ppv = NULL;
858     return E_NOINTERFACE;
859 }
860
861 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface)
862 {
863     return 2;
864 }
865
866 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface)
867 {
868     return 1;
869 }
870
871
872 static void WINAPI AdviseSink_OnDataChange(
873     IAdviseSink *iface,
874     FORMATETC *pFormatetc,
875     STGMEDIUM *pStgmed)
876 {
877     CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
878 }
879
880 static void WINAPI AdviseSink_OnViewChange(
881     IAdviseSink *iface,
882     DWORD dwAspect,
883     LONG lindex)
884 {
885     CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
886 }
887
888 static void WINAPI AdviseSink_OnRename(
889     IAdviseSink *iface,
890     IMoniker *pmk)
891 {
892     CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
893 }
894
895 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface)
896 {
897     CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
898 }
899
900 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface)
901 {
902     CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
903 }
904
905 static const IAdviseSinkVtbl AdviseSinkVtbl =
906 {
907     AdviseSink_QueryInterface,
908     AdviseSink_AddRef,
909     AdviseSink_Release,
910     AdviseSink_OnDataChange,
911     AdviseSink_OnViewChange,
912     AdviseSink_OnRename,
913     AdviseSink_OnSave,
914     AdviseSink_OnClose
915 };
916
917 static IAdviseSink AdviseSink = { &AdviseSinkVtbl };
918
919 static HRESULT WINAPI DataObject_QueryInterface(
920             IDataObject*     iface,
921             REFIID           riid,
922             void**           ppvObject)
923 {
924     if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
925     {
926         *ppvObject = iface;
927         return S_OK;
928     }
929     *ppvObject = NULL;
930     return S_OK;
931 }
932
933 static ULONG WINAPI DataObject_AddRef(
934             IDataObject*     iface)
935 {
936     return 2;
937 }
938
939 static ULONG WINAPI DataObject_Release(
940             IDataObject*     iface)
941 {
942     return 1;
943 }
944
945 static HRESULT WINAPI DataObject_GetData(
946         IDataObject*     iface,
947         LPFORMATETC      pformatetcIn,
948         STGMEDIUM*       pmedium)
949 {
950     CHECK_EXPECTED_METHOD("DataObject_GetData");
951     return E_NOTIMPL;
952 }
953
954 static HRESULT WINAPI DataObject_GetDataHere(
955         IDataObject*     iface,
956         LPFORMATETC      pformatetc,
957         STGMEDIUM*       pmedium)
958 {
959     CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
960     return E_NOTIMPL;
961 }
962
963 static HRESULT WINAPI DataObject_QueryGetData(
964         IDataObject*     iface,
965         LPFORMATETC      pformatetc)
966 {
967     CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
968     return S_OK;
969 }
970
971 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
972         IDataObject*     iface,
973         LPFORMATETC      pformatectIn,
974         LPFORMATETC      pformatetcOut)
975 {
976     CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
977     return E_NOTIMPL;
978 }
979
980 static HRESULT WINAPI DataObject_SetData(
981         IDataObject*     iface,
982         LPFORMATETC      pformatetc,
983         STGMEDIUM*       pmedium,
984         BOOL             fRelease)
985 {
986     CHECK_EXPECTED_METHOD("DataObject_SetData");
987     return E_NOTIMPL;
988 }
989
990 static HRESULT WINAPI DataObject_EnumFormatEtc(
991         IDataObject*     iface,
992         DWORD            dwDirection,
993         IEnumFORMATETC** ppenumFormatEtc)
994 {
995     CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
996     return E_NOTIMPL;
997 }
998
999 static HRESULT WINAPI DataObject_DAdvise(
1000         IDataObject*     iface,
1001         FORMATETC*       pformatetc,
1002         DWORD            advf,
1003         IAdviseSink*     pAdvSink,
1004         DWORD*           pdwConnection)
1005 {
1006     CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1007     *pdwConnection = 1;
1008     return S_OK;
1009 }
1010
1011 static HRESULT WINAPI DataObject_DUnadvise(
1012         IDataObject*     iface,
1013         DWORD            dwConnection)
1014 {
1015     CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1016     return S_OK;
1017 }
1018
1019 static HRESULT WINAPI DataObject_EnumDAdvise(
1020         IDataObject*     iface,
1021         IEnumSTATDATA**  ppenumAdvise)
1022 {
1023     CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1024     return OLE_E_ADVISENOTSUPPORTED;
1025 }
1026
1027 static IDataObjectVtbl DataObjectVtbl =
1028 {
1029     DataObject_QueryInterface,
1030     DataObject_AddRef,
1031     DataObject_Release,
1032     DataObject_GetData,
1033     DataObject_GetDataHere,
1034     DataObject_QueryGetData,
1035     DataObject_GetCanonicalFormatEtc,
1036     DataObject_SetData,
1037     DataObject_EnumFormatEtc,
1038     DataObject_DAdvise,
1039     DataObject_DUnadvise,
1040     DataObject_EnumDAdvise
1041 };
1042
1043 static IDataObject DataObject = { &DataObjectVtbl };
1044
1045 static void test_data_cache(void)
1046 {
1047     HRESULT hr;
1048     IOleCache2 *pOleCache;
1049     IStorage *pStorage;
1050     IPersistStorage *pPS;
1051     IViewObject *pViewObject;
1052     IOleCacheControl *pOleCacheControl;
1053     FORMATETC fmtetc;
1054     STGMEDIUM stgmedium;
1055     DWORD dwConnection;
1056     DWORD dwFreeze;
1057     RECTL rcBounds;
1058     HDC hdcMem;
1059     CLSID clsid;
1060     char szSystemDir[MAX_PATH];
1061     WCHAR wszPath[MAX_PATH];
1062     static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1063
1064     static const char *methods_cacheinitnew[] =
1065     {
1066         "AdviseSink_OnViewChange",
1067         "AdviseSink_OnViewChange",
1068         "draw_continue",
1069         "DataObject_DAdvise",
1070         "DataObject_DAdvise",
1071         "DataObject_DUnadvise",
1072         "DataObject_DUnadvise",
1073         NULL
1074     };
1075     static const char *methods_cacheload[] =
1076     {
1077         "AdviseSink_OnViewChange",
1078         "draw_continue",
1079         "draw_continue",
1080         "draw_continue",
1081         "DataObject_GetData",
1082         "DataObject_GetData",
1083         "DataObject_GetData",
1084         NULL
1085     };
1086
1087     GetSystemDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
1088
1089     expected_method_list = methods_cacheinitnew;
1090
1091     fmtetc.cfFormat = CF_METAFILEPICT;
1092     fmtetc.dwAspect = DVASPECT_ICON;
1093     fmtetc.lindex = -1;
1094     fmtetc.ptd = NULL;
1095     fmtetc.tymed = TYMED_MFPICT;
1096
1097     hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1098     ok_ole_success(hr, "StgCreateDocfile");
1099
1100     /* Test with new data */
1101
1102     hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1103     ok_ole_success(hr, "CreateDataCache");
1104
1105     hr = IOleCache_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1106     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1107     hr = IOleCache_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1108     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1109     hr = IOleCache_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1110     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1111
1112     hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1113     ok_ole_success(hr, "IViewObject_SetAdvise");
1114
1115     hr = IPersistStorage_InitNew(pPS, pStorage);
1116     ok_ole_success(hr, "IPersistStorage_InitNew");
1117
1118     hr = IPersistStorage_IsDirty(pPS);
1119     ok_ole_success(hr, "IPersistStorage_IsDirty");
1120
1121     hr = IPersistStorage_GetClassID(pPS, &clsid);
1122     ok_ole_success(hr, "IPersistStorage_GetClassID");
1123     ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n");
1124
1125     hr = IOleCache_Uncache(pOleCache, 0xdeadbeef);
1126     ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr);
1127
1128     for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++)
1129     {
1130         int i;
1131         fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1132         for (i = 0; i < 7; i++)
1133         {
1134             fmtetc.tymed = 1 << i;
1135             hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1136             if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) ||
1137                 (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) ||
1138                 (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) ||
1139                 (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF))
1140                 ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1141                     fmtetc.cfFormat, fmtetc.tymed, hr);
1142             else if (fmtetc.tymed == TYMED_HGLOBAL)
1143                 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED,
1144                     "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1145                     fmtetc.cfFormat, fmtetc.tymed, hr);
1146             else
1147                 ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1148                     fmtetc.cfFormat, fmtetc.tymed, hr);
1149             if (SUCCEEDED(hr))
1150             {
1151                 hr = IOleCache_Uncache(pOleCache, dwConnection);
1152                 ok_ole_success(hr, "IOleCache_Uncache");
1153             }
1154         }
1155     }
1156
1157     fmtetc.cfFormat = CF_BITMAP;
1158     fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1159     fmtetc.tymed = TYMED_GDI;
1160     hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1161     ok_ole_success(hr, "IOleCache_Cache");
1162
1163     fmtetc.cfFormat = 0;
1164     fmtetc.dwAspect = DVASPECT_ICON;
1165     fmtetc.tymed = TYMED_MFPICT;
1166     hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1167     ok_ole_success(hr, "IOleCache_Cache");
1168
1169     MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
1170     memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
1171
1172     fmtetc.cfFormat = CF_METAFILEPICT;
1173     stgmedium.tymed = TYMED_MFPICT;
1174     U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel(
1175         LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)), wszPath, wszPath, 0);
1176     stgmedium.pUnkForRelease = NULL;
1177
1178     fmtetc.dwAspect = DVASPECT_CONTENT;
1179     hr = IOleCache_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1180     ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr);
1181
1182     fmtetc.dwAspect = DVASPECT_ICON;
1183     hr = IOleCache_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1184     ok_ole_success(hr, "IOleCache_SetData");
1185
1186     hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze);
1187     todo_wine {
1188     ok_ole_success(hr, "IViewObject_Freeze");
1189     hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze);
1190     ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1191     }
1192
1193     rcBounds.left = 0;
1194     rcBounds.top = 0;
1195     rcBounds.right = 100;
1196     rcBounds.bottom = 100;
1197     hdcMem = CreateCompatibleDC(NULL);
1198
1199     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1200     ok_ole_success(hr, "IViewObject_Draw");
1201
1202     hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1203     ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1204
1205     DeleteDC(hdcMem);
1206
1207     hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1208     todo_wine {
1209     ok_ole_success(hr, "IOleCacheControl_OnRun");
1210     }
1211
1212     hr = IPersistStorage_Save(pPS, pStorage, TRUE);
1213     ok_ole_success(hr, "IPersistStorage_Save");
1214
1215     hr = IPersistStorage_SaveCompleted(pPS, NULL);
1216     ok_ole_success(hr, "IPersistStorage_SaveCompleted");
1217
1218     hr = IPersistStorage_IsDirty(pPS);
1219     ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1220
1221     IPersistStorage_Release(pPS);
1222     IViewObject_Release(pViewObject);
1223     IOleCache_Release(pOleCache);
1224     IOleCacheControl_Release(pOleCacheControl);
1225
1226     todo_wine {
1227     ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
1228     }
1229
1230     /* Test with loaded data */
1231     trace("Testing loaded data with CreateDataCache:\n");
1232     expected_method_list = methods_cacheload;
1233
1234     hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1235     ok_ole_success(hr, "CreateDataCache");
1236
1237     hr = IOleCache_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1238     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1239     hr = IOleCache_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1240     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1241
1242     hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1243     ok_ole_success(hr, "IViewObject_SetAdvise");
1244
1245     hr = IPersistStorage_Load(pPS, pStorage);
1246     ok_ole_success(hr, "IPersistStorage_Load");
1247
1248     hr = IPersistStorage_IsDirty(pPS);
1249     ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1250
1251     fmtetc.cfFormat = 0;
1252     fmtetc.dwAspect = DVASPECT_ICON;
1253     fmtetc.lindex = -1;
1254     fmtetc.ptd = NULL;
1255     fmtetc.tymed = TYMED_MFPICT;
1256     hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1257     ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr);
1258
1259     rcBounds.left = 0;
1260     rcBounds.top = 0;
1261     rcBounds.right = 100;
1262     rcBounds.bottom = 100;
1263     hdcMem = CreateCompatibleDC(NULL);
1264
1265     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1266     ok_ole_success(hr, "IViewObject_Draw");
1267
1268     hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1269     ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1270
1271     /* unload the cached storage object, causing it to be reloaded */
1272     hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1273     ok_ole_success(hr, "IOleCache2_DiscardCache");
1274     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1275     ok_ole_success(hr, "IViewObject_Draw");
1276
1277     /* unload the cached storage object, but don't allow it to be reloaded */
1278     hr = IPersistStorage_HandsOffStorage(pPS);
1279     ok_ole_success(hr, "IPersistStorage_HandsOffStorage");
1280     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1281     ok_ole_success(hr, "IViewObject_Draw");
1282     hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1283     ok_ole_success(hr, "IOleCache2_DiscardCache");
1284     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1285     ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1286
1287     DeleteDC(hdcMem);
1288
1289     todo_wine {
1290     hr = IOleCache_InitCache(pOleCache, &DataObject);
1291     ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr);
1292     }
1293
1294     IPersistStorage_Release(pPS);
1295     IViewObject_Release(pViewObject);
1296     IOleCache_Release(pOleCache);
1297
1298     todo_wine {
1299     ok(!*expected_method_list, "Method sequence starting from %s not called\n", *expected_method_list);
1300     }
1301
1302     IStorage_Release(pStorage);
1303     ReleaseStgMedium(&stgmedium);
1304 }
1305
1306 static void test_default_handler(void)
1307 {
1308     HRESULT hr;
1309     IOleObject *pObject;
1310     IRunnableObject *pRunnableObject;
1311     IOleClientSite *pClientSite;
1312     IDataObject *pDataObject;
1313     SIZEL sizel;
1314     DWORD dwStatus;
1315     CLSID clsid;
1316     LPOLESTR pszUserType;
1317     LOGPALETTE palette;
1318     DWORD dwAdvConn;
1319     IMoniker *pMoniker;
1320     FORMATETC fmtetc;
1321     IOleInPlaceObject *pInPlaceObj;
1322     IEnumOLEVERB *pEnumVerbs;
1323     static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0};
1324     static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
1325     static const WCHAR wszDelim[] = {'!',0};
1326
1327     hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject);
1328     ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1329
1330     hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject);
1331     ok_ole_success(hr, "OleCreateDefaultHandler");
1332
1333     hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj);
1334     ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr);
1335
1336     hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn);
1337     ok_ole_success(hr, "IOleObject_Advise");
1338
1339     hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
1340     ok_ole_success(hr, "IOleObject_Close");
1341
1342     /* FIXME: test IOleObject_EnumAdvise */
1343
1344     hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs);
1345     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1346
1347     hr = IOleObject_GetClientSite(pObject, &pClientSite);
1348     ok_ole_success(hr, "IOleObject_GetClientSite");
1349
1350     hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject);
1351     ok(hr == OLE_E_NOTRUNNING,
1352        "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
1353        hr);
1354
1355     hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel);
1356     ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
1357        hr);
1358
1359     hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1360     todo_wine
1361     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1362
1363     hr = IOleObject_GetUserClassID(pObject, &clsid);
1364     ok_ole_success(hr, "IOleObject_GetUserClassID");
1365     ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n");
1366
1367     hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType);
1368     todo_wine {
1369     ok_ole_success(hr, "IOleObject_GetUserType");
1370     ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n");
1371     }
1372
1373     hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0);
1374     ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1375
1376     hr = IOleObject_IsUpToDate(pObject);
1377     ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1378
1379     palette.palNumEntries = 1;
1380     palette.palVersion = 2;
1381     memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0]));
1382     hr = IOleObject_SetColorScheme(pObject, &palette);
1383     ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1384
1385     sizel.cx = sizel.cy = 0;
1386     hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
1387
1388     hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
1389     ok_ole_success(hr, "IOleObject_SetHostNames");
1390
1391     hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker);
1392     ok_ole_success(hr, "CreateItemMoniker");
1393     hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker);
1394     ok_ole_success(hr, "IOleObject_SetMoniker");
1395
1396     hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker);
1397     ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr);
1398
1399     hr = IOleObject_Update(pObject);
1400     todo_wine
1401     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1402
1403     hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject);
1404     ok_ole_success(hr, "IOleObject_QueryInterface");
1405
1406     fmtetc.cfFormat = CF_TEXT;
1407     fmtetc.ptd = NULL;
1408     fmtetc.dwAspect = DVASPECT_CONTENT;
1409     fmtetc.lindex = -1;
1410     fmtetc.tymed = TYMED_NULL;
1411     hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
1412     ok_ole_success(hr, "IDataObject_DAdvise");
1413
1414     fmtetc.cfFormat = CF_ENHMETAFILE;
1415     fmtetc.ptd = NULL;
1416     fmtetc.dwAspect = DVASPECT_CONTENT;
1417     fmtetc.lindex = -1;
1418     fmtetc.tymed = TYMED_ENHMF;
1419     hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
1420     ok_ole_success(hr, "IDataObject_DAdvise");
1421
1422     fmtetc.cfFormat = CF_ENHMETAFILE;
1423     fmtetc.ptd = NULL;
1424     fmtetc.dwAspect = DVASPECT_CONTENT;
1425     fmtetc.lindex = -1;
1426     fmtetc.tymed = TYMED_ENHMF;
1427     hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
1428     todo_wine
1429     ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1430
1431     fmtetc.cfFormat = CF_TEXT;
1432     fmtetc.ptd = NULL;
1433     fmtetc.dwAspect = DVASPECT_CONTENT;
1434     fmtetc.lindex = -1;
1435     fmtetc.tymed = TYMED_NULL;
1436     hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
1437     todo_wine
1438     ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1439
1440     hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject);
1441     ok_ole_success(hr, "IOleObject_QueryInterface");
1442
1443     hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE);
1444     ok_ole_success(hr, "IRunnableObject_SetContainedObject");
1445
1446     hr = IRunnableObject_Run(pRunnableObject, NULL);
1447     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1448
1449     hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
1450     ok_ole_success(hr, "IOleObject_Close");
1451
1452     IRunnableObject_Release(pRunnableObject);
1453     IOleObject_Release(pObject);
1454 }
1455
1456 START_TEST(ole2)
1457 {
1458     DWORD dwRegister;
1459     IStorage *pStorage;
1460     STATSTG statstg;
1461     HRESULT hr;
1462
1463     CoInitialize(NULL);
1464
1465     hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
1466     ok_ole_success(hr, "CoRegisterClassObject");
1467
1468     hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1469     ok_ole_success(hr, "StgCreateDocfile");
1470
1471     test_OleCreate(pStorage);
1472
1473     hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME);
1474     ok_ole_success(hr, "IStorage_Stat");
1475     ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n");
1476
1477     test_OleLoad(pStorage);
1478
1479     IStorage_Release(pStorage);
1480
1481     hr = CoRevokeClassObject(dwRegister);
1482     ok_ole_success(hr, "CoRevokeClassObject");
1483
1484     test_data_cache();
1485     test_default_handler();
1486
1487     CoUninitialize();
1488 }