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