ole32/tests: Make sure to use a return value (LLVM/Clang).
[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 const IID IID_WineTest =
48 { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */
49     0x9474ba1a,
50     0x258b,
51     0x490b,
52     {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1}
53 };
54
55 #define TEST_OPTIONAL 0x1
56 #define TEST_TODO     0x2
57
58 struct expected_method
59 {
60     const char *method;
61     unsigned int flags;
62 };
63
64 static const struct expected_method *expected_method_list;
65 static FORMATETC *g_expected_fetc = NULL;
66
67 static BOOL g_showRunnable = TRUE;
68 static BOOL g_isRunning = TRUE;
69 static BOOL g_failGetMiscStatus;
70 static HRESULT g_QIFailsWith;
71
72 static UINT cf_test_1, cf_test_2, cf_test_3;
73
74 #define CHECK_EXPECTED_METHOD(method_name) \
75     do { \
76         trace("%s\n", method_name); \
77         ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \
78         if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \
79         { \
80             todo_wine ok(0, "Too many method calls.\n"); \
81             break; \
82         } \
83         if (expected_method_list->method) \
84         { \
85             while (expected_method_list->flags & TEST_OPTIONAL && \
86                    strcmp(expected_method_list->method, method_name) != 0) \
87                 expected_method_list++; \
88             if (expected_method_list->flags & TEST_TODO) \
89                 todo_wine \
90                     ok(!strcmp(expected_method_list->method, method_name), \
91                        "Expected %s to be called instead of %s\n", \
92                        expected_method_list->method, method_name); \
93             else \
94                 ok(!strcmp(expected_method_list->method, method_name), \
95                    "Expected %s to be called instead of %s\n", \
96                    expected_method_list->method, method_name); \
97             expected_method_list++; \
98         } \
99     } while(0)
100
101 #define CHECK_NO_EXTRA_METHODS() \
102     do { \
103         while (expected_method_list->flags & TEST_OPTIONAL) \
104             expected_method_list++; \
105         ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
106     } while (0)
107
108 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
109 {
110     CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
111
112     *ppv = NULL;
113
114     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject))
115         *ppv = iface;
116     else if (IsEqualIID(riid, &IID_IPersistStorage))
117         *ppv = &OleObjectPersistStg;
118     else if (IsEqualIID(riid, &IID_IOleCache))
119         *ppv = cache;
120     else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable)
121         *ppv = runnable;
122     else if (IsEqualIID(riid, &IID_WineTest))
123         return g_QIFailsWith;
124
125     if(*ppv) {
126         IUnknown_AddRef((IUnknown*)*ppv);
127         return S_OK;
128     }
129
130     trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
131     return E_NOINTERFACE;
132 }
133
134 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
135 {
136     CHECK_EXPECTED_METHOD("OleObject_AddRef");
137     return 2;
138 }
139
140 static ULONG WINAPI OleObject_Release(IOleObject *iface)
141 {
142     CHECK_EXPECTED_METHOD("OleObject_Release");
143     return 1;
144 }
145
146 static HRESULT WINAPI OleObject_SetClientSite
147     (
148         IOleObject *iface,
149         IOleClientSite *pClientSite
150     )
151 {
152     CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
153     return S_OK;
154 }
155
156 static HRESULT WINAPI OleObject_GetClientSite
157     (
158         IOleObject *iface,
159         IOleClientSite **ppClientSite
160     )
161 {
162     CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
163     return E_NOTIMPL;
164 }
165
166 static HRESULT WINAPI OleObject_SetHostNames
167     (
168         IOleObject *iface,
169         LPCOLESTR szContainerApp,
170         LPCOLESTR szContainerObj
171     )
172 {
173     CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
174     return S_OK;
175 }
176
177 static HRESULT WINAPI OleObject_Close
178     (
179         IOleObject *iface,
180         DWORD dwSaveOption
181     )
182 {
183     CHECK_EXPECTED_METHOD("OleObject_Close");
184     return S_OK;
185 }
186
187 static HRESULT WINAPI OleObject_SetMoniker
188     (
189         IOleObject *iface,
190         DWORD dwWhichMoniker,
191         IMoniker *pmk
192     )
193 {
194     CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
195     return S_OK;
196 }
197
198 static HRESULT WINAPI OleObject_GetMoniker
199     (
200         IOleObject *iface,
201         DWORD dwAssign,
202         DWORD dwWhichMoniker,
203         IMoniker **ppmk
204     )
205 {
206     CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
207     return S_OK;
208 }
209
210 static HRESULT WINAPI OleObject_InitFromData
211     (
212         IOleObject *iface,
213         IDataObject *pDataObject,
214         BOOL fCreation,
215         DWORD dwReserved
216     )
217 {
218     CHECK_EXPECTED_METHOD("OleObject_InitFromData");
219     return S_OK;
220 }
221
222 static HRESULT WINAPI OleObject_GetClipboardData
223     (
224         IOleObject *iface,
225         DWORD dwReserved,
226         IDataObject **ppDataObject
227     )
228 {
229     CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
230     return E_NOTIMPL;
231 }
232
233 static HRESULT WINAPI OleObject_DoVerb
234     (
235         IOleObject *iface,
236         LONG iVerb,
237         LPMSG lpmsg,
238         IOleClientSite *pActiveSite,
239         LONG lindex,
240         HWND hwndParent,
241         LPCRECT lprcPosRect
242     )
243 {
244     CHECK_EXPECTED_METHOD("OleObject_DoVerb");
245     return S_OK;
246 }
247
248 static HRESULT WINAPI OleObject_EnumVerbs
249     (
250         IOleObject *iface,
251         IEnumOLEVERB **ppEnumOleVerb
252     )
253 {
254     CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
255     return E_NOTIMPL;
256 }
257
258 static HRESULT WINAPI OleObject_Update
259     (
260         IOleObject *iface
261     )
262 {
263     CHECK_EXPECTED_METHOD("OleObject_Update");
264     return S_OK;
265 }
266
267 static HRESULT WINAPI OleObject_IsUpToDate
268     (
269         IOleObject *iface
270     )
271 {
272     CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
273     return S_OK;
274 }
275
276 static HRESULT WINAPI OleObject_GetUserClassID
277 (
278     IOleObject *iface,
279     CLSID *pClsid
280 )
281 {
282     CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
283     return E_NOTIMPL;
284 }
285
286 static HRESULT WINAPI OleObject_GetUserType
287 (
288     IOleObject *iface,
289     DWORD dwFormOfType,
290     LPOLESTR *pszUserType
291 )
292 {
293     CHECK_EXPECTED_METHOD("OleObject_GetUserType");
294     return E_NOTIMPL;
295 }
296
297 static HRESULT WINAPI OleObject_SetExtent
298 (
299     IOleObject *iface,
300     DWORD dwDrawAspect,
301     SIZEL *psizel
302 )
303 {
304     CHECK_EXPECTED_METHOD("OleObject_SetExtent");
305     return S_OK;
306 }
307
308 static HRESULT WINAPI OleObject_GetExtent
309 (
310     IOleObject *iface,
311     DWORD dwDrawAspect,
312     SIZEL *psizel
313 )
314 {
315     CHECK_EXPECTED_METHOD("OleObject_GetExtent");
316     return E_NOTIMPL;
317 }
318
319 static HRESULT WINAPI OleObject_Advise
320 (
321     IOleObject *iface,
322     IAdviseSink *pAdvSink,
323     DWORD *pdwConnection
324 )
325 {
326     CHECK_EXPECTED_METHOD("OleObject_Advise");
327     return S_OK;
328 }
329
330 static HRESULT WINAPI OleObject_Unadvise
331 (
332     IOleObject *iface,
333     DWORD dwConnection
334 )
335 {
336     CHECK_EXPECTED_METHOD("OleObject_Unadvise");
337     return S_OK;
338 }
339
340 static HRESULT WINAPI OleObject_EnumAdvise
341 (
342     IOleObject *iface,
343     IEnumSTATDATA **ppenumAdvise
344 )
345 {
346     CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
347     return E_NOTIMPL;
348 }
349
350 static HRESULT WINAPI OleObject_GetMiscStatus
351 (
352     IOleObject *iface,
353     DWORD dwAspect,
354     DWORD *pdwStatus
355 )
356 {
357     CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
358     if(!g_failGetMiscStatus)
359     {
360         *pdwStatus = OLEMISC_RECOMPOSEONRESIZE;
361         return S_OK;
362     }
363     else
364     {
365         *pdwStatus = 0x1234;
366         return E_FAIL;
367     }
368 }
369
370 static HRESULT WINAPI OleObject_SetColorScheme
371 (
372     IOleObject *iface,
373     LOGPALETTE *pLogpal
374 )
375 {
376     CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
377     return E_NOTIMPL;
378 }
379
380 static const IOleObjectVtbl OleObjectVtbl =
381 {
382     OleObject_QueryInterface,
383     OleObject_AddRef,
384     OleObject_Release,
385     OleObject_SetClientSite,
386     OleObject_GetClientSite,
387     OleObject_SetHostNames,
388     OleObject_Close,
389     OleObject_SetMoniker,
390     OleObject_GetMoniker,
391     OleObject_InitFromData,
392     OleObject_GetClipboardData,
393     OleObject_DoVerb,
394     OleObject_EnumVerbs,
395     OleObject_Update,
396     OleObject_IsUpToDate,
397     OleObject_GetUserClassID,
398     OleObject_GetUserType,
399     OleObject_SetExtent,
400     OleObject_GetExtent,
401     OleObject_Advise,
402     OleObject_Unadvise,
403     OleObject_EnumAdvise,
404     OleObject_GetMiscStatus,
405     OleObject_SetColorScheme
406 };
407
408 static IOleObject OleObject = { &OleObjectVtbl };
409
410 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv)
411 {
412     trace("OleObjectPersistStg_QueryInterface\n");
413     return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
414 }
415
416 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface)
417 {
418     CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
419     return 2;
420 }
421
422 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface)
423 {
424     CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
425     return 1;
426 }
427
428 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid)
429 {
430     CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
431     return E_NOTIMPL;
432 }
433
434 static HRESULT WINAPI OleObjectPersistStg_IsDirty
435 (
436     IPersistStorage *iface
437 )
438 {
439     CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
440     return S_OK;
441 }
442
443 static HRESULT WINAPI OleObjectPersistStg_InitNew
444 (
445     IPersistStorage *iface,
446     IStorage *pStg
447 )
448 {
449     CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
450     return S_OK;
451 }
452
453 static HRESULT WINAPI OleObjectPersistStg_Load
454 (
455     IPersistStorage *iface,
456     IStorage *pStg
457 )
458 {
459     CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
460     return S_OK;
461 }
462
463 static HRESULT WINAPI OleObjectPersistStg_Save
464 (
465     IPersistStorage *iface,
466     IStorage *pStgSave,
467     BOOL fSameAsLoad
468 )
469 {
470     CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
471     return S_OK;
472 }
473
474 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
475 (
476     IPersistStorage *iface,
477     IStorage *pStgNew
478 )
479 {
480     CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
481     return S_OK;
482 }
483
484 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
485 (
486     IPersistStorage *iface
487 )
488 {
489     CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
490     return S_OK;
491 }
492
493 static const IPersistStorageVtbl OleObjectPersistStgVtbl =
494 {
495     OleObjectPersistStg_QueryInterface,
496     OleObjectPersistStg_AddRef,
497     OleObjectPersistStg_Release,
498     OleObjectPersistStg_GetClassId,
499     OleObjectPersistStg_IsDirty,
500     OleObjectPersistStg_InitNew,
501     OleObjectPersistStg_Load,
502     OleObjectPersistStg_Save,
503     OleObjectPersistStg_SaveCompleted,
504     OleObjectPersistStg_HandsOffStorage
505 };
506
507 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl };
508
509 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv)
510 {
511     return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
512 }
513
514 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface)
515 {
516     CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
517     return 2;
518 }
519
520 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface)
521 {
522     CHECK_EXPECTED_METHOD("OleObjectCache_Release");
523     return 1;
524 }
525
526 static HRESULT WINAPI OleObjectCache_Cache
527 (
528     IOleCache *iface,
529     FORMATETC *pformatetc,
530     DWORD advf,
531     DWORD *pdwConnection
532 )
533 {
534     CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
535     if (g_expected_fetc) {
536         ok(pformatetc != NULL, "pformatetc should not be NULL\n");
537         if (pformatetc) {
538             ok(pformatetc->cfFormat == g_expected_fetc->cfFormat,
539                     "cfFormat: %x\n", pformatetc->cfFormat);
540             ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL),
541                     "ptd: %p\n", pformatetc->ptd);
542             ok(pformatetc->dwAspect == g_expected_fetc->dwAspect,
543                     "dwAspect: %x\n", pformatetc->dwAspect);
544             ok(pformatetc->lindex == g_expected_fetc->lindex,
545                     "lindex: %x\n", pformatetc->lindex);
546             ok(pformatetc->tymed == g_expected_fetc->tymed,
547                     "tymed: %x\n", pformatetc->tymed);
548         }
549     } else
550         ok(pformatetc == NULL, "pformatetc should be NULL\n");
551     return S_OK;
552 }
553
554 static HRESULT WINAPI OleObjectCache_Uncache
555 (
556     IOleCache *iface,
557     DWORD dwConnection
558 )
559 {
560     CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
561     return S_OK;
562 }
563
564 static HRESULT WINAPI OleObjectCache_EnumCache
565 (
566     IOleCache *iface,
567     IEnumSTATDATA **ppenumSTATDATA
568 )
569 {
570     CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
571     return S_OK;
572 }
573
574
575 static HRESULT WINAPI OleObjectCache_InitCache
576 (
577     IOleCache *iface,
578     IDataObject *pDataObject
579 )
580 {
581     CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
582     return S_OK;
583 }
584
585
586 static HRESULT WINAPI OleObjectCache_SetData
587 (
588     IOleCache *iface,
589     FORMATETC *pformatetc,
590     STGMEDIUM *pmedium,
591     BOOL fRelease
592 )
593 {
594     CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
595     return S_OK;
596 }
597
598
599 static const IOleCacheVtbl OleObjectCacheVtbl =
600 {
601     OleObjectCache_QueryInterface,
602     OleObjectCache_AddRef,
603     OleObjectCache_Release,
604     OleObjectCache_Cache,
605     OleObjectCache_Uncache,
606     OleObjectCache_EnumCache,
607     OleObjectCache_InitCache,
608     OleObjectCache_SetData
609 };
610
611 static IOleCache OleObjectCache = { &OleObjectCacheVtbl };
612
613 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
614 {
615     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
616     {
617         *ppv = iface;
618         IUnknown_AddRef(iface);
619         return S_OK;
620     }
621     *ppv = NULL;
622     return E_NOINTERFACE;
623 }
624
625 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface)
626 {
627     return 2;
628 }
629
630 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface)
631 {
632     return 1;
633 }
634
635 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv)
636 {
637     return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
638 }
639
640 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock)
641 {
642     return S_OK;
643 }
644
645 static const IClassFactoryVtbl OleObjectCFVtbl =
646 {
647     OleObjectCF_QueryInterface,
648     OleObjectCF_AddRef,
649     OleObjectCF_Release,
650     OleObjectCF_CreateInstance,
651     OleObjectCF_LockServer
652 };
653
654 static IClassFactory OleObjectCF = { &OleObjectCFVtbl };
655
656 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
657 {
658     return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
659 }
660
661 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface)
662 {
663     CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
664     return 2;
665 }
666
667 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface)
668 {
669     CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
670     return 1;
671 }
672
673 static HRESULT WINAPI OleObjectRunnable_GetRunningClass(
674     IRunnableObject *iface,
675     LPCLSID lpClsid)
676 {
677     CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
678     return E_NOTIMPL;
679 }
680
681 static HRESULT WINAPI OleObjectRunnable_Run(
682     IRunnableObject *iface,
683     LPBINDCTX pbc)
684 {
685     CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
686     return S_OK;
687 }
688
689 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface)
690 {
691     CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
692     return g_isRunning;
693 }
694
695 static HRESULT WINAPI OleObjectRunnable_LockRunning(
696     IRunnableObject *iface,
697     BOOL fLock,
698     BOOL fLastUnlockCloses)
699 {
700     CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
701     return S_OK;
702 }
703
704 static HRESULT WINAPI OleObjectRunnable_SetContainedObject(
705     IRunnableObject *iface,
706     BOOL fContained)
707 {
708     CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
709     return S_OK;
710 }
711
712 static const IRunnableObjectVtbl OleObjectRunnableVtbl =
713 {
714     OleObjectRunnable_QueryInterface,
715     OleObjectRunnable_AddRef,
716     OleObjectRunnable_Release,
717     OleObjectRunnable_GetRunningClass,
718     OleObjectRunnable_Run,
719     OleObjectRunnable_IsRunning,
720     OleObjectRunnable_LockRunning,
721     OleObjectRunnable_SetContainedObject
722 };
723
724 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl };
725
726 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
727
728 static void test_OleCreate(IStorage *pStorage)
729 {
730     HRESULT hr;
731     IOleObject *pObject;
732     FORMATETC formatetc;
733     static const struct expected_method methods_olerender_none[] =
734     {
735         { "OleObject_QueryInterface", 0 },
736         { "OleObject_AddRef", 0 },
737         { "OleObject_QueryInterface", 0 },
738         { "OleObject_AddRef", TEST_OPTIONAL },
739         { "OleObject_Release", TEST_OPTIONAL },
740         { "OleObject_QueryInterface", TEST_OPTIONAL },
741         { "OleObjectPersistStg_AddRef", 0 },
742         { "OleObjectPersistStg_InitNew", 0 },
743         { "OleObjectPersistStg_Release", 0 },
744         { "OleObject_Release", 0 },
745         { "OleObject_Release", TEST_OPTIONAL },
746         { NULL, 0 }
747     };
748     static const struct expected_method methods_olerender_draw[] =
749     {
750         { "OleObject_QueryInterface", 0 },
751         { "OleObject_AddRef", 0 },
752         { "OleObject_QueryInterface", 0 },
753         { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
754         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
755         { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
756         { "OleObjectPersistStg_AddRef", 0 },
757         { "OleObjectPersistStg_InitNew", 0 },
758         { "OleObjectPersistStg_Release", 0 },
759         { "OleObject_QueryInterface", 0 },
760         { "OleObjectRunnable_AddRef", 0 },
761         { "OleObjectRunnable_Run", 0 },
762         { "OleObjectRunnable_Release", 0 },
763         { "OleObject_QueryInterface", 0 },
764         { "OleObjectCache_AddRef", 0 },
765         { "OleObjectCache_Cache", 0 },
766         { "OleObjectCache_Release", 0 },
767         { "OleObject_Release", 0 },
768         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
769         { NULL, 0 }
770     };
771     static const struct expected_method methods_olerender_format[] =
772     {
773         { "OleObject_QueryInterface", 0 },
774         { "OleObject_AddRef", 0 },
775         { "OleObject_QueryInterface", 0 },
776         { "OleObject_AddRef", 0 },
777         { "OleObject_GetMiscStatus", 0 },
778         { "OleObject_QueryInterface", 0 },
779         { "OleObjectPersistStg_AddRef", 0 },
780         { "OleObjectPersistStg_InitNew", 0 },
781         { "OleObjectPersistStg_Release", 0 },
782         { "OleObject_SetClientSite", 0 },
783         { "OleObject_Release", 0 },
784         { "OleObject_QueryInterface", 0 },
785         { "OleObjectRunnable_AddRef", 0 },
786         { "OleObjectRunnable_Run", 0 },
787         { "OleObjectRunnable_Release", 0 },
788         { "OleObject_QueryInterface", 0 },
789         { "OleObjectCache_AddRef", 0 },
790         { "OleObjectCache_Cache", 0 },
791         { "OleObjectCache_Release", 0 },
792         { "OleObject_Release", 0 },
793         { NULL, 0 }
794     };
795     static const struct expected_method methods_olerender_asis[] =
796     {
797         { "OleObject_QueryInterface", 0 },
798         { "OleObject_AddRef", 0 },
799         { "OleObject_QueryInterface", 0 },
800         { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
801         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
802         { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
803         { "OleObjectPersistStg_AddRef", 0 },
804         { "OleObjectPersistStg_InitNew", 0 },
805         { "OleObjectPersistStg_Release", 0 },
806         { "OleObject_Release", 0 },
807         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
808         { NULL, 0 }
809     };
810     static const struct expected_method methods_olerender_draw_no_runnable[] =
811     {
812         { "OleObject_QueryInterface", 0 },
813         { "OleObject_AddRef", 0 },
814         { "OleObject_QueryInterface", 0 },
815         { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
816         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
817         { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
818         { "OleObjectPersistStg_AddRef", 0 },
819         { "OleObjectPersistStg_InitNew", 0 },
820         { "OleObjectPersistStg_Release", 0 },
821         { "OleObject_QueryInterface", 0 },
822         { "OleObject_QueryInterface", 0 },
823         { "OleObjectCache_AddRef", 0 },
824         { "OleObjectCache_Cache", 0 },
825         { "OleObjectCache_Release", 0 },
826         { "OleObject_Release", 0 },
827         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
828         { NULL, 0 },
829     };
830     static const struct expected_method methods_olerender_draw_no_cache[] =
831     {
832         { "OleObject_QueryInterface", 0 },
833         { "OleObject_AddRef", 0 },
834         { "OleObject_QueryInterface", 0 },
835         { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
836         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
837         { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
838         { "OleObjectPersistStg_AddRef", 0 },
839         { "OleObjectPersistStg_InitNew", 0 },
840         { "OleObjectPersistStg_Release", 0 },
841         { "OleObject_QueryInterface", 0 },
842         { "OleObjectRunnable_AddRef", 0 },
843         { "OleObjectRunnable_Run", 0 },
844         { "OleObjectRunnable_Release", 0 },
845         { "OleObject_QueryInterface", 0 },
846         { "OleObject_Release", 0 },
847         { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
848         { NULL, 0 }
849     };
850
851     g_expected_fetc = &formatetc;
852     formatetc.cfFormat = 0;
853     formatetc.ptd = NULL;
854     formatetc.dwAspect = DVASPECT_CONTENT;
855     formatetc.lindex = -1;
856     formatetc.tymed = TYMED_NULL;
857     runnable = &OleObjectRunnable;
858     cache = &OleObjectCache;
859     expected_method_list = methods_olerender_none;
860     trace("OleCreate with OLERENDER_NONE:\n");
861     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject);
862     ok_ole_success(hr, "OleCreate");
863     IOleObject_Release(pObject);
864     CHECK_NO_EXTRA_METHODS();
865
866     expected_method_list = methods_olerender_draw;
867     trace("OleCreate with OLERENDER_DRAW:\n");
868     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
869     ok_ole_success(hr, "OleCreate");
870     IOleObject_Release(pObject);
871     CHECK_NO_EXTRA_METHODS();
872
873     formatetc.cfFormat = CF_TEXT;
874     formatetc.ptd = NULL;
875     formatetc.dwAspect = DVASPECT_CONTENT;
876     formatetc.lindex = -1;
877     formatetc.tymed = TYMED_HGLOBAL;
878     expected_method_list = methods_olerender_format;
879     trace("OleCreate with OLERENDER_FORMAT:\n");
880     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject);
881     ok(hr == S_OK ||
882        broken(hr == E_INVALIDARG), /* win2k */
883        "OleCreate failed with error 0x%08x\n", hr);
884     if (pObject)
885     {
886         IOleObject_Release(pObject);
887         CHECK_NO_EXTRA_METHODS();
888     }
889
890     expected_method_list = methods_olerender_asis;
891     trace("OleCreate with OLERENDER_ASIS:\n");
892     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject);
893     ok_ole_success(hr, "OleCreate");
894     IOleObject_Release(pObject);
895     CHECK_NO_EXTRA_METHODS();
896
897     formatetc.cfFormat = 0;
898     formatetc.tymed = TYMED_NULL;
899     runnable = NULL;
900     expected_method_list = methods_olerender_draw_no_runnable;
901     trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
902     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
903     ok_ole_success(hr, "OleCreate");
904     IOleObject_Release(pObject);
905     CHECK_NO_EXTRA_METHODS();
906
907     runnable = &OleObjectRunnable;
908     cache = NULL;
909     expected_method_list = methods_olerender_draw_no_cache;
910     trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n");
911     hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
912     ok_ole_success(hr, "OleCreate");
913     IOleObject_Release(pObject);
914     CHECK_NO_EXTRA_METHODS();
915     trace("end\n");
916 }
917
918 static void test_OleLoad(IStorage *pStorage)
919 {
920     HRESULT hr;
921     IOleObject *pObject;
922
923     static const struct expected_method methods_oleload[] =
924     {
925         { "OleObject_QueryInterface", 0 },
926         { "OleObject_AddRef", 0 },
927         { "OleObject_QueryInterface", 0 },
928         { "OleObject_AddRef", 0 },
929         { "OleObject_GetMiscStatus", 0 },
930         { "OleObject_QueryInterface", 0 },
931         { "OleObjectPersistStg_AddRef", 0 },
932         { "OleObjectPersistStg_Load", 0 },
933         { "OleObjectPersistStg_Release", 0 },
934         { "OleObject_SetClientSite", 0 },
935         { "OleObject_Release", 0 },
936         { "OleObject_QueryInterface", 0 },
937         { "OleObject_GetMiscStatus", 0 },
938         { "OleObject_Release", 0 },
939         { NULL, 0 }
940     };
941
942     /* Test once with IOleObject_GetMiscStatus failing */
943     expected_method_list = methods_oleload;
944     g_failGetMiscStatus = TRUE;
945     trace("OleLoad:\n");
946     hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
947     ok(hr == S_OK ||
948        broken(hr == E_INVALIDARG), /* win98 and win2k */
949        "OleLoad failed with error 0x%08x\n", hr);
950     if(pObject)
951     {
952         DWORD dwStatus = 0xdeadbeef;
953         hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
954         ok(hr == E_FAIL, "Got 0x%08x\n", hr);
955         ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus);
956
957         IOleObject_Release(pObject);
958         CHECK_NO_EXTRA_METHODS();
959     }
960
961     /* Test again, let IOleObject_GetMiscStatus succeed. */
962     g_failGetMiscStatus = FALSE;
963     expected_method_list = methods_oleload;
964     trace("OleLoad:\n");
965     hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
966     ok(hr == S_OK ||
967        broken(hr == E_INVALIDARG), /* win98 and win2k */
968        "OleLoad failed with error 0x%08x\n", hr);
969     if (pObject)
970     {
971         DWORD dwStatus = 0xdeadbeef;
972         hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
973         ok(hr == S_OK, "Got 0x%08x\n", hr);
974         ok(dwStatus == 1, "Got 0x%08x\n", dwStatus);
975
976         IOleObject_Release(pObject);
977         CHECK_NO_EXTRA_METHODS();
978     }
979 }
980
981 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param)
982 {
983     CHECK_EXPECTED_METHOD("draw_continue");
984     return TRUE;
985 }
986
987 static BOOL STDMETHODCALLTYPE draw_continue_false(ULONG_PTR param)
988 {
989     CHECK_EXPECTED_METHOD("draw_continue_false");
990     return FALSE;
991 }
992
993 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv)
994 {
995     if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown))
996     {
997         *ppv = iface;
998         IUnknown_AddRef(iface);
999         return S_OK;
1000     }
1001     *ppv = NULL;
1002     return E_NOINTERFACE;
1003 }
1004
1005 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface)
1006 {
1007     return 2;
1008 }
1009
1010 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface)
1011 {
1012     return 1;
1013 }
1014
1015
1016 static void WINAPI AdviseSink_OnDataChange(
1017     IAdviseSink *iface,
1018     FORMATETC *pFormatetc,
1019     STGMEDIUM *pStgmed)
1020 {
1021     CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
1022 }
1023
1024 static void WINAPI AdviseSink_OnViewChange(
1025     IAdviseSink *iface,
1026     DWORD dwAspect,
1027     LONG lindex)
1028 {
1029     CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
1030 }
1031
1032 static void WINAPI AdviseSink_OnRename(
1033     IAdviseSink *iface,
1034     IMoniker *pmk)
1035 {
1036     CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
1037 }
1038
1039 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface)
1040 {
1041     CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
1042 }
1043
1044 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface)
1045 {
1046     CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
1047 }
1048
1049 static const IAdviseSinkVtbl AdviseSinkVtbl =
1050 {
1051     AdviseSink_QueryInterface,
1052     AdviseSink_AddRef,
1053     AdviseSink_Release,
1054     AdviseSink_OnDataChange,
1055     AdviseSink_OnViewChange,
1056     AdviseSink_OnRename,
1057     AdviseSink_OnSave,
1058     AdviseSink_OnClose
1059 };
1060
1061 static IAdviseSink AdviseSink = { &AdviseSinkVtbl };
1062
1063 static HRESULT WINAPI DataObject_QueryInterface(
1064             IDataObject*     iface,
1065             REFIID           riid,
1066             void**           ppvObject)
1067 {
1068     CHECK_EXPECTED_METHOD("DataObject_QueryInterface");
1069
1070     if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
1071     {
1072         *ppvObject = iface;
1073         return S_OK;
1074     }
1075     *ppvObject = NULL;
1076     return S_OK;
1077 }
1078
1079 static ULONG WINAPI DataObject_AddRef(
1080             IDataObject*     iface)
1081 {
1082     CHECK_EXPECTED_METHOD("DataObject_AddRef");
1083     return 2;
1084 }
1085
1086 static ULONG WINAPI DataObject_Release(
1087             IDataObject*     iface)
1088 {
1089     CHECK_EXPECTED_METHOD("DataObject_Release");
1090     return 1;
1091 }
1092
1093 static HRESULT WINAPI DataObject_GetData(
1094         IDataObject*     iface,
1095         LPFORMATETC      pformatetcIn,
1096         STGMEDIUM*       pmedium)
1097 {
1098     CHECK_EXPECTED_METHOD("DataObject_GetData");
1099     return E_NOTIMPL;
1100 }
1101
1102 static HRESULT WINAPI DataObject_GetDataHere(
1103         IDataObject*     iface,
1104         LPFORMATETC      pformatetc,
1105         STGMEDIUM*       pmedium)
1106 {
1107     CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1108     return E_NOTIMPL;
1109 }
1110
1111 static HRESULT WINAPI DataObject_QueryGetData(
1112         IDataObject*     iface,
1113         LPFORMATETC      pformatetc)
1114 {
1115     CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
1116     return S_OK;
1117 }
1118
1119 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
1120         IDataObject*     iface,
1121         LPFORMATETC      pformatectIn,
1122         LPFORMATETC      pformatetcOut)
1123 {
1124     CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1125     return E_NOTIMPL;
1126 }
1127
1128 static HRESULT WINAPI DataObject_SetData(
1129         IDataObject*     iface,
1130         LPFORMATETC      pformatetc,
1131         STGMEDIUM*       pmedium,
1132         BOOL             fRelease)
1133 {
1134     CHECK_EXPECTED_METHOD("DataObject_SetData");
1135     return E_NOTIMPL;
1136 }
1137
1138 static HRESULT WINAPI DataObject_EnumFormatEtc(
1139         IDataObject*     iface,
1140         DWORD            dwDirection,
1141         IEnumFORMATETC** ppenumFormatEtc)
1142 {
1143     CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1144     return E_NOTIMPL;
1145 }
1146
1147 static HRESULT WINAPI DataObject_DAdvise(
1148         IDataObject*     iface,
1149         FORMATETC*       pformatetc,
1150         DWORD            advf,
1151         IAdviseSink*     pAdvSink,
1152         DWORD*           pdwConnection)
1153 {
1154     STGMEDIUM stgmedium;
1155
1156     CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1157     *pdwConnection = 1;
1158
1159     if(advf & ADVF_PRIMEFIRST)
1160     {
1161         ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat);
1162         stgmedium.tymed = TYMED_HGLOBAL;
1163         U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4);
1164         stgmedium.pUnkForRelease = NULL;
1165         IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium);
1166     }
1167
1168     return S_OK;
1169 }
1170
1171 static HRESULT WINAPI DataObject_DUnadvise(
1172         IDataObject*     iface,
1173         DWORD            dwConnection)
1174 {
1175     CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1176     return S_OK;
1177 }
1178
1179 static HRESULT WINAPI DataObject_EnumDAdvise(
1180         IDataObject*     iface,
1181         IEnumSTATDATA**  ppenumAdvise)
1182 {
1183     CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1184     return OLE_E_ADVISENOTSUPPORTED;
1185 }
1186
1187 static IDataObjectVtbl DataObjectVtbl =
1188 {
1189     DataObject_QueryInterface,
1190     DataObject_AddRef,
1191     DataObject_Release,
1192     DataObject_GetData,
1193     DataObject_GetDataHere,
1194     DataObject_QueryGetData,
1195     DataObject_GetCanonicalFormatEtc,
1196     DataObject_SetData,
1197     DataObject_EnumFormatEtc,
1198     DataObject_DAdvise,
1199     DataObject_DUnadvise,
1200     DataObject_EnumDAdvise
1201 };
1202
1203 static IDataObject DataObject = { &DataObjectVtbl };
1204
1205 static void test_data_cache(void)
1206 {
1207     HRESULT hr;
1208     IOleCache2 *pOleCache;
1209     IStorage *pStorage;
1210     IPersistStorage *pPS;
1211     IViewObject *pViewObject;
1212     IOleCacheControl *pOleCacheControl;
1213     IDataObject *pCacheDataObject;
1214     FORMATETC fmtetc;
1215     STGMEDIUM stgmedium;
1216     DWORD dwConnection;
1217     DWORD dwFreeze;
1218     RECTL rcBounds;
1219     HDC hdcMem;
1220     CLSID clsid;
1221     char szSystemDir[MAX_PATH];
1222     WCHAR wszPath[MAX_PATH];
1223     static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1224
1225     static const struct expected_method methods_cacheinitnew[] =
1226     {
1227         { "AdviseSink_OnViewChange", 0 },
1228         { "AdviseSink_OnViewChange", 0 },
1229         { "draw_continue", 1 },
1230         { "draw_continue_false", 1 },
1231         { "DataObject_DAdvise", 0 },
1232         { "DataObject_DAdvise", 0 },
1233         { "DataObject_DUnadvise", 0 },
1234         { "DataObject_DUnadvise", 0 },
1235         { NULL, 0 }
1236     };
1237     static const struct expected_method methods_cacheload[] =
1238     {
1239         { "AdviseSink_OnViewChange", 0 },
1240         { "draw_continue", 1 },
1241         { "draw_continue", 1 },
1242         { "draw_continue", 1 },
1243         { "DataObject_GetData", 0 },
1244         { "DataObject_GetData", 0 },
1245         { "DataObject_GetData", 0 },
1246         { NULL, 0 }
1247     };
1248     static const struct expected_method methods_cachethenrun[] =
1249     {
1250         { "DataObject_DAdvise", 0 },
1251         { "DataObject_DAdvise", 0 },
1252         { "DataObject_DAdvise", 0 },
1253         { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */
1254         { "DataObject_DAdvise", 0 },
1255         { "DataObject_DUnadvise", 0 },
1256         { "DataObject_DUnadvise", 0 },
1257         { "DataObject_DUnadvise", 0 },
1258         { "DataObject_DUnadvise", 0 },
1259         { NULL, 0 }
1260     };
1261
1262     GetSystemDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
1263
1264     expected_method_list = methods_cacheinitnew;
1265
1266     fmtetc.cfFormat = CF_METAFILEPICT;
1267     fmtetc.dwAspect = DVASPECT_ICON;
1268     fmtetc.lindex = -1;
1269     fmtetc.ptd = NULL;
1270     fmtetc.tymed = TYMED_MFPICT;
1271
1272     hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1273     ok_ole_success(hr, "StgCreateDocfile");
1274
1275     /* Test with new data */
1276
1277     hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1278     ok_ole_success(hr, "CreateDataCache");
1279
1280     hr = IOleCache_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1281     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1282     hr = IOleCache_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1283     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1284     hr = IOleCache_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1285     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1286
1287     hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1288     ok_ole_success(hr, "IViewObject_SetAdvise");
1289
1290     hr = IPersistStorage_InitNew(pPS, pStorage);
1291     ok_ole_success(hr, "IPersistStorage_InitNew");
1292
1293     hr = IPersistStorage_IsDirty(pPS);
1294     ok_ole_success(hr, "IPersistStorage_IsDirty");
1295
1296     hr = IPersistStorage_GetClassID(pPS, &clsid);
1297     ok_ole_success(hr, "IPersistStorage_GetClassID");
1298     ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n");
1299
1300     hr = IOleCache_Uncache(pOleCache, 0xdeadbeef);
1301     ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr);
1302
1303     /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1304     if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
1305     {
1306         hr = IOleCache_Cache(pOleCache, NULL, 0, &dwConnection);
1307         ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1308
1309         hr = IOleCache_Cache(pOleCache, NULL, 0, NULL);
1310         ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1311     }
1312     else
1313     {
1314         skip("tests with NULL parameters will crash on NT4 and below\n");
1315     }
1316
1317     for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++)
1318     {
1319         int i;
1320         fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1321         for (i = 0; i < 7; i++)
1322         {
1323             fmtetc.tymed = 1 << i;
1324             hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1325             if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) ||
1326                 (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) ||
1327                 (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) ||
1328                 (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF))
1329                 ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1330                     fmtetc.cfFormat, fmtetc.tymed, hr);
1331             else if (fmtetc.tymed == TYMED_HGLOBAL)
1332                 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED ||
1333                    broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */,
1334                     "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1335                     fmtetc.cfFormat, fmtetc.tymed, hr);
1336             else
1337                 ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1338                     fmtetc.cfFormat, fmtetc.tymed, hr);
1339             if (SUCCEEDED(hr))
1340             {
1341                 hr = IOleCache_Uncache(pOleCache, dwConnection);
1342                 ok_ole_success(hr, "IOleCache_Uncache");
1343             }
1344         }
1345     }
1346
1347     fmtetc.cfFormat = CF_BITMAP;
1348     fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1349     fmtetc.tymed = TYMED_GDI;
1350     hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1351     ok_ole_success(hr, "IOleCache_Cache");
1352
1353     fmtetc.cfFormat = 0;
1354     fmtetc.dwAspect = DVASPECT_ICON;
1355     fmtetc.tymed = TYMED_MFPICT;
1356     hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1357     ok_ole_success(hr, "IOleCache_Cache");
1358
1359     MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
1360     memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
1361
1362     fmtetc.cfFormat = CF_METAFILEPICT;
1363     stgmedium.tymed = TYMED_MFPICT;
1364     U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel(
1365         LoadIcon(NULL, IDI_APPLICATION), wszPath, wszPath, 0);
1366     stgmedium.pUnkForRelease = NULL;
1367
1368     fmtetc.dwAspect = DVASPECT_CONTENT;
1369     hr = IOleCache_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1370     ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr);
1371
1372     fmtetc.dwAspect = DVASPECT_ICON;
1373     hr = IOleCache_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1374     ok_ole_success(hr, "IOleCache_SetData");
1375     ReleaseStgMedium(&stgmedium);
1376
1377     hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze);
1378     todo_wine {
1379     ok_ole_success(hr, "IViewObject_Freeze");
1380     hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze);
1381     ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1382     }
1383
1384     rcBounds.left = 0;
1385     rcBounds.top = 0;
1386     rcBounds.right = 100;
1387     rcBounds.bottom = 100;
1388     hdcMem = CreateCompatibleDC(NULL);
1389
1390     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1391     ok_ole_success(hr, "IViewObject_Draw");
1392
1393     hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1394     ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1395
1396     /* a NULL draw_continue fn ptr */
1397     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef);
1398     ok_ole_success(hr, "IViewObject_Draw");
1399
1400     /* draw_continue that returns FALSE to abort drawing */
1401     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef);
1402     ok(hr == E_ABORT ||
1403        broken(hr == S_OK), /* win9x may skip the callbacks */
1404        "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr);
1405
1406     DeleteDC(hdcMem);
1407
1408     hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1409     ok_ole_success(hr, "IOleCacheControl_OnRun");
1410
1411     hr = IPersistStorage_Save(pPS, pStorage, TRUE);
1412     ok_ole_success(hr, "IPersistStorage_Save");
1413
1414     hr = IPersistStorage_SaveCompleted(pPS, NULL);
1415     ok_ole_success(hr, "IPersistStorage_SaveCompleted");
1416
1417     hr = IPersistStorage_IsDirty(pPS);
1418     ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1419
1420     IPersistStorage_Release(pPS);
1421     IViewObject_Release(pViewObject);
1422     IOleCache_Release(pOleCache);
1423     IOleCacheControl_Release(pOleCacheControl);
1424
1425     CHECK_NO_EXTRA_METHODS();
1426
1427     /* Test with loaded data */
1428     trace("Testing loaded data with CreateDataCache:\n");
1429     expected_method_list = methods_cacheload;
1430
1431     hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1432     ok_ole_success(hr, "CreateDataCache");
1433
1434     hr = IOleCache_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1435     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1436     hr = IOleCache_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1437     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1438
1439     hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1440     ok_ole_success(hr, "IViewObject_SetAdvise");
1441
1442     hr = IPersistStorage_Load(pPS, pStorage);
1443     ok_ole_success(hr, "IPersistStorage_Load");
1444
1445     hr = IPersistStorage_IsDirty(pPS);
1446     ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1447
1448     fmtetc.cfFormat = 0;
1449     fmtetc.dwAspect = DVASPECT_ICON;
1450     fmtetc.lindex = -1;
1451     fmtetc.ptd = NULL;
1452     fmtetc.tymed = TYMED_MFPICT;
1453     hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1454     ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr);
1455
1456     rcBounds.left = 0;
1457     rcBounds.top = 0;
1458     rcBounds.right = 100;
1459     rcBounds.bottom = 100;
1460     hdcMem = CreateCompatibleDC(NULL);
1461
1462     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1463     ok_ole_success(hr, "IViewObject_Draw");
1464
1465     hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1466     ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1467
1468     /* unload the cached storage object, causing it to be reloaded */
1469     hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1470     ok_ole_success(hr, "IOleCache2_DiscardCache");
1471     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1472     ok_ole_success(hr, "IViewObject_Draw");
1473
1474     /* unload the cached storage object, but don't allow it to be reloaded */
1475     hr = IPersistStorage_HandsOffStorage(pPS);
1476     ok_ole_success(hr, "IPersistStorage_HandsOffStorage");
1477     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1478     ok_ole_success(hr, "IViewObject_Draw");
1479     hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1480     ok_ole_success(hr, "IOleCache2_DiscardCache");
1481     hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1482     ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1483
1484     DeleteDC(hdcMem);
1485
1486     todo_wine {
1487     hr = IOleCache_InitCache(pOleCache, &DataObject);
1488     ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr);
1489     }
1490
1491     IPersistStorage_Release(pPS);
1492     IViewObject_Release(pViewObject);
1493     IOleCache_Release(pOleCache);
1494
1495     todo_wine {
1496     CHECK_NO_EXTRA_METHODS();
1497     }
1498
1499     hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1500     ok_ole_success(hr, "CreateDataCache");
1501
1502     expected_method_list = methods_cachethenrun;
1503
1504     hr = IOleCache_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject);
1505     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)");
1506     hr = IOleCache_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1507     ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1508
1509     fmtetc.cfFormat = CF_METAFILEPICT;
1510     fmtetc.dwAspect = DVASPECT_CONTENT;
1511     fmtetc.tymed = TYMED_MFPICT;
1512
1513     hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1514     ok_ole_success(hr, "IOleCache_Cache");
1515
1516     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1517     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1518
1519     fmtetc.cfFormat = cf_test_1;
1520     fmtetc.dwAspect = DVASPECT_CONTENT;
1521     fmtetc.tymed = TYMED_HGLOBAL;
1522
1523     hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1524     ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1525
1526     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1527     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1528
1529     fmtetc.cfFormat = cf_test_2;
1530     hr = IOleCache_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection);
1531     ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1532
1533     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1534     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1535
1536     hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1537     ok_ole_success(hr, "IOleCacheControl_OnRun");
1538
1539     fmtetc.cfFormat = cf_test_3;
1540     hr = IOleCache_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1541     ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1542
1543     fmtetc.cfFormat = cf_test_1;
1544     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1545     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1546
1547     fmtetc.cfFormat = cf_test_2;
1548     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1549     ok(hr == S_OK, "got %08x\n", hr);
1550     ReleaseStgMedium(&stgmedium);
1551
1552     fmtetc.cfFormat = cf_test_3;
1553     hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1554     ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1555
1556     IOleCacheControl_Release(pOleCacheControl);
1557     IDataObject_Release(pCacheDataObject);
1558     IOleCache_Release(pOleCache);
1559
1560     CHECK_NO_EXTRA_METHODS();
1561
1562     IStorage_Release(pStorage);
1563 }
1564
1565 static void test_default_handler(void)
1566 {
1567     HRESULT hr;
1568     IOleObject *pObject;
1569     IRunnableObject *pRunnableObject;
1570     IOleClientSite *pClientSite;
1571     IDataObject *pDataObject;
1572     SIZEL sizel;
1573     DWORD dwStatus;
1574     CLSID clsid;
1575     LPOLESTR pszUserType;
1576     LOGPALETTE palette;
1577     DWORD dwAdvConn;
1578     IMoniker *pMoniker;
1579     FORMATETC fmtetc;
1580     IOleInPlaceObject *pInPlaceObj;
1581     IEnumOLEVERB *pEnumVerbs;
1582     DWORD dwRegister;
1583     static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0};
1584     static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
1585     static const WCHAR wszDelim[] = {'!',0};
1586
1587     static const struct expected_method methods_embeddinghelper[] =
1588     {
1589         { "OleObject_QueryInterface", 0 },
1590         { "OleObject_AddRef", 0 },
1591         { "OleObject_QueryInterface", 0 },
1592         { "OleObject_QueryInterface", TEST_TODO },
1593         { "OleObject_QueryInterface", 0 },
1594         { "OleObject_QueryInterface", 0 },
1595         { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */
1596         { "OleObject_Release", TEST_TODO },
1597         { "WINE_EXTRA", TEST_OPTIONAL },
1598         { NULL, 0 }
1599     };
1600
1601     hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject);
1602     ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1603
1604     hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject);
1605     ok_ole_success(hr, "OleCreateDefaultHandler");
1606
1607     hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj);
1608     ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr);
1609
1610     hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn);
1611     ok_ole_success(hr, "IOleObject_Advise");
1612
1613     hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
1614     ok_ole_success(hr, "IOleObject_Close");
1615
1616     /* FIXME: test IOleObject_EnumAdvise */
1617
1618     hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs);
1619     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1620
1621     hr = IOleObject_GetClientSite(pObject, &pClientSite);
1622     ok_ole_success(hr, "IOleObject_GetClientSite");
1623
1624     hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject);
1625     ok(hr == OLE_E_NOTRUNNING,
1626        "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
1627        hr);
1628
1629     hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel);
1630     ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
1631        hr);
1632
1633     hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1634     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1635
1636     hr = IOleObject_GetUserClassID(pObject, &clsid);
1637     ok_ole_success(hr, "IOleObject_GetUserClassID");
1638     ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n");
1639
1640     hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType);
1641     todo_wine {
1642     ok_ole_success(hr, "IOleObject_GetUserType");
1643     ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n");
1644     }
1645
1646     hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0);
1647     ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1648
1649     hr = IOleObject_IsUpToDate(pObject);
1650     ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1651
1652     palette.palNumEntries = 1;
1653     palette.palVersion = 2;
1654     memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0]));
1655     hr = IOleObject_SetColorScheme(pObject, &palette);
1656     ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1657
1658     sizel.cx = sizel.cy = 0;
1659     hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
1660     ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1661
1662     hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
1663     ok_ole_success(hr, "IOleObject_SetHostNames");
1664
1665     hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker);
1666     ok_ole_success(hr, "CreateItemMoniker");
1667     hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker);
1668     ok_ole_success(hr, "IOleObject_SetMoniker");
1669     IMoniker_Release(pMoniker);
1670
1671     hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker);
1672     ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr);
1673
1674     hr = IOleObject_Update(pObject);
1675     todo_wine
1676     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1677
1678     hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject);
1679     ok_ole_success(hr, "IOleObject_QueryInterface");
1680
1681     fmtetc.cfFormat = CF_TEXT;
1682     fmtetc.ptd = NULL;
1683     fmtetc.dwAspect = DVASPECT_CONTENT;
1684     fmtetc.lindex = -1;
1685     fmtetc.tymed = TYMED_NULL;
1686     hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
1687     ok_ole_success(hr, "IDataObject_DAdvise");
1688
1689     fmtetc.cfFormat = CF_ENHMETAFILE;
1690     fmtetc.ptd = NULL;
1691     fmtetc.dwAspect = DVASPECT_CONTENT;
1692     fmtetc.lindex = -1;
1693     fmtetc.tymed = TYMED_ENHMF;
1694     hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
1695     ok_ole_success(hr, "IDataObject_DAdvise");
1696
1697     fmtetc.cfFormat = CF_ENHMETAFILE;
1698     fmtetc.ptd = NULL;
1699     fmtetc.dwAspect = DVASPECT_CONTENT;
1700     fmtetc.lindex = -1;
1701     fmtetc.tymed = TYMED_ENHMF;
1702     hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
1703     todo_wine
1704     ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1705
1706     fmtetc.cfFormat = CF_TEXT;
1707     fmtetc.ptd = NULL;
1708     fmtetc.dwAspect = DVASPECT_CONTENT;
1709     fmtetc.lindex = -1;
1710     fmtetc.tymed = TYMED_NULL;
1711     hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
1712     todo_wine
1713     ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
1714
1715     hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject);
1716     ok_ole_success(hr, "IOleObject_QueryInterface");
1717
1718     hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE);
1719     ok_ole_success(hr, "IRunnableObject_SetContainedObject");
1720
1721     hr = IRunnableObject_Run(pRunnableObject, NULL);
1722     ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1723
1724     hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
1725     ok_ole_success(hr, "IOleObject_Close");
1726
1727     IRunnableObject_Release(pRunnableObject);
1728     IOleObject_Release(pObject);
1729
1730     /* Test failure propagation from delegate ::QueryInterface */
1731     hr = CoRegisterClassObject(&CLSID_WineTest, (IUnknown*)&OleObjectCF,
1732                                CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
1733     ok_ole_success(hr, "CoRegisterClassObject");
1734     if(SUCCEEDED(hr))
1735     {
1736         expected_method_list = methods_embeddinghelper;
1737         hr = OleCreateEmbeddingHelper(&CLSID_WineTest, NULL, EMBDHLP_INPROC_SERVER,
1738                                       &OleObjectCF, &IID_IOleObject, (void**)&pObject);
1739         ok_ole_success(hr, "OleCreateEmbeddingHelper");
1740         if(SUCCEEDED(hr))
1741         {
1742             IUnknown *punk;
1743
1744             g_QIFailsWith = E_FAIL;
1745             hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
1746             ok(hr == E_FAIL, "Got 0x%08x\n", hr);
1747
1748             g_QIFailsWith = E_NOINTERFACE;
1749             hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
1750             ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
1751
1752             g_QIFailsWith = CO_E_OBJNOTCONNECTED;
1753             hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
1754             ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr);
1755
1756             g_QIFailsWith = 0x87654321;
1757             hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
1758             ok(hr == 0x87654321, "Got 0x%08x\n", hr);
1759
1760             IOleObject_Release(pObject);
1761         }
1762
1763         CHECK_NO_EXTRA_METHODS();
1764
1765         hr = CoRevokeClassObject(dwRegister);
1766         ok_ole_success(hr, "CoRevokeClassObject");
1767     }
1768 }
1769
1770 static void test_runnable(void)
1771 {
1772     static const struct expected_method methods_query_runnable[] =
1773     {
1774         { "OleObject_QueryInterface", 0 },
1775         { "OleObjectRunnable_AddRef", 0 },
1776         { "OleObjectRunnable_IsRunning", 0 },
1777         { "OleObjectRunnable_Release", 0 },
1778         { NULL, 0 }
1779     };
1780
1781     static const struct expected_method methods_no_runnable[] =
1782     {
1783         { "OleObject_QueryInterface", 0 },
1784         { NULL, 0 }
1785     };
1786
1787     IOleObject *object = &OleObject;
1788
1789     expected_method_list = methods_query_runnable;
1790     ok(OleIsRunning(object), "Object should be running\n");
1791     CHECK_NO_EXTRA_METHODS();
1792
1793     g_isRunning = FALSE;
1794     expected_method_list = methods_query_runnable;
1795     ok(OleIsRunning(object) == FALSE, "Object should not be running\n");
1796     CHECK_NO_EXTRA_METHODS();
1797
1798     g_showRunnable = FALSE;  /* QueryInterface(IID_IRunnableObject, ...) will fail */
1799     expected_method_list = methods_no_runnable;
1800     ok(OleIsRunning(object), "Object without IRunnableObject should be running\n");
1801     CHECK_NO_EXTRA_METHODS();
1802
1803     g_isRunning = TRUE;
1804     g_showRunnable = TRUE;
1805 }
1806
1807 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
1808 {
1809     *ppv = NULL;
1810     if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface;
1811     if (*ppv)
1812     {
1813         IUnknown_AddRef((IUnknown *)*ppv);
1814         return S_OK;
1815     }
1816     return E_NOINTERFACE;
1817 }
1818
1819 static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
1820 {
1821     return 2;
1822 }
1823
1824 static ULONG WINAPI Unknown_Release(IUnknown *iface)
1825 {
1826     return 1;
1827 }
1828
1829 static const IUnknownVtbl UnknownVtbl =
1830 {
1831     Unknown_QueryInterface,
1832     Unknown_AddRef,
1833     Unknown_Release
1834 };
1835
1836 static IUnknown Unknown = { &UnknownVtbl };
1837
1838 static void test_OleLockRunning(void)
1839 {
1840     HRESULT hr;
1841
1842     hr = OleLockRunning((LPUNKNOWN)&Unknown, TRUE, FALSE);
1843     ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
1844 }
1845
1846 START_TEST(ole2)
1847 {
1848     DWORD dwRegister;
1849     IStorage *pStorage;
1850     STATSTG statstg;
1851     HRESULT hr;
1852
1853     cf_test_1 = RegisterClipboardFormatA("cf_winetest_1");
1854     cf_test_2 = RegisterClipboardFormatA("cf_winetest_2");
1855     cf_test_3 = RegisterClipboardFormatA("cf_winetest_3");
1856
1857     CoInitialize(NULL);
1858
1859     hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
1860     ok_ole_success(hr, "CoRegisterClassObject");
1861
1862     hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1863     ok_ole_success(hr, "StgCreateDocfile");
1864
1865     test_OleCreate(pStorage);
1866
1867     hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME);
1868     ok_ole_success(hr, "IStorage_Stat");
1869     ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n");
1870
1871     test_OleLoad(pStorage);
1872
1873     IStorage_Release(pStorage);
1874
1875     hr = CoRevokeClassObject(dwRegister);
1876     ok_ole_success(hr, "CoRevokeClassObject");
1877
1878     test_data_cache();
1879     test_default_handler();
1880     test_runnable();
1881     test_OleLockRunning();
1882
1883     CoUninitialize();
1884 }