ole32/tests: Mark the draw_continue callbacks as optional. Win9x can skip calls under...
[wine.git] / dlls / ole32 / tests / ole2.c
blob080c2f262f49cd160d4734675a80bcec0f86fa34
1 /*
2 * Object Linking and Embedding Tests
4 * Copyright 2005 Robert Shearman
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.
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.
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
21 #define COBJMACROS
22 #define CONST_VTABLE
24 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "objbase.h"
29 #include "shlguid.h"
31 #include "wine/test.h"
33 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
35 static IPersistStorage OleObjectPersistStg;
36 static IOleCache *cache;
37 static IRunnableObject *runnable;
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}
47 #define TEST_OPTIONAL 0x1
49 struct expected_method
51 const char *method;
52 unsigned int flags;
55 static const struct expected_method *expected_method_list;
57 BOOL g_showRunnable = TRUE;
58 BOOL g_isRunning = TRUE;
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)
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)
82 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
84 CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
86 *ppv = NULL;
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;
97 if(*ppv) {
98 IUnknown_AddRef((IUnknown*)*ppv);
99 return S_OK;
102 trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
103 return E_NOINTERFACE;
106 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
108 CHECK_EXPECTED_METHOD("OleObject_AddRef");
109 return 2;
112 static ULONG WINAPI OleObject_Release(IOleObject *iface)
114 CHECK_EXPECTED_METHOD("OleObject_Release");
115 return 1;
118 static HRESULT WINAPI OleObject_SetClientSite
120 IOleObject *iface,
121 IOleClientSite *pClientSite
124 CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
125 return S_OK;
128 static HRESULT WINAPI OleObject_GetClientSite
130 IOleObject *iface,
131 IOleClientSite **ppClientSite
134 CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
135 return E_NOTIMPL;
138 static HRESULT WINAPI OleObject_SetHostNames
140 IOleObject *iface,
141 LPCOLESTR szContainerApp,
142 LPCOLESTR szContainerObj
145 CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
146 return S_OK;
149 static HRESULT WINAPI OleObject_Close
151 IOleObject *iface,
152 DWORD dwSaveOption
155 CHECK_EXPECTED_METHOD("OleObject_Close");
156 return S_OK;
159 static HRESULT WINAPI OleObject_SetMoniker
161 IOleObject *iface,
162 DWORD dwWhichMoniker,
163 IMoniker *pmk
166 CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
167 return S_OK;
170 static HRESULT WINAPI OleObject_GetMoniker
172 IOleObject *iface,
173 DWORD dwAssign,
174 DWORD dwWhichMoniker,
175 IMoniker **ppmk
178 CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
179 return S_OK;
182 static HRESULT WINAPI OleObject_InitFromData
184 IOleObject *iface,
185 IDataObject *pDataObject,
186 BOOL fCreation,
187 DWORD dwReserved
190 CHECK_EXPECTED_METHOD("OleObject_InitFromData");
191 return S_OK;
194 static HRESULT WINAPI OleObject_GetClipboardData
196 IOleObject *iface,
197 DWORD dwReserved,
198 IDataObject **ppDataObject
201 CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
202 return E_NOTIMPL;
205 static HRESULT WINAPI OleObject_DoVerb
207 IOleObject *iface,
208 LONG iVerb,
209 LPMSG lpmsg,
210 IOleClientSite *pActiveSite,
211 LONG lindex,
212 HWND hwndParent,
213 LPCRECT lprcPosRect
216 CHECK_EXPECTED_METHOD("OleObject_DoVerb");
217 return S_OK;
220 static HRESULT WINAPI OleObject_EnumVerbs
222 IOleObject *iface,
223 IEnumOLEVERB **ppEnumOleVerb
226 CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
227 return E_NOTIMPL;
230 static HRESULT WINAPI OleObject_Update
232 IOleObject *iface
235 CHECK_EXPECTED_METHOD("OleObject_Update");
236 return S_OK;
239 static HRESULT WINAPI OleObject_IsUpToDate
241 IOleObject *iface
244 CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
245 return S_OK;
248 static HRESULT WINAPI OleObject_GetUserClassID
250 IOleObject *iface,
251 CLSID *pClsid
254 CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
255 return E_NOTIMPL;
258 static HRESULT WINAPI OleObject_GetUserType
260 IOleObject *iface,
261 DWORD dwFormOfType,
262 LPOLESTR *pszUserType
265 CHECK_EXPECTED_METHOD("OleObject_GetUserType");
266 return E_NOTIMPL;
269 static HRESULT WINAPI OleObject_SetExtent
271 IOleObject *iface,
272 DWORD dwDrawAspect,
273 SIZEL *psizel
276 CHECK_EXPECTED_METHOD("OleObject_SetExtent");
277 return S_OK;
280 static HRESULT WINAPI OleObject_GetExtent
282 IOleObject *iface,
283 DWORD dwDrawAspect,
284 SIZEL *psizel
287 CHECK_EXPECTED_METHOD("OleObject_GetExtent");
288 return E_NOTIMPL;
291 static HRESULT WINAPI OleObject_Advise
293 IOleObject *iface,
294 IAdviseSink *pAdvSink,
295 DWORD *pdwConnection
298 CHECK_EXPECTED_METHOD("OleObject_Advise");
299 return S_OK;
302 static HRESULT WINAPI OleObject_Unadvise
304 IOleObject *iface,
305 DWORD dwConnection
308 CHECK_EXPECTED_METHOD("OleObject_Unadvise");
309 return S_OK;
312 static HRESULT WINAPI OleObject_EnumAdvise
314 IOleObject *iface,
315 IEnumSTATDATA **ppenumAdvise
318 CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
319 return E_NOTIMPL;
322 static HRESULT WINAPI OleObject_GetMiscStatus
324 IOleObject *iface,
325 DWORD dwAspect,
326 DWORD *pdwStatus
329 CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
330 *pdwStatus = DVASPECT_CONTENT;
331 return S_OK;
334 static HRESULT WINAPI OleObject_SetColorScheme
336 IOleObject *iface,
337 LOGPALETTE *pLogpal
340 CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
341 return E_NOTIMPL;
344 static const IOleObjectVtbl OleObjectVtbl =
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
372 static IOleObject OleObject = { &OleObjectVtbl };
374 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv)
376 trace("OleObjectPersistStg_QueryInterface\n");
377 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
380 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface)
382 CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
383 return 2;
386 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface)
388 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
389 return 1;
392 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid)
394 CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
395 return E_NOTIMPL;
398 static HRESULT WINAPI OleObjectPersistStg_IsDirty
400 IPersistStorage *iface
403 CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
404 return S_OK;
407 static HRESULT WINAPI OleObjectPersistStg_InitNew
409 IPersistStorage *iface,
410 IStorage *pStg
413 CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
414 return S_OK;
417 static HRESULT WINAPI OleObjectPersistStg_Load
419 IPersistStorage *iface,
420 IStorage *pStg
423 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
424 return S_OK;
427 static HRESULT WINAPI OleObjectPersistStg_Save
429 IPersistStorage *iface,
430 IStorage *pStgSave,
431 BOOL fSameAsLoad
434 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
435 return S_OK;
438 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
440 IPersistStorage *iface,
441 IStorage *pStgNew
444 CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
445 return S_OK;
448 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
450 IPersistStorage *iface
453 CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
454 return S_OK;
457 static const IPersistStorageVtbl OleObjectPersistStgVtbl =
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
471 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl };
473 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv)
475 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
478 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface)
480 CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
481 return 2;
484 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface)
486 CHECK_EXPECTED_METHOD("OleObjectCache_Release");
487 return 1;
490 static HRESULT WINAPI OleObjectCache_Cache
492 IOleCache *iface,
493 FORMATETC *pformatetc,
494 DWORD advf,
495 DWORD *pdwConnection
498 CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
499 return S_OK;
502 static HRESULT WINAPI OleObjectCache_Uncache
504 IOleCache *iface,
505 DWORD dwConnection
508 CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
509 return S_OK;
512 static HRESULT WINAPI OleObjectCache_EnumCache
514 IOleCache *iface,
515 IEnumSTATDATA **ppenumSTATDATA
518 CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
519 return S_OK;
523 static HRESULT WINAPI OleObjectCache_InitCache
525 IOleCache *iface,
526 IDataObject *pDataObject
529 CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
530 return S_OK;
534 static HRESULT WINAPI OleObjectCache_SetData
536 IOleCache *iface,
537 FORMATETC *pformatetc,
538 STGMEDIUM *pmedium,
539 BOOL fRelease
542 CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
543 return S_OK;
547 static const IOleCacheVtbl OleObjectCacheVtbl =
549 OleObjectCache_QueryInterface,
550 OleObjectCache_AddRef,
551 OleObjectCache_Release,
552 OleObjectCache_Cache,
553 OleObjectCache_Uncache,
554 OleObjectCache_EnumCache,
555 OleObjectCache_InitCache,
556 OleObjectCache_SetData
559 static IOleCache OleObjectCache = { &OleObjectCacheVtbl };
561 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
563 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
565 *ppv = iface;
566 IUnknown_AddRef(iface);
567 return S_OK;
569 *ppv = NULL;
570 return E_NOINTERFACE;
573 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface)
575 return 2;
578 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface)
580 return 1;
583 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv)
585 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
588 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock)
590 return S_OK;
593 static const IClassFactoryVtbl OleObjectCFVtbl =
595 OleObjectCF_QueryInterface,
596 OleObjectCF_AddRef,
597 OleObjectCF_Release,
598 OleObjectCF_CreateInstance,
599 OleObjectCF_LockServer
602 static IClassFactory OleObjectCF = { &OleObjectCFVtbl };
604 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
606 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
609 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface)
611 CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
612 return 2;
615 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface)
617 CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
618 return 1;
621 static HRESULT WINAPI OleObjectRunnable_GetRunningClass(
622 IRunnableObject *iface,
623 LPCLSID lpClsid)
625 CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
626 return E_NOTIMPL;
629 static HRESULT WINAPI OleObjectRunnable_Run(
630 IRunnableObject *iface,
631 LPBINDCTX pbc)
633 CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
634 return S_OK;
637 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface)
639 CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
640 return g_isRunning;
643 static HRESULT WINAPI OleObjectRunnable_LockRunning(
644 IRunnableObject *iface,
645 BOOL fLock,
646 BOOL fLastUnlockCloses)
648 CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
649 return S_OK;
652 static HRESULT WINAPI OleObjectRunnable_SetContainedObject(
653 IRunnableObject *iface,
654 BOOL fContained)
656 CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
657 return S_OK;
660 static const IRunnableObjectVtbl OleObjectRunnableVtbl =
662 OleObjectRunnable_QueryInterface,
663 OleObjectRunnable_AddRef,
664 OleObjectRunnable_Release,
665 OleObjectRunnable_GetRunningClass,
666 OleObjectRunnable_Run,
667 OleObjectRunnable_IsRunning,
668 OleObjectRunnable_LockRunning,
669 OleObjectRunnable_SetContainedObject
672 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl };
674 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
676 static void test_OleCreate(IStorage *pStorage)
678 HRESULT hr;
679 IOleObject *pObject;
680 FORMATETC formatetc;
681 static const struct expected_method methods_olerender_none[] =
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 }
696 static const struct expected_method methods_olerender_draw[] =
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 }
719 static const struct expected_method methods_olerender_format[] =
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 }
743 static const struct expected_method methods_olerender_asis[] =
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 }
758 static const struct expected_method methods_olerender_draw_no_runnable[] =
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 },
778 static const struct expected_method methods_olerender_draw_no_cache[] =
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 }
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();
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();
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)
828 IOleObject_Release(pObject);
829 CHECK_NO_EXTRA_METHODS();
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();
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();
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");
858 static void test_OleLoad(IStorage *pStorage)
860 HRESULT hr;
861 IOleObject *pObject;
863 static const struct expected_method methods_oleload[] =
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 }
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)
889 IOleObject_Release(pObject);
890 CHECK_NO_EXTRA_METHODS();
894 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param)
896 CHECK_EXPECTED_METHOD("draw_continue");
897 return TRUE;
900 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv)
902 if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown))
904 *ppv = iface;
905 IUnknown_AddRef(iface);
906 return S_OK;
908 *ppv = NULL;
909 return E_NOINTERFACE;
912 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface)
914 return 2;
917 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface)
919 return 1;
923 static void WINAPI AdviseSink_OnDataChange(
924 IAdviseSink *iface,
925 FORMATETC *pFormatetc,
926 STGMEDIUM *pStgmed)
928 CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
931 static void WINAPI AdviseSink_OnViewChange(
932 IAdviseSink *iface,
933 DWORD dwAspect,
934 LONG lindex)
936 CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
939 static void WINAPI AdviseSink_OnRename(
940 IAdviseSink *iface,
941 IMoniker *pmk)
943 CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
946 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface)
948 CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
951 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface)
953 CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
956 static const IAdviseSinkVtbl AdviseSinkVtbl =
958 AdviseSink_QueryInterface,
959 AdviseSink_AddRef,
960 AdviseSink_Release,
961 AdviseSink_OnDataChange,
962 AdviseSink_OnViewChange,
963 AdviseSink_OnRename,
964 AdviseSink_OnSave,
965 AdviseSink_OnClose
968 static IAdviseSink AdviseSink = { &AdviseSinkVtbl };
970 static HRESULT WINAPI DataObject_QueryInterface(
971 IDataObject* iface,
972 REFIID riid,
973 void** ppvObject)
975 if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
977 *ppvObject = iface;
978 return S_OK;
980 *ppvObject = NULL;
981 return S_OK;
984 static ULONG WINAPI DataObject_AddRef(
985 IDataObject* iface)
987 return 2;
990 static ULONG WINAPI DataObject_Release(
991 IDataObject* iface)
993 return 1;
996 static HRESULT WINAPI DataObject_GetData(
997 IDataObject* iface,
998 LPFORMATETC pformatetcIn,
999 STGMEDIUM* pmedium)
1001 CHECK_EXPECTED_METHOD("DataObject_GetData");
1002 return E_NOTIMPL;
1005 static HRESULT WINAPI DataObject_GetDataHere(
1006 IDataObject* iface,
1007 LPFORMATETC pformatetc,
1008 STGMEDIUM* pmedium)
1010 CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1011 return E_NOTIMPL;
1014 static HRESULT WINAPI DataObject_QueryGetData(
1015 IDataObject* iface,
1016 LPFORMATETC pformatetc)
1018 CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
1019 return S_OK;
1022 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
1023 IDataObject* iface,
1024 LPFORMATETC pformatectIn,
1025 LPFORMATETC pformatetcOut)
1027 CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1028 return E_NOTIMPL;
1031 static HRESULT WINAPI DataObject_SetData(
1032 IDataObject* iface,
1033 LPFORMATETC pformatetc,
1034 STGMEDIUM* pmedium,
1035 BOOL fRelease)
1037 CHECK_EXPECTED_METHOD("DataObject_SetData");
1038 return E_NOTIMPL;
1041 static HRESULT WINAPI DataObject_EnumFormatEtc(
1042 IDataObject* iface,
1043 DWORD dwDirection,
1044 IEnumFORMATETC** ppenumFormatEtc)
1046 CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1047 return E_NOTIMPL;
1050 static HRESULT WINAPI DataObject_DAdvise(
1051 IDataObject* iface,
1052 FORMATETC* pformatetc,
1053 DWORD advf,
1054 IAdviseSink* pAdvSink,
1055 DWORD* pdwConnection)
1057 CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1058 *pdwConnection = 1;
1059 return S_OK;
1062 static HRESULT WINAPI DataObject_DUnadvise(
1063 IDataObject* iface,
1064 DWORD dwConnection)
1066 CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1067 return S_OK;
1070 static HRESULT WINAPI DataObject_EnumDAdvise(
1071 IDataObject* iface,
1072 IEnumSTATDATA** ppenumAdvise)
1074 CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1075 return OLE_E_ADVISENOTSUPPORTED;
1078 static IDataObjectVtbl DataObjectVtbl =
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
1094 static IDataObject DataObject = { &DataObjectVtbl };
1096 static void test_data_cache(void)
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};
1115 static const struct expected_method methods_cacheinitnew[] =
1117 { "AdviseSink_OnViewChange", 0 },
1118 { "AdviseSink_OnViewChange", 0 },
1119 { "draw_continue", 1 },
1120 { "DataObject_DAdvise", 0 },
1121 { "DataObject_DAdvise", 0 },
1122 { "DataObject_DUnadvise", 0 },
1123 { "DataObject_DUnadvise", 0 },
1124 { NULL, 0 }
1126 static const struct expected_method methods_cacheload[] =
1128 { "AdviseSink_OnViewChange", 0 },
1129 { "draw_continue", 1 },
1130 { "draw_continue", 1 },
1131 { "draw_continue", 1 },
1132 { "DataObject_GetData", 0 },
1133 { "DataObject_GetData", 0 },
1134 { "DataObject_GetData", 0 },
1135 { NULL, 0 }
1138 GetSystemDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
1140 expected_method_list = methods_cacheinitnew;
1142 fmtetc.cfFormat = CF_METAFILEPICT;
1143 fmtetc.dwAspect = DVASPECT_ICON;
1144 fmtetc.lindex = -1;
1145 fmtetc.ptd = NULL;
1146 fmtetc.tymed = TYMED_MFPICT;
1148 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1149 ok_ole_success(hr, "StgCreateDocfile");
1151 /* Test with new data */
1153 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1154 ok_ole_success(hr, "CreateDataCache");
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)");
1163 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1164 ok_ole_success(hr, "IViewObject_SetAdvise");
1166 hr = IPersistStorage_InitNew(pPS, pStorage);
1167 ok_ole_success(hr, "IPersistStorage_InitNew");
1169 hr = IPersistStorage_IsDirty(pPS);
1170 ok_ole_success(hr, "IPersistStorage_IsDirty");
1172 hr = IPersistStorage_GetClassID(pPS, &clsid);
1173 ok_ole_success(hr, "IPersistStorage_GetClassID");
1174 ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n");
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);
1179 /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1180 if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
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);
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);
1188 else
1190 skip("tests with NULL parameters will crash on NT4 and below\n");
1193 for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++)
1195 int i;
1196 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1197 for (i = 0; i < 7; i++)
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))
1217 hr = IOleCache_Uncache(pOleCache, dwConnection);
1218 ok_ole_success(hr, "IOleCache_Uncache");
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");
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");
1235 MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
1236 memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
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;
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);
1248 fmtetc.dwAspect = DVASPECT_ICON;
1249 hr = IOleCache_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1250 ok_ole_success(hr, "IOleCache_SetData");
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);
1259 rcBounds.left = 0;
1260 rcBounds.top = 0;
1261 rcBounds.right = 100;
1262 rcBounds.bottom = 100;
1263 hdcMem = CreateCompatibleDC(NULL);
1265 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1266 ok_ole_success(hr, "IViewObject_Draw");
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);
1271 DeleteDC(hdcMem);
1273 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1274 todo_wine {
1275 ok_ole_success(hr, "IOleCacheControl_OnRun");
1278 hr = IPersistStorage_Save(pPS, pStorage, TRUE);
1279 ok_ole_success(hr, "IPersistStorage_Save");
1281 hr = IPersistStorage_SaveCompleted(pPS, NULL);
1282 ok_ole_success(hr, "IPersistStorage_SaveCompleted");
1284 hr = IPersistStorage_IsDirty(pPS);
1285 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1287 IPersistStorage_Release(pPS);
1288 IViewObject_Release(pViewObject);
1289 IOleCache_Release(pOleCache);
1290 IOleCacheControl_Release(pOleCacheControl);
1292 todo_wine {
1293 CHECK_NO_EXTRA_METHODS();
1296 /* Test with loaded data */
1297 trace("Testing loaded data with CreateDataCache:\n");
1298 expected_method_list = methods_cacheload;
1300 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1301 ok_ole_success(hr, "CreateDataCache");
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)");
1308 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1309 ok_ole_success(hr, "IViewObject_SetAdvise");
1311 hr = IPersistStorage_Load(pPS, pStorage);
1312 ok_ole_success(hr, "IPersistStorage_Load");
1314 hr = IPersistStorage_IsDirty(pPS);
1315 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
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);
1325 rcBounds.left = 0;
1326 rcBounds.top = 0;
1327 rcBounds.right = 100;
1328 rcBounds.bottom = 100;
1329 hdcMem = CreateCompatibleDC(NULL);
1331 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1332 ok_ole_success(hr, "IViewObject_Draw");
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);
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");
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);
1353 DeleteDC(hdcMem);
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);
1360 IPersistStorage_Release(pPS);
1361 IViewObject_Release(pViewObject);
1362 IOleCache_Release(pOleCache);
1364 todo_wine {
1365 CHECK_NO_EXTRA_METHODS();
1368 IStorage_Release(pStorage);
1369 ReleaseStgMedium(&stgmedium);
1372 static void test_default_handler(void)
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};
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);
1396 hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject);
1397 ok_ole_success(hr, "OleCreateDefaultHandler");
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);
1402 hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn);
1403 ok_ole_success(hr, "IOleObject_Advise");
1405 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
1406 ok_ole_success(hr, "IOleObject_Close");
1408 /* FIXME: test IOleObject_EnumAdvise */
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);
1413 hr = IOleObject_GetClientSite(pObject, &pClientSite);
1414 ok_ole_success(hr, "IOleObject_GetClientSite");
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);
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);
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);
1428 hr = IOleObject_GetUserClassID(pObject, &clsid);
1429 ok_ole_success(hr, "IOleObject_GetUserClassID");
1430 ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n");
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");
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);
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);
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);
1450 sizel.cx = sizel.cy = 0;
1451 hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
1453 hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
1454 ok_ole_success(hr, "IOleObject_SetHostNames");
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);
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);
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);
1469 hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject);
1470 ok_ole_success(hr, "IOleObject_QueryInterface");
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");
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");
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);
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);
1506 hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject);
1507 ok_ole_success(hr, "IOleObject_QueryInterface");
1509 hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE);
1510 ok_ole_success(hr, "IRunnableObject_SetContainedObject");
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);
1515 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
1516 ok_ole_success(hr, "IOleObject_Close");
1518 IRunnableObject_Release(pRunnableObject);
1519 IOleObject_Release(pObject);
1522 static void test_runnable(void)
1524 static const struct expected_method methods_query_runnable[] =
1526 { "OleObject_QueryInterface", 0 },
1527 { "OleObjectRunnable_AddRef", 0 },
1528 { "OleObjectRunnable_IsRunning", 0 },
1529 { "OleObjectRunnable_Release", 0 },
1530 { NULL, 0 }
1533 static const struct expected_method methods_no_runnable[] =
1535 { "OleObject_QueryInterface", 0 },
1536 { NULL, 0 }
1539 IOleObject *object = &OleObject;
1541 expected_method_list = methods_query_runnable;
1542 ok(OleIsRunning(object), "Object should be running\n");
1543 CHECK_NO_EXTRA_METHODS();
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();
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();
1555 g_isRunning = TRUE;
1556 g_showRunnable = TRUE;
1559 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
1561 *ppv = NULL;
1562 if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface;
1563 if (*ppv)
1565 IUnknown_AddRef((IUnknown *)*ppv);
1566 return S_OK;
1568 return E_NOINTERFACE;
1571 static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
1573 return 2;
1576 static ULONG WINAPI Unknown_Release(IUnknown *iface)
1578 return 1;
1581 static const IUnknownVtbl UnknownVtbl =
1583 Unknown_QueryInterface,
1584 Unknown_AddRef,
1585 Unknown_Release
1588 static IUnknown Unknown = { &UnknownVtbl };
1590 static void test_OleLockRunning(void)
1592 HRESULT hr;
1594 hr = OleLockRunning((LPUNKNOWN)&Unknown, TRUE, FALSE);
1595 ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
1598 START_TEST(ole2)
1600 DWORD dwRegister;
1601 IStorage *pStorage;
1602 STATSTG statstg;
1603 HRESULT hr;
1605 CoInitialize(NULL);
1607 hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
1608 ok_ole_success(hr, "CoRegisterClassObject");
1610 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1611 ok_ole_success(hr, "StgCreateDocfile");
1613 test_OleCreate(pStorage);
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");
1619 test_OleLoad(pStorage);
1621 IStorage_Release(pStorage);
1623 hr = CoRevokeClassObject(dwRegister);
1624 ok_ole_success(hr, "CoRevokeClassObject");
1626 test_data_cache();
1627 test_default_handler();
1628 test_runnable();
1629 test_OleLockRunning();
1631 CoUninitialize();