ole32/tests: A test to show data cache QI problems.
[wine.git] / dlls / ole32 / tests / ole2.c
blobd58105c6a8eab176511176af768312351365612a
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
23 #define WIN32_LEAN_AND_MEAN
25 #include <stdarg.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "objbase.h"
31 #include "shlguid.h"
33 #include "wine/test.h"
35 #include "initguid.h"
37 DEFINE_GUID(CLSID_Picture_Metafile,0x315,0,0,0xc0,0,0,0,0,0,0,0x46);
38 DEFINE_GUID(CLSID_Picture_Dib,0x316,0,0,0xc0,0,0,0,0,0,0,0x46);
40 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
42 #define DEFINE_EXPECT(func) \
43 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
45 #define SET_EXPECT(func) \
46 expect_ ## func = TRUE
48 #define CHECK_EXPECT2(func) \
49 do { \
50 ok(expect_ ##func, "unexpected call " #func "\n"); \
51 called_ ## func = TRUE; \
52 }while(0)
54 #define CHECK_EXPECT(func) \
55 do { \
56 CHECK_EXPECT2(func); \
57 expect_ ## func = FALSE; \
58 }while(0)
60 #define CHECK_CALLED(func) \
61 do { \
62 ok(called_ ## func, "expected " #func "\n"); \
63 expect_ ## func = called_ ## func = FALSE; \
64 }while(0)
66 DEFINE_EXPECT(Storage_Stat);
67 DEFINE_EXPECT(Storage_OpenStream_CompObj);
68 DEFINE_EXPECT(Storage_SetClass);
69 DEFINE_EXPECT(Storage_CreateStream_CompObj);
70 DEFINE_EXPECT(Storage_OpenStream_Ole);
72 static IPersistStorage OleObjectPersistStg;
73 static IOleCache *cache;
74 static IRunnableObject *runnable;
76 static const CLSID CLSID_WineTestOld =
77 { /* 9474ba1a-258b-490b-bc13-516e9239acd0 */
78 0x9474ba1a,
79 0x258b,
80 0x490b,
81 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xd0}
84 static const CLSID CLSID_WineTest =
85 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
86 0x9474ba1a,
87 0x258b,
88 0x490b,
89 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
92 static const IID IID_WineTest =
93 { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */
94 0x9474ba1a,
95 0x258b,
96 0x490b,
97 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1}
100 #define TEST_OPTIONAL 0x1
101 #define TEST_TODO 0x2
103 struct expected_method
105 const char *method;
106 unsigned int flags;
109 static const struct expected_method *expected_method_list;
110 static FORMATETC *g_expected_fetc = NULL;
112 static BOOL g_showRunnable = TRUE;
113 static BOOL g_isRunning = TRUE;
114 static HRESULT g_GetMiscStatusFailsWith = S_OK;
115 static HRESULT g_QIFailsWith;
117 static UINT cf_test_1, cf_test_2, cf_test_3;
119 /****************************************************************************
120 * PresentationDataHeader
122 * This structure represents the header of the \002OlePresXXX stream in
123 * the OLE object storage.
125 typedef struct PresentationDataHeader
127 /* clipformat:
128 * - standard clipformat:
129 * DWORD length = 0xffffffff;
130 * DWORD cfFormat;
131 * - or custom clipformat:
132 * DWORD length;
133 * CHAR format_name[length]; (null-terminated)
135 DWORD unknown3; /* 4, possibly TYMED_ISTREAM */
136 DVASPECT dvAspect;
137 DWORD lindex;
138 DWORD tymed;
139 DWORD unknown7; /* 0 */
140 DWORD dwObjectExtentX;
141 DWORD dwObjectExtentY;
142 DWORD dwSize;
143 } PresentationDataHeader;
145 #define CHECK_EXPECTED_METHOD(method_name) \
146 do { \
147 trace("%s\n", method_name); \
148 ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \
149 if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \
151 todo_wine ok(0, "Too many method calls.\n"); \
152 break; \
154 if (expected_method_list->method) \
156 while (expected_method_list->flags & TEST_OPTIONAL && \
157 strcmp(expected_method_list->method, method_name) != 0) \
158 expected_method_list++; \
159 todo_wine_if (expected_method_list->flags & TEST_TODO) \
160 ok(!strcmp(expected_method_list->method, method_name), \
161 "Expected %s to be called instead of %s\n", \
162 expected_method_list->method, method_name); \
163 expected_method_list++; \
165 } while(0)
167 #define CHECK_NO_EXTRA_METHODS() \
168 do { \
169 while (expected_method_list->flags & TEST_OPTIONAL) \
170 expected_method_list++; \
171 ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
172 } while (0)
174 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
176 CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
178 *ppv = NULL;
180 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject))
181 *ppv = iface;
182 else if (IsEqualIID(riid, &IID_IPersistStorage))
183 *ppv = &OleObjectPersistStg;
184 else if (IsEqualIID(riid, &IID_IOleCache))
185 *ppv = cache;
186 else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable)
187 *ppv = runnable;
188 else if (IsEqualIID(riid, &IID_WineTest))
189 return g_QIFailsWith;
191 if(*ppv) {
192 IUnknown_AddRef((IUnknown*)*ppv);
193 return S_OK;
196 trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
197 return E_NOINTERFACE;
200 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
202 CHECK_EXPECTED_METHOD("OleObject_AddRef");
203 return 2;
206 static ULONG WINAPI OleObject_Release(IOleObject *iface)
208 CHECK_EXPECTED_METHOD("OleObject_Release");
209 return 1;
212 static HRESULT WINAPI OleObject_SetClientSite
214 IOleObject *iface,
215 IOleClientSite *pClientSite
218 CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
219 return S_OK;
222 static HRESULT WINAPI OleObject_GetClientSite
224 IOleObject *iface,
225 IOleClientSite **ppClientSite
228 CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
229 return E_NOTIMPL;
232 static HRESULT WINAPI OleObject_SetHostNames
234 IOleObject *iface,
235 LPCOLESTR szContainerApp,
236 LPCOLESTR szContainerObj
239 CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
240 return S_OK;
243 static HRESULT WINAPI OleObject_Close
245 IOleObject *iface,
246 DWORD dwSaveOption
249 CHECK_EXPECTED_METHOD("OleObject_Close");
250 return S_OK;
253 static HRESULT WINAPI OleObject_SetMoniker
255 IOleObject *iface,
256 DWORD dwWhichMoniker,
257 IMoniker *pmk
260 CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
261 return S_OK;
264 static HRESULT WINAPI OleObject_GetMoniker
266 IOleObject *iface,
267 DWORD dwAssign,
268 DWORD dwWhichMoniker,
269 IMoniker **ppmk
272 CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
273 return S_OK;
276 static HRESULT WINAPI OleObject_InitFromData
278 IOleObject *iface,
279 IDataObject *pDataObject,
280 BOOL fCreation,
281 DWORD dwReserved
284 CHECK_EXPECTED_METHOD("OleObject_InitFromData");
285 return S_OK;
288 static HRESULT WINAPI OleObject_GetClipboardData
290 IOleObject *iface,
291 DWORD dwReserved,
292 IDataObject **ppDataObject
295 CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
296 return E_NOTIMPL;
299 static HRESULT WINAPI OleObject_DoVerb
301 IOleObject *iface,
302 LONG iVerb,
303 LPMSG lpmsg,
304 IOleClientSite *pActiveSite,
305 LONG lindex,
306 HWND hwndParent,
307 LPCRECT lprcPosRect
310 CHECK_EXPECTED_METHOD("OleObject_DoVerb");
311 return S_OK;
314 static HRESULT WINAPI OleObject_EnumVerbs
316 IOleObject *iface,
317 IEnumOLEVERB **ppEnumOleVerb
320 CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
321 return E_NOTIMPL;
324 static HRESULT WINAPI OleObject_Update
326 IOleObject *iface
329 CHECK_EXPECTED_METHOD("OleObject_Update");
330 return S_OK;
333 static HRESULT WINAPI OleObject_IsUpToDate
335 IOleObject *iface
338 CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
339 return S_OK;
342 static HRESULT WINAPI OleObject_GetUserClassID
344 IOleObject *iface,
345 CLSID *pClsid
348 CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
349 return E_NOTIMPL;
352 static HRESULT WINAPI OleObject_GetUserType
354 IOleObject *iface,
355 DWORD dwFormOfType,
356 LPOLESTR *pszUserType
359 CHECK_EXPECTED_METHOD("OleObject_GetUserType");
360 return E_NOTIMPL;
363 static HRESULT WINAPI OleObject_SetExtent
365 IOleObject *iface,
366 DWORD dwDrawAspect,
367 SIZEL *psizel
370 CHECK_EXPECTED_METHOD("OleObject_SetExtent");
371 return S_OK;
374 static HRESULT WINAPI OleObject_GetExtent
376 IOleObject *iface,
377 DWORD dwDrawAspect,
378 SIZEL *psizel
381 CHECK_EXPECTED_METHOD("OleObject_GetExtent");
382 return E_NOTIMPL;
385 static HRESULT WINAPI OleObject_Advise
387 IOleObject *iface,
388 IAdviseSink *pAdvSink,
389 DWORD *pdwConnection
392 CHECK_EXPECTED_METHOD("OleObject_Advise");
393 return S_OK;
396 static HRESULT WINAPI OleObject_Unadvise
398 IOleObject *iface,
399 DWORD dwConnection
402 CHECK_EXPECTED_METHOD("OleObject_Unadvise");
403 return S_OK;
406 static HRESULT WINAPI OleObject_EnumAdvise
408 IOleObject *iface,
409 IEnumSTATDATA **ppenumAdvise
412 CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
413 return E_NOTIMPL;
416 static HRESULT WINAPI OleObject_GetMiscStatus
418 IOleObject *iface,
419 DWORD aspect,
420 DWORD *pdwStatus
423 CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
425 ok(aspect == DVASPECT_CONTENT, "got aspect %d\n", aspect);
427 if (g_GetMiscStatusFailsWith == S_OK)
429 *pdwStatus = OLEMISC_RECOMPOSEONRESIZE;
430 return S_OK;
432 else
434 *pdwStatus = 0x1234;
435 return g_GetMiscStatusFailsWith;
439 static HRESULT WINAPI OleObject_SetColorScheme
441 IOleObject *iface,
442 LOGPALETTE *pLogpal
445 CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
446 return E_NOTIMPL;
449 static const IOleObjectVtbl OleObjectVtbl =
451 OleObject_QueryInterface,
452 OleObject_AddRef,
453 OleObject_Release,
454 OleObject_SetClientSite,
455 OleObject_GetClientSite,
456 OleObject_SetHostNames,
457 OleObject_Close,
458 OleObject_SetMoniker,
459 OleObject_GetMoniker,
460 OleObject_InitFromData,
461 OleObject_GetClipboardData,
462 OleObject_DoVerb,
463 OleObject_EnumVerbs,
464 OleObject_Update,
465 OleObject_IsUpToDate,
466 OleObject_GetUserClassID,
467 OleObject_GetUserType,
468 OleObject_SetExtent,
469 OleObject_GetExtent,
470 OleObject_Advise,
471 OleObject_Unadvise,
472 OleObject_EnumAdvise,
473 OleObject_GetMiscStatus,
474 OleObject_SetColorScheme
477 static IOleObject OleObject = { &OleObjectVtbl };
479 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv)
481 trace("OleObjectPersistStg_QueryInterface\n");
482 return IOleObject_QueryInterface(&OleObject, riid, ppv);
485 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface)
487 CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
488 return 2;
491 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface)
493 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
494 return 1;
497 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid)
499 CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
500 return E_NOTIMPL;
503 static HRESULT WINAPI OleObjectPersistStg_IsDirty
505 IPersistStorage *iface
508 CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
509 return S_OK;
512 static HRESULT WINAPI OleObjectPersistStg_InitNew
514 IPersistStorage *iface,
515 IStorage *pStg
518 CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
519 return S_OK;
522 static HRESULT WINAPI OleObjectPersistStg_Load
524 IPersistStorage *iface,
525 IStorage *pStg
528 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
529 return S_OK;
532 static HRESULT WINAPI OleObjectPersistStg_Save
534 IPersistStorage *iface,
535 IStorage *pStgSave,
536 BOOL fSameAsLoad
539 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
540 return S_OK;
543 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
545 IPersistStorage *iface,
546 IStorage *pStgNew
549 CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
550 return S_OK;
553 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
555 IPersistStorage *iface
558 CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
559 return S_OK;
562 static const IPersistStorageVtbl OleObjectPersistStgVtbl =
564 OleObjectPersistStg_QueryInterface,
565 OleObjectPersistStg_AddRef,
566 OleObjectPersistStg_Release,
567 OleObjectPersistStg_GetClassId,
568 OleObjectPersistStg_IsDirty,
569 OleObjectPersistStg_InitNew,
570 OleObjectPersistStg_Load,
571 OleObjectPersistStg_Save,
572 OleObjectPersistStg_SaveCompleted,
573 OleObjectPersistStg_HandsOffStorage
576 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl };
578 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv)
580 return IOleObject_QueryInterface(&OleObject, riid, ppv);
583 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface)
585 CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
586 return 2;
589 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface)
591 CHECK_EXPECTED_METHOD("OleObjectCache_Release");
592 return 1;
595 static HRESULT WINAPI OleObjectCache_Cache
597 IOleCache *iface,
598 FORMATETC *pformatetc,
599 DWORD advf,
600 DWORD *pdwConnection
603 CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
604 if (g_expected_fetc) {
605 ok(pformatetc != NULL, "pformatetc should not be NULL\n");
606 if (pformatetc) {
607 ok(pformatetc->cfFormat == g_expected_fetc->cfFormat,
608 "cfFormat: %x\n", pformatetc->cfFormat);
609 ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL),
610 "ptd: %p\n", pformatetc->ptd);
611 ok(pformatetc->dwAspect == g_expected_fetc->dwAspect,
612 "dwAspect: %x\n", pformatetc->dwAspect);
613 ok(pformatetc->lindex == g_expected_fetc->lindex,
614 "lindex: %x\n", pformatetc->lindex);
615 ok(pformatetc->tymed == g_expected_fetc->tymed,
616 "tymed: %x\n", pformatetc->tymed);
618 } else
619 ok(pformatetc == NULL, "pformatetc should be NULL\n");
620 return S_OK;
623 static HRESULT WINAPI OleObjectCache_Uncache
625 IOleCache *iface,
626 DWORD dwConnection
629 CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
630 return S_OK;
633 static HRESULT WINAPI OleObjectCache_EnumCache
635 IOleCache *iface,
636 IEnumSTATDATA **ppenumSTATDATA
639 CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
640 return S_OK;
644 static HRESULT WINAPI OleObjectCache_InitCache
646 IOleCache *iface,
647 IDataObject *pDataObject
650 CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
651 return S_OK;
655 static HRESULT WINAPI OleObjectCache_SetData
657 IOleCache *iface,
658 FORMATETC *pformatetc,
659 STGMEDIUM *pmedium,
660 BOOL fRelease
663 CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
664 return S_OK;
668 static const IOleCacheVtbl OleObjectCacheVtbl =
670 OleObjectCache_QueryInterface,
671 OleObjectCache_AddRef,
672 OleObjectCache_Release,
673 OleObjectCache_Cache,
674 OleObjectCache_Uncache,
675 OleObjectCache_EnumCache,
676 OleObjectCache_InitCache,
677 OleObjectCache_SetData
680 static IOleCache OleObjectCache = { &OleObjectCacheVtbl };
682 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
684 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
686 *ppv = iface;
687 IClassFactory_AddRef(iface);
688 return S_OK;
690 *ppv = NULL;
691 return E_NOINTERFACE;
694 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface)
696 return 2;
699 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface)
701 return 1;
704 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv)
706 return IOleObject_QueryInterface(&OleObject, riid, ppv);
709 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock)
711 return S_OK;
714 static const IClassFactoryVtbl OleObjectCFVtbl =
716 OleObjectCF_QueryInterface,
717 OleObjectCF_AddRef,
718 OleObjectCF_Release,
719 OleObjectCF_CreateInstance,
720 OleObjectCF_LockServer
723 static IClassFactory OleObjectCF = { &OleObjectCFVtbl };
725 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
727 return IOleObject_QueryInterface(&OleObject, riid, ppv);
730 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface)
732 CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
733 return 2;
736 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface)
738 CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
739 return 1;
742 static HRESULT WINAPI OleObjectRunnable_GetRunningClass(
743 IRunnableObject *iface,
744 LPCLSID lpClsid)
746 CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
747 return E_NOTIMPL;
750 static HRESULT WINAPI OleObjectRunnable_Run(
751 IRunnableObject *iface,
752 LPBINDCTX pbc)
754 CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
755 return S_OK;
758 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface)
760 CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
761 return g_isRunning;
764 static HRESULT WINAPI OleObjectRunnable_LockRunning(
765 IRunnableObject *iface,
766 BOOL fLock,
767 BOOL fLastUnlockCloses)
769 CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
770 return S_OK;
773 static HRESULT WINAPI OleObjectRunnable_SetContainedObject(
774 IRunnableObject *iface,
775 BOOL fContained)
777 CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
778 return S_OK;
781 static const IRunnableObjectVtbl OleObjectRunnableVtbl =
783 OleObjectRunnable_QueryInterface,
784 OleObjectRunnable_AddRef,
785 OleObjectRunnable_Release,
786 OleObjectRunnable_GetRunningClass,
787 OleObjectRunnable_Run,
788 OleObjectRunnable_IsRunning,
789 OleObjectRunnable_LockRunning,
790 OleObjectRunnable_SetContainedObject
793 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl };
795 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
797 static HRESULT WINAPI viewobject_QueryInterface(IViewObject *iface, REFIID riid, void **obj)
799 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IViewObject))
801 *obj = iface;
802 return S_OK;
805 *obj = NULL;
806 return E_NOINTERFACE;
809 static ULONG WINAPI viewobject_AddRef(IViewObject *iface)
811 return 2;
814 static ULONG WINAPI viewobject_Release(IViewObject *iface)
816 return 1;
819 static HRESULT WINAPI viewobject_Draw(IViewObject *iface, DWORD aspect, LONG index,
820 void *paspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw,
821 LPCRECTL bounds, LPCRECTL wbounds, BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue),
822 ULONG_PTR dwContinue)
824 ok(index == -1, "index=%d\n", index);
825 return S_OK;
828 static HRESULT WINAPI viewobject_GetColorSet(IViewObject *iface, DWORD draw_aspect, LONG index,
829 void *aspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **colorset)
831 ok(0, "unexpected call GetColorSet\n");
832 return E_NOTIMPL;
835 static HRESULT WINAPI viewobject_Freeze(IViewObject *iface, DWORD draw_aspect, LONG index,
836 void *aspect, DWORD *freeze)
838 ok(0, "unexpected call Freeze\n");
839 return E_NOTIMPL;
842 static HRESULT WINAPI viewobject_Unfreeze(IViewObject *iface, DWORD freeze)
844 ok(0, "unexpected call Unfreeze\n");
845 return E_NOTIMPL;
848 static HRESULT WINAPI viewobject_SetAdvise(IViewObject *iface, DWORD aspects, DWORD advf, IAdviseSink *sink)
850 ok(0, "unexpected call SetAdvise\n");
851 return E_NOTIMPL;
854 static HRESULT WINAPI viewobject_GetAdvise(IViewObject *iface, DWORD *aspects, DWORD *advf,
855 IAdviseSink **sink)
857 ok(0, "unexpected call GetAdvise\n");
858 return E_NOTIMPL;
861 static const struct IViewObjectVtbl viewobjectvtbl = {
862 viewobject_QueryInterface,
863 viewobject_AddRef,
864 viewobject_Release,
865 viewobject_Draw,
866 viewobject_GetColorSet,
867 viewobject_Freeze,
868 viewobject_Unfreeze,
869 viewobject_SetAdvise,
870 viewobject_GetAdvise
873 static IViewObject viewobject = { &viewobjectvtbl };
875 static void test_OleCreate(IStorage *pStorage)
877 HRESULT hr;
878 IOleObject *pObject;
879 FORMATETC formatetc;
880 static const struct expected_method methods_olerender_none[] =
882 { "OleObject_QueryInterface", 0 },
883 { "OleObject_AddRef", 0 },
884 { "OleObject_QueryInterface", 0 },
885 { "OleObject_AddRef", TEST_OPTIONAL },
886 { "OleObject_Release", TEST_OPTIONAL },
887 { "OleObject_QueryInterface", TEST_OPTIONAL },
888 { "OleObjectPersistStg_AddRef", 0 },
889 { "OleObjectPersistStg_InitNew", 0 },
890 { "OleObjectPersistStg_Release", 0 },
891 { "OleObject_Release", 0 },
892 { "OleObject_Release", TEST_OPTIONAL },
893 { NULL, 0 }
895 static const struct expected_method methods_olerender_draw[] =
897 { "OleObject_QueryInterface", 0 },
898 { "OleObject_AddRef", 0 },
899 { "OleObject_QueryInterface", 0 },
900 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
901 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
902 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
903 { "OleObjectPersistStg_AddRef", 0 },
904 { "OleObjectPersistStg_InitNew", 0 },
905 { "OleObjectPersistStg_Release", 0 },
906 { "OleObject_QueryInterface", 0 },
907 { "OleObjectRunnable_AddRef", 0 },
908 { "OleObjectRunnable_Run", 0 },
909 { "OleObjectRunnable_Release", 0 },
910 { "OleObject_QueryInterface", 0 },
911 { "OleObjectCache_AddRef", 0 },
912 { "OleObjectCache_Cache", 0 },
913 { "OleObjectCache_Release", 0 },
914 { "OleObject_Release", 0 },
915 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
916 { NULL, 0 }
918 static const struct expected_method methods_olerender_draw_with_site[] =
920 { "OleObject_QueryInterface", 0 },
921 { "OleObject_AddRef", 0 },
922 { "OleObject_QueryInterface", 0 },
923 { "OleObject_AddRef", 0 },
924 { "OleObject_GetMiscStatus", 0 },
925 { "OleObject_QueryInterface", 0 },
926 { "OleObjectPersistStg_AddRef", 0 },
927 { "OleObjectPersistStg_InitNew", 0 },
928 { "OleObjectPersistStg_Release", 0 },
929 { "OleObject_SetClientSite", 0 },
930 { "OleObject_Release", 0 },
931 { "OleObject_QueryInterface", 0 },
932 { "OleObjectRunnable_AddRef", 0 },
933 { "OleObjectRunnable_Run", 0 },
934 { "OleObjectRunnable_Release", 0 },
935 { "OleObject_QueryInterface", 0 },
936 { "OleObjectCache_AddRef", 0 },
937 { "OleObjectCache_Cache", 0 },
938 { "OleObjectCache_Release", 0 },
939 { "OleObject_Release", 0 },
940 { NULL, 0 }
942 static const struct expected_method methods_olerender_format[] =
944 { "OleObject_QueryInterface", 0 },
945 { "OleObject_AddRef", 0 },
946 { "OleObject_QueryInterface", 0 },
947 { "OleObject_AddRef", 0 },
948 { "OleObject_GetMiscStatus", 0 },
949 { "OleObject_QueryInterface", 0 },
950 { "OleObjectPersistStg_AddRef", 0 },
951 { "OleObjectPersistStg_InitNew", 0 },
952 { "OleObjectPersistStg_Release", 0 },
953 { "OleObject_SetClientSite", 0 },
954 { "OleObject_Release", 0 },
955 { "OleObject_QueryInterface", 0 },
956 { "OleObjectRunnable_AddRef", 0 },
957 { "OleObjectRunnable_Run", 0 },
958 { "OleObjectRunnable_Release", 0 },
959 { "OleObject_QueryInterface", 0 },
960 { "OleObjectCache_AddRef", 0 },
961 { "OleObjectCache_Cache", 0 },
962 { "OleObjectCache_Release", 0 },
963 { "OleObject_Release", 0 },
964 { NULL, 0 }
966 static const struct expected_method methods_olerender_asis[] =
968 { "OleObject_QueryInterface", 0 },
969 { "OleObject_AddRef", 0 },
970 { "OleObject_QueryInterface", 0 },
971 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
972 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
973 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
974 { "OleObjectPersistStg_AddRef", 0 },
975 { "OleObjectPersistStg_InitNew", 0 },
976 { "OleObjectPersistStg_Release", 0 },
977 { "OleObject_Release", 0 },
978 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
979 { NULL, 0 }
981 static const struct expected_method methods_olerender_draw_no_runnable[] =
983 { "OleObject_QueryInterface", 0 },
984 { "OleObject_AddRef", 0 },
985 { "OleObject_QueryInterface", 0 },
986 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
987 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
988 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
989 { "OleObjectPersistStg_AddRef", 0 },
990 { "OleObjectPersistStg_InitNew", 0 },
991 { "OleObjectPersistStg_Release", 0 },
992 { "OleObject_QueryInterface", 0 },
993 { "OleObject_QueryInterface", 0 },
994 { "OleObjectCache_AddRef", 0 },
995 { "OleObjectCache_Cache", 0 },
996 { "OleObjectCache_Release", 0 },
997 { "OleObject_Release", 0 },
998 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
999 { NULL, 0 },
1001 static const struct expected_method methods_olerender_draw_no_cache[] =
1003 { "OleObject_QueryInterface", 0 },
1004 { "OleObject_AddRef", 0 },
1005 { "OleObject_QueryInterface", 0 },
1006 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
1007 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1008 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
1009 { "OleObjectPersistStg_AddRef", 0 },
1010 { "OleObjectPersistStg_InitNew", 0 },
1011 { "OleObjectPersistStg_Release", 0 },
1012 { "OleObject_QueryInterface", 0 },
1013 { "OleObjectRunnable_AddRef", 0 },
1014 { "OleObjectRunnable_Run", 0 },
1015 { "OleObjectRunnable_Release", 0 },
1016 { "OleObject_QueryInterface", 0 },
1017 { "OleObject_Release", 0 },
1018 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1019 { NULL, 0 }
1022 g_expected_fetc = &formatetc;
1023 formatetc.cfFormat = 0;
1024 formatetc.ptd = NULL;
1025 formatetc.dwAspect = DVASPECT_CONTENT;
1026 formatetc.lindex = -1;
1027 formatetc.tymed = TYMED_NULL;
1028 runnable = &OleObjectRunnable;
1029 cache = &OleObjectCache;
1030 expected_method_list = methods_olerender_none;
1031 trace("OleCreate with OLERENDER_NONE:\n");
1032 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject);
1033 ok_ole_success(hr, "OleCreate");
1034 IOleObject_Release(pObject);
1035 CHECK_NO_EXTRA_METHODS();
1037 expected_method_list = methods_olerender_draw;
1038 trace("OleCreate with OLERENDER_DRAW:\n");
1039 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1040 ok_ole_success(hr, "OleCreate");
1041 IOleObject_Release(pObject);
1042 CHECK_NO_EXTRA_METHODS();
1044 expected_method_list = methods_olerender_draw_with_site;
1045 trace("OleCreate with OLERENDER_DRAW, with site:\n");
1046 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject);
1047 ok_ole_success(hr, "OleCreate");
1048 IOleObject_Release(pObject);
1049 CHECK_NO_EXTRA_METHODS();
1051 /* GetMiscStatus fails */
1052 g_GetMiscStatusFailsWith = 0x8fafefaf;
1053 expected_method_list = methods_olerender_draw_with_site;
1054 trace("OleCreate with OLERENDER_DRAW, with site:\n");
1055 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject);
1056 ok_ole_success(hr, "OleCreate");
1057 IOleObject_Release(pObject);
1058 CHECK_NO_EXTRA_METHODS();
1059 g_GetMiscStatusFailsWith = S_OK;
1061 formatetc.cfFormat = CF_TEXT;
1062 formatetc.ptd = NULL;
1063 formatetc.dwAspect = DVASPECT_CONTENT;
1064 formatetc.lindex = -1;
1065 formatetc.tymed = TYMED_HGLOBAL;
1066 expected_method_list = methods_olerender_format;
1067 trace("OleCreate with OLERENDER_FORMAT:\n");
1068 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject);
1069 ok(hr == S_OK ||
1070 broken(hr == E_INVALIDARG), /* win2k */
1071 "OleCreate failed with error 0x%08x\n", hr);
1072 if (pObject)
1074 IOleObject_Release(pObject);
1075 CHECK_NO_EXTRA_METHODS();
1078 expected_method_list = methods_olerender_asis;
1079 trace("OleCreate with OLERENDER_ASIS:\n");
1080 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject);
1081 ok_ole_success(hr, "OleCreate");
1082 IOleObject_Release(pObject);
1083 CHECK_NO_EXTRA_METHODS();
1085 formatetc.cfFormat = 0;
1086 formatetc.tymed = TYMED_NULL;
1087 runnable = NULL;
1088 expected_method_list = methods_olerender_draw_no_runnable;
1089 trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
1090 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1091 ok_ole_success(hr, "OleCreate");
1092 IOleObject_Release(pObject);
1093 CHECK_NO_EXTRA_METHODS();
1095 runnable = &OleObjectRunnable;
1096 cache = NULL;
1097 expected_method_list = methods_olerender_draw_no_cache;
1098 trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n");
1099 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1100 ok_ole_success(hr, "OleCreate");
1101 IOleObject_Release(pObject);
1102 CHECK_NO_EXTRA_METHODS();
1103 trace("end\n");
1104 g_expected_fetc = NULL;
1107 static void test_OleLoad(IStorage *pStorage)
1109 HRESULT hr;
1110 IOleObject *pObject;
1111 DWORD fmt;
1113 static const struct expected_method methods_oleload[] =
1115 { "OleObject_QueryInterface", 0 },
1116 { "OleObject_AddRef", 0 },
1117 { "OleObject_QueryInterface", 0 },
1118 { "OleObject_AddRef", 0 },
1119 { "OleObject_GetMiscStatus", 0 },
1120 { "OleObject_QueryInterface", 0 },
1121 { "OleObjectPersistStg_AddRef", 0 },
1122 { "OleObjectPersistStg_Load", 0 },
1123 { "OleObjectPersistStg_Release", 0 },
1124 { "OleObject_SetClientSite", 0 },
1125 { "OleObject_Release", 0 },
1126 { "OleObject_QueryInterface", 0 },
1127 { "OleObject_GetMiscStatus", 0 },
1128 { "OleObject_Release", 0 },
1129 { NULL, 0 }
1132 /* Test once with IOleObject_GetMiscStatus failing */
1133 expected_method_list = methods_oleload;
1134 g_GetMiscStatusFailsWith = E_FAIL;
1135 trace("OleLoad:\n");
1136 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1137 ok(hr == S_OK ||
1138 broken(hr == E_INVALIDARG), /* win98 and win2k */
1139 "OleLoad failed with error 0x%08x\n", hr);
1140 if(pObject)
1142 DWORD dwStatus = 0xdeadbeef;
1143 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1144 ok(hr == E_FAIL, "Got 0x%08x\n", hr);
1145 ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus);
1147 IOleObject_Release(pObject);
1148 CHECK_NO_EXTRA_METHODS();
1150 g_GetMiscStatusFailsWith = S_OK;
1152 /* Test again, let IOleObject_GetMiscStatus succeed. */
1153 expected_method_list = methods_oleload;
1154 trace("OleLoad:\n");
1155 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1156 ok(hr == S_OK ||
1157 broken(hr == E_INVALIDARG), /* win98 and win2k */
1158 "OleLoad failed with error 0x%08x\n", hr);
1159 if (pObject)
1161 DWORD dwStatus = 0xdeadbeef;
1162 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1163 ok(hr == S_OK, "Got 0x%08x\n", hr);
1164 ok(dwStatus == 1, "Got 0x%08x\n", dwStatus);
1166 IOleObject_Release(pObject);
1167 CHECK_NO_EXTRA_METHODS();
1170 for (fmt = CF_TEXT; fmt < CF_MAX; fmt++)
1172 static const WCHAR olrepres[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 };
1173 IStorage *stg;
1174 IStream *stream;
1175 IUnknown *obj;
1176 DWORD data, i, tymed, data_size;
1177 PresentationDataHeader header;
1178 HDC hdc;
1179 HGDIOBJ hobj;
1180 RECT rc;
1181 char buf[256];
1183 for (i = 0; i < 7; i++)
1185 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &stg);
1186 ok(hr == S_OK, "StgCreateDocfile error %#x\n", hr);
1188 hr = IStorage_SetClass(stg, &CLSID_WineTest);
1189 ok(hr == S_OK, "SetClass error %#x\n", hr);
1191 hr = IStorage_CreateStream(stg, olrepres, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stream);
1192 ok(hr == S_OK, "CreateStream error %#x\n", hr);
1194 data = ~0;
1195 hr = IStream_Write(stream, &data, sizeof(data), NULL);
1196 ok(hr == S_OK, "Write error %#x\n", hr);
1198 data = fmt;
1199 hr = IStream_Write(stream, &data, sizeof(data), NULL);
1200 ok(hr == S_OK, "Write error %#x\n", hr);
1202 switch (fmt)
1204 case CF_BITMAP:
1205 /* FIXME: figure out stream format */
1206 hobj = CreateBitmap(1, 1, 1, 1, NULL);
1207 data_size = GetBitmapBits(hobj, sizeof(buf), buf);
1208 DeleteObject(hobj);
1209 break;
1211 case CF_METAFILEPICT:
1212 case CF_ENHMETAFILE:
1213 hdc = CreateMetaFileA(NULL);
1214 hobj = CloseMetaFile(hdc);
1215 data_size = GetMetaFileBitsEx(hobj, sizeof(buf), buf);
1216 DeleteMetaFile(hobj);
1217 break;
1219 default:
1220 data_size = sizeof(buf);
1221 memset(buf, 'A', sizeof(buf));
1222 break;
1225 tymed = 1 << i;
1227 header.unknown3 = 4;
1228 header.dvAspect = DVASPECT_CONTENT;
1229 header.lindex = -1;
1230 header.tymed = tymed;
1231 header.unknown7 = 0;
1232 header.dwObjectExtentX = 1;
1233 header.dwObjectExtentY = 1;
1234 header.dwSize = data_size;
1235 hr = IStream_Write(stream, &header, sizeof(header), NULL);
1236 ok(hr == S_OK, "Write error %#x\n", hr);
1238 hr = IStream_Write(stream, buf, data_size, NULL);
1239 ok(hr == S_OK, "Write error %#x\n", hr);
1241 IStream_Release(stream);
1243 hr = OleLoad(stg, &IID_IUnknown, NULL, (void **)&obj);
1244 /* FIXME: figure out stream format */
1245 if (fmt == CF_BITMAP && hr != S_OK)
1247 IStorage_Release(stg);
1248 continue;
1250 ok(hr == S_OK, "OleLoad error %#x: cfFormat = %u, tymed = %u\n", hr, fmt, tymed);
1252 hdc = CreateCompatibleDC(0);
1253 SetRect(&rc, 0, 0, 100, 100);
1254 hr = OleDraw(obj, DVASPECT_CONTENT, hdc, &rc);
1255 DeleteDC(hdc);
1256 if (fmt == CF_METAFILEPICT)
1257 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, tymed = %u\n", hr, fmt, tymed);
1258 else if (fmt == CF_ENHMETAFILE)
1259 todo_wine
1260 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, tymed = %u\n", hr, fmt, tymed);
1261 else
1262 ok(hr == OLE_E_BLANK || hr == OLE_E_NOTRUNNING || hr == E_FAIL, "OleDraw should fail: %#x, cfFormat = %u, tymed = %u\n", hr, fmt, header.tymed);
1264 IUnknown_Release(obj);
1265 IStorage_Release(stg);
1270 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param)
1272 CHECK_EXPECTED_METHOD("draw_continue");
1273 return TRUE;
1276 static BOOL STDMETHODCALLTYPE draw_continue_false(ULONG_PTR param)
1278 CHECK_EXPECTED_METHOD("draw_continue_false");
1279 return FALSE;
1282 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv)
1284 if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown))
1286 *ppv = iface;
1287 IAdviseSink_AddRef(iface);
1288 return S_OK;
1290 *ppv = NULL;
1291 return E_NOINTERFACE;
1294 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface)
1296 return 2;
1299 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface)
1301 return 1;
1305 static void WINAPI AdviseSink_OnDataChange(
1306 IAdviseSink *iface,
1307 FORMATETC *pFormatetc,
1308 STGMEDIUM *pStgmed)
1310 CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
1313 static void WINAPI AdviseSink_OnViewChange(
1314 IAdviseSink *iface,
1315 DWORD dwAspect,
1316 LONG lindex)
1318 CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
1321 static void WINAPI AdviseSink_OnRename(
1322 IAdviseSink *iface,
1323 IMoniker *pmk)
1325 CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
1328 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface)
1330 CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
1333 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface)
1335 CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
1338 static const IAdviseSinkVtbl AdviseSinkVtbl =
1340 AdviseSink_QueryInterface,
1341 AdviseSink_AddRef,
1342 AdviseSink_Release,
1343 AdviseSink_OnDataChange,
1344 AdviseSink_OnViewChange,
1345 AdviseSink_OnRename,
1346 AdviseSink_OnSave,
1347 AdviseSink_OnClose
1350 static IAdviseSink AdviseSink = { &AdviseSinkVtbl };
1352 static HRESULT WINAPI DataObject_QueryInterface(
1353 IDataObject* iface,
1354 REFIID riid,
1355 void** ppvObject)
1357 CHECK_EXPECTED_METHOD("DataObject_QueryInterface");
1359 if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
1361 *ppvObject = iface;
1362 return S_OK;
1364 *ppvObject = NULL;
1365 return S_OK;
1368 static ULONG WINAPI DataObject_AddRef(
1369 IDataObject* iface)
1371 CHECK_EXPECTED_METHOD("DataObject_AddRef");
1372 return 2;
1375 static ULONG WINAPI DataObject_Release(
1376 IDataObject* iface)
1378 CHECK_EXPECTED_METHOD("DataObject_Release");
1379 return 1;
1382 static HRESULT WINAPI DataObject_GetData(
1383 IDataObject* iface,
1384 LPFORMATETC pformatetcIn,
1385 STGMEDIUM* pmedium)
1387 CHECK_EXPECTED_METHOD("DataObject_GetData");
1388 return E_NOTIMPL;
1391 static HRESULT WINAPI DataObject_GetDataHere(
1392 IDataObject* iface,
1393 LPFORMATETC pformatetc,
1394 STGMEDIUM* pmedium)
1396 CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1397 return E_NOTIMPL;
1400 static HRESULT WINAPI DataObject_QueryGetData(
1401 IDataObject* iface,
1402 LPFORMATETC pformatetc)
1404 CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
1405 return S_OK;
1408 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
1409 IDataObject* iface,
1410 LPFORMATETC pformatectIn,
1411 LPFORMATETC pformatetcOut)
1413 CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1414 return E_NOTIMPL;
1417 static HRESULT WINAPI DataObject_SetData(
1418 IDataObject* iface,
1419 LPFORMATETC pformatetc,
1420 STGMEDIUM* pmedium,
1421 BOOL fRelease)
1423 CHECK_EXPECTED_METHOD("DataObject_SetData");
1424 return E_NOTIMPL;
1427 static HRESULT WINAPI DataObject_EnumFormatEtc(
1428 IDataObject* iface,
1429 DWORD dwDirection,
1430 IEnumFORMATETC** ppenumFormatEtc)
1432 CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1433 return E_NOTIMPL;
1436 static HRESULT WINAPI DataObject_DAdvise(
1437 IDataObject* iface,
1438 FORMATETC* pformatetc,
1439 DWORD advf,
1440 IAdviseSink* pAdvSink,
1441 DWORD* pdwConnection)
1443 STGMEDIUM stgmedium;
1445 CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1446 *pdwConnection = 1;
1448 if(advf & ADVF_PRIMEFIRST)
1450 ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat);
1451 stgmedium.tymed = TYMED_HGLOBAL;
1452 U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4);
1453 stgmedium.pUnkForRelease = NULL;
1454 IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium);
1457 return S_OK;
1460 static HRESULT WINAPI DataObject_DUnadvise(
1461 IDataObject* iface,
1462 DWORD dwConnection)
1464 CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1465 return S_OK;
1468 static HRESULT WINAPI DataObject_EnumDAdvise(
1469 IDataObject* iface,
1470 IEnumSTATDATA** ppenumAdvise)
1472 CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1473 return OLE_E_ADVISENOTSUPPORTED;
1476 static IDataObjectVtbl DataObjectVtbl =
1478 DataObject_QueryInterface,
1479 DataObject_AddRef,
1480 DataObject_Release,
1481 DataObject_GetData,
1482 DataObject_GetDataHere,
1483 DataObject_QueryGetData,
1484 DataObject_GetCanonicalFormatEtc,
1485 DataObject_SetData,
1486 DataObject_EnumFormatEtc,
1487 DataObject_DAdvise,
1488 DataObject_DUnadvise,
1489 DataObject_EnumDAdvise
1492 static IDataObject DataObject = { &DataObjectVtbl };
1494 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
1496 *ppv = NULL;
1497 if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface;
1498 if (*ppv)
1500 IUnknown_AddRef((IUnknown *)*ppv);
1501 return S_OK;
1503 return E_NOINTERFACE;
1506 static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
1508 return 2;
1511 static ULONG WINAPI Unknown_Release(IUnknown *iface)
1513 return 1;
1516 static const IUnknownVtbl UnknownVtbl =
1518 Unknown_QueryInterface,
1519 Unknown_AddRef,
1520 Unknown_Release
1523 static IUnknown unknown = { &UnknownVtbl };
1525 static void test_data_cache(void)
1527 HRESULT hr;
1528 IOleCache2 *pOleCache;
1529 IOleCache *olecache;
1530 IStorage *pStorage;
1531 IUnknown *unk;
1532 IPersistStorage *pPS;
1533 IViewObject *pViewObject;
1534 IOleCacheControl *pOleCacheControl;
1535 IDataObject *pCacheDataObject;
1536 FORMATETC fmtetc;
1537 STGMEDIUM stgmedium;
1538 DWORD dwConnection;
1539 DWORD dwFreeze;
1540 RECTL rcBounds;
1541 HDC hdcMem;
1542 CLSID clsid;
1543 char szSystemDir[MAX_PATH];
1544 WCHAR wszPath[MAX_PATH];
1545 static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1547 static const struct expected_method methods_cacheinitnew[] =
1549 { "AdviseSink_OnViewChange", 0 },
1550 { "AdviseSink_OnViewChange", 0 },
1551 { "draw_continue", 1 },
1552 { "draw_continue_false", 1 },
1553 { "DataObject_DAdvise", 0 },
1554 { "DataObject_DAdvise", 0 },
1555 { "DataObject_DUnadvise", 0 },
1556 { "DataObject_DUnadvise", 0 },
1557 { NULL, 0 }
1559 static const struct expected_method methods_cacheload[] =
1561 { "AdviseSink_OnViewChange", 0 },
1562 { "draw_continue", 1 },
1563 { "draw_continue", 1 },
1564 { "draw_continue", 1 },
1565 { "DataObject_GetData", 0 },
1566 { "DataObject_GetData", 0 },
1567 { "DataObject_GetData", 0 },
1568 { NULL, 0 }
1570 static const struct expected_method methods_cachethenrun[] =
1572 { "DataObject_DAdvise", 0 },
1573 { "DataObject_DAdvise", 0 },
1574 { "DataObject_DAdvise", 0 },
1575 { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */
1576 { "DataObject_DAdvise", 0 },
1577 { "DataObject_DUnadvise", 0 },
1578 { "DataObject_DUnadvise", 0 },
1579 { "DataObject_DUnadvise", 0 },
1580 { "DataObject_DUnadvise", 0 },
1581 { NULL, 0 }
1584 GetSystemDirectoryA(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
1586 expected_method_list = methods_cacheinitnew;
1588 fmtetc.cfFormat = CF_METAFILEPICT;
1589 fmtetc.dwAspect = DVASPECT_ICON;
1590 fmtetc.lindex = -1;
1591 fmtetc.ptd = NULL;
1592 fmtetc.tymed = TYMED_MFPICT;
1594 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1595 ok_ole_success(hr, "StgCreateDocfile");
1597 /* aggregation */
1599 /* requested is not IUnknown */
1600 hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IOleCache2, (void**)&pOleCache);
1601 todo_wine
1602 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1604 hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IUnknown, (void**)&unk);
1605 ok(hr == S_OK, "got 0x%08x\n", hr);
1607 hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache);
1608 ok(hr == S_OK, "got 0x%08x\n", hr);
1609 hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache);
1610 ok(hr == S_OK, "got 0x%08x\n", hr);
1611 ok(unk != (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk);
1612 ok(unk != (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk);
1613 IOleCache2_Release(pOleCache);
1614 IOleCache_Release(olecache);
1615 IUnknown_Release(unk);
1617 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void**)&unk);
1618 ok(hr == S_OK, "got 0x%08x\n", hr);
1619 hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache);
1620 ok(hr == S_OK, "got 0x%08x\n", hr);
1621 hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache);
1622 ok(hr == S_OK, "got 0x%08x\n", hr);
1623 todo_wine {
1624 ok(unk == (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk);
1625 ok(unk == (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk);
1627 IOleCache2_Release(pOleCache);
1628 IOleCache_Release(olecache);
1629 IUnknown_Release(unk);
1631 /* Test with new data */
1633 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1634 ok_ole_success(hr, "CreateDataCache");
1636 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1637 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1638 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1639 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1640 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1641 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1643 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1644 ok_ole_success(hr, "IViewObject_SetAdvise");
1646 hr = IPersistStorage_InitNew(pPS, pStorage);
1647 ok_ole_success(hr, "IPersistStorage_InitNew");
1649 hr = IPersistStorage_IsDirty(pPS);
1650 ok_ole_success(hr, "IPersistStorage_IsDirty");
1652 hr = IPersistStorage_GetClassID(pPS, &clsid);
1653 ok_ole_success(hr, "IPersistStorage_GetClassID");
1654 ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n");
1656 hr = IOleCache2_Uncache(pOleCache, 0xdeadbeef);
1657 ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr);
1659 /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1660 if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
1662 hr = IOleCache2_Cache(pOleCache, NULL, 0, &dwConnection);
1663 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1665 hr = IOleCache2_Cache(pOleCache, NULL, 0, NULL);
1666 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1668 else
1670 skip("tests with NULL parameters will crash on NT4 and below\n");
1673 for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++)
1675 int i;
1676 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1677 for (i = 0; i < 7; i++)
1679 fmtetc.tymed = 1 << i;
1680 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1681 if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) ||
1682 (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) ||
1683 (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) ||
1684 (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF))
1685 ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1686 fmtetc.cfFormat, fmtetc.tymed, hr);
1687 else if (fmtetc.tymed == TYMED_HGLOBAL)
1688 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED ||
1689 broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */,
1690 "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1691 fmtetc.cfFormat, fmtetc.tymed, hr);
1692 else
1693 ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1694 fmtetc.cfFormat, fmtetc.tymed, hr);
1695 if (SUCCEEDED(hr))
1697 hr = IOleCache2_Uncache(pOleCache, dwConnection);
1698 ok_ole_success(hr, "IOleCache_Uncache");
1703 fmtetc.cfFormat = CF_BITMAP;
1704 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1705 fmtetc.tymed = TYMED_GDI;
1706 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1707 ok_ole_success(hr, "IOleCache_Cache");
1709 fmtetc.cfFormat = 0;
1710 fmtetc.dwAspect = DVASPECT_ICON;
1711 fmtetc.tymed = TYMED_MFPICT;
1712 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1713 ok_ole_success(hr, "IOleCache_Cache");
1715 MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
1716 memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
1718 fmtetc.cfFormat = CF_METAFILEPICT;
1719 stgmedium.tymed = TYMED_MFPICT;
1720 U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel(
1721 LoadIconA(NULL, (LPSTR)IDI_APPLICATION), wszPath, wszPath, 0);
1722 stgmedium.pUnkForRelease = NULL;
1724 fmtetc.dwAspect = DVASPECT_CONTENT;
1725 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1726 ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr);
1728 fmtetc.dwAspect = DVASPECT_ICON;
1729 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1730 ok_ole_success(hr, "IOleCache_SetData");
1731 ReleaseStgMedium(&stgmedium);
1733 hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze);
1734 todo_wine {
1735 ok_ole_success(hr, "IViewObject_Freeze");
1736 hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze);
1737 ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1740 rcBounds.left = 0;
1741 rcBounds.top = 0;
1742 rcBounds.right = 100;
1743 rcBounds.bottom = 100;
1744 hdcMem = CreateCompatibleDC(NULL);
1746 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1747 ok_ole_success(hr, "IViewObject_Draw");
1749 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1750 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1752 /* a NULL draw_continue fn ptr */
1753 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef);
1754 ok_ole_success(hr, "IViewObject_Draw");
1756 /* draw_continue that returns FALSE to abort drawing */
1757 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef);
1758 ok(hr == E_ABORT ||
1759 broken(hr == S_OK), /* win9x may skip the callbacks */
1760 "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr);
1762 DeleteDC(hdcMem);
1764 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1765 ok_ole_success(hr, "IOleCacheControl_OnRun");
1767 hr = IPersistStorage_Save(pPS, pStorage, TRUE);
1768 ok_ole_success(hr, "IPersistStorage_Save");
1770 hr = IPersistStorage_SaveCompleted(pPS, NULL);
1771 ok_ole_success(hr, "IPersistStorage_SaveCompleted");
1773 hr = IPersistStorage_IsDirty(pPS);
1774 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1776 IPersistStorage_Release(pPS);
1777 IViewObject_Release(pViewObject);
1778 IOleCache2_Release(pOleCache);
1779 IOleCacheControl_Release(pOleCacheControl);
1781 CHECK_NO_EXTRA_METHODS();
1783 /* Test with loaded data */
1784 trace("Testing loaded data with CreateDataCache:\n");
1785 expected_method_list = methods_cacheload;
1787 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1788 ok_ole_success(hr, "CreateDataCache");
1790 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1791 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1792 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1793 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1795 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1796 ok_ole_success(hr, "IViewObject_SetAdvise");
1798 hr = IPersistStorage_Load(pPS, pStorage);
1799 ok_ole_success(hr, "IPersistStorage_Load");
1801 hr = IPersistStorage_IsDirty(pPS);
1802 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1804 fmtetc.cfFormat = 0;
1805 fmtetc.dwAspect = DVASPECT_ICON;
1806 fmtetc.lindex = -1;
1807 fmtetc.ptd = NULL;
1808 fmtetc.tymed = TYMED_MFPICT;
1809 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1810 ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr);
1812 rcBounds.left = 0;
1813 rcBounds.top = 0;
1814 rcBounds.right = 100;
1815 rcBounds.bottom = 100;
1816 hdcMem = CreateCompatibleDC(NULL);
1818 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1819 ok_ole_success(hr, "IViewObject_Draw");
1821 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1822 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1824 /* unload the cached storage object, causing it to be reloaded */
1825 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1826 ok_ole_success(hr, "IOleCache2_DiscardCache");
1827 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1828 ok_ole_success(hr, "IViewObject_Draw");
1830 /* unload the cached storage object, but don't allow it to be reloaded */
1831 hr = IPersistStorage_HandsOffStorage(pPS);
1832 ok_ole_success(hr, "IPersistStorage_HandsOffStorage");
1833 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1834 ok_ole_success(hr, "IViewObject_Draw");
1835 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1836 ok_ole_success(hr, "IOleCache2_DiscardCache");
1837 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1838 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1840 DeleteDC(hdcMem);
1842 todo_wine {
1843 hr = IOleCache2_InitCache(pOleCache, &DataObject);
1844 ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr);
1847 IPersistStorage_Release(pPS);
1848 IViewObject_Release(pViewObject);
1849 IOleCache2_Release(pOleCache);
1851 todo_wine {
1852 CHECK_NO_EXTRA_METHODS();
1855 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1856 ok_ole_success(hr, "CreateDataCache");
1858 expected_method_list = methods_cachethenrun;
1860 hr = IOleCache2_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject);
1861 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)");
1862 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1863 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1865 fmtetc.cfFormat = CF_METAFILEPICT;
1866 fmtetc.dwAspect = DVASPECT_CONTENT;
1867 fmtetc.tymed = TYMED_MFPICT;
1869 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1870 ok_ole_success(hr, "IOleCache_Cache");
1872 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1873 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1875 fmtetc.cfFormat = cf_test_1;
1876 fmtetc.dwAspect = DVASPECT_CONTENT;
1877 fmtetc.tymed = TYMED_HGLOBAL;
1879 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1880 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1882 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1883 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1885 fmtetc.cfFormat = cf_test_2;
1886 hr = IOleCache2_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection);
1887 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1889 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1890 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1892 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1893 ok_ole_success(hr, "IOleCacheControl_OnRun");
1895 fmtetc.cfFormat = cf_test_3;
1896 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1897 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1899 fmtetc.cfFormat = cf_test_1;
1900 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1901 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1903 fmtetc.cfFormat = cf_test_2;
1904 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1905 ok(hr == S_OK, "got %08x\n", hr);
1906 ReleaseStgMedium(&stgmedium);
1908 fmtetc.cfFormat = cf_test_3;
1909 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1910 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1912 IOleCacheControl_Release(pOleCacheControl);
1913 IDataObject_Release(pCacheDataObject);
1914 IOleCache2_Release(pOleCache);
1916 CHECK_NO_EXTRA_METHODS();
1918 IStorage_Release(pStorage);
1922 static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
1924 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
1925 static BYTE dib[] =
1927 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
1928 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
1930 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
1931 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
1933 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
1934 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
1936 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1937 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1940 static IStorage *create_storage( int num )
1942 IStorage *stg;
1943 IStream *stm;
1944 HRESULT hr;
1945 ULONG written;
1947 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg );
1948 ok( hr == S_OK, "got %08x\n", hr);
1949 hr = IStorage_SetClass( stg, &CLSID_Picture_Dib );
1950 ok( hr == S_OK, "got %08x\n", hr);
1951 hr = IStorage_CreateStream( stg, CONTENTS, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stm );
1952 ok( hr == S_OK, "got %08x\n", hr);
1953 if (num == 1) /* Set biXPelsPerMeter = 0 */
1955 dib[0x26] = 0;
1956 dib[0x27] = 0;
1958 hr = IStream_Write( stm, dib, sizeof(dib), &written );
1959 ok( hr == S_OK, "got %08x\n", hr);
1960 IStream_Release( stm );
1961 return stg;
1964 static void test_data_cache_dib_contents_stream(int num)
1966 HRESULT hr;
1967 IUnknown *unk;
1968 IPersistStorage *persist;
1969 IDataObject *data;
1970 IViewObject2 *view;
1971 IStorage *stg;
1972 FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
1973 STGMEDIUM med;
1974 CLSID cls;
1975 SIZEL sz;
1977 hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk );
1978 ok( SUCCEEDED(hr), "got %08x\n", hr );
1979 hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void **)&persist );
1980 ok( SUCCEEDED(hr), "got %08x\n", hr );
1981 hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void **)&data );
1982 ok( SUCCEEDED(hr), "got %08x\n", hr );
1983 hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view );
1984 ok( SUCCEEDED(hr), "got %08x\n", hr );
1986 stg = create_storage( num );
1988 hr = IPersistStorage_Load( persist, stg );
1989 ok( SUCCEEDED(hr), "got %08x\n", hr );
1990 IStorage_Release( stg );
1992 hr = IPersistStorage_GetClassID( persist, &cls );
1993 ok( SUCCEEDED(hr), "got %08x\n", hr );
1994 ok( IsEqualCLSID( &cls, &CLSID_Picture_Dib ), "class id mismatch\n" );
1996 hr = IDataObject_GetData( data, &fmt, &med );
1997 ok( SUCCEEDED(hr), "got %08x\n", hr );
1998 if (SUCCEEDED(hr))
2000 ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed );
2001 ReleaseStgMedium( &med );
2004 hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz );
2005 ok( SUCCEEDED(hr), "got %08x\n", hr );
2006 if (num == 0)
2008 ok( sz.cx == 1000, "got %d\n", sz.cx );
2009 ok( sz.cy == 250, "got %d\n", sz.cy );
2011 else
2013 HDC hdc = GetDC( 0 );
2014 LONG x = 2 * 2540 / GetDeviceCaps( hdc, LOGPIXELSX );
2015 LONG y = 1 * 2540 / GetDeviceCaps( hdc, LOGPIXELSY );
2016 ok( sz.cx == x, "got %d %d\n", sz.cx, x );
2017 ok( sz.cy == y, "got %d %d\n", sz.cy, y );
2019 ReleaseDC( 0, hdc );
2022 IViewObject2_Release( view );
2023 IDataObject_Release( data );
2024 IPersistStorage_Release( persist );
2025 IUnknown_Release( unk );
2028 static void test_default_handler(void)
2030 HRESULT hr;
2031 IOleObject *pObject;
2032 IRunnableObject *pRunnableObject;
2033 IOleClientSite *pClientSite;
2034 IDataObject *pDataObject;
2035 SIZEL sizel;
2036 DWORD dwStatus;
2037 CLSID clsid;
2038 LPOLESTR pszUserType;
2039 LOGPALETTE palette;
2040 DWORD dwAdvConn;
2041 IMoniker *pMoniker;
2042 FORMATETC fmtetc;
2043 IOleInPlaceObject *pInPlaceObj;
2044 IEnumOLEVERB *pEnumVerbs;
2045 DWORD dwRegister;
2046 static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0};
2047 static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
2048 static const WCHAR wszDelim[] = {'!',0};
2050 static const struct expected_method methods_embeddinghelper[] =
2052 { "OleObject_QueryInterface", 0 },
2053 { "OleObject_AddRef", 0 },
2054 { "OleObject_QueryInterface", 0 },
2055 { "OleObject_QueryInterface", TEST_TODO },
2056 { "OleObject_QueryInterface", 0 },
2057 { "OleObject_QueryInterface", 0 },
2058 { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */
2059 { "OleObject_Release", TEST_TODO },
2060 { "WINE_EXTRA", TEST_OPTIONAL },
2061 { NULL, 0 }
2064 hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject);
2065 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2067 hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject);
2068 ok_ole_success(hr, "OleCreateDefaultHandler");
2070 hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj);
2071 ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr);
2073 hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn);
2074 ok_ole_success(hr, "IOleObject_Advise");
2076 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
2077 ok_ole_success(hr, "IOleObject_Close");
2079 /* FIXME: test IOleObject_EnumAdvise */
2081 hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs);
2082 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2084 hr = IOleObject_GetClientSite(pObject, &pClientSite);
2085 ok_ole_success(hr, "IOleObject_GetClientSite");
2087 hr = IOleObject_SetClientSite(pObject, pClientSite);
2088 ok_ole_success(hr, "IOleObject_SetClientSite");
2090 hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject);
2091 ok(hr == OLE_E_NOTRUNNING,
2092 "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
2093 hr);
2095 hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel);
2096 ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
2097 hr);
2099 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
2100 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2102 hr = IOleObject_GetUserClassID(pObject, &clsid);
2103 ok_ole_success(hr, "IOleObject_GetUserClassID");
2104 ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n");
2106 hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType);
2107 todo_wine {
2108 ok_ole_success(hr, "IOleObject_GetUserType");
2109 ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n");
2112 hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0);
2113 ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2115 hr = IOleObject_IsUpToDate(pObject);
2116 ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2118 palette.palNumEntries = 1;
2119 palette.palVersion = 2;
2120 memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0]));
2121 hr = IOleObject_SetColorScheme(pObject, &palette);
2122 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2124 sizel.cx = sizel.cy = 0;
2125 hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
2126 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2128 hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
2129 ok_ole_success(hr, "IOleObject_SetHostNames");
2131 hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker);
2132 ok_ole_success(hr, "CreateItemMoniker");
2133 hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker);
2134 ok_ole_success(hr, "IOleObject_SetMoniker");
2135 IMoniker_Release(pMoniker);
2137 hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker);
2138 ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr);
2140 hr = IOleObject_Update(pObject);
2141 todo_wine
2142 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2144 hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject);
2145 ok_ole_success(hr, "IOleObject_QueryInterface");
2147 fmtetc.cfFormat = CF_TEXT;
2148 fmtetc.ptd = NULL;
2149 fmtetc.dwAspect = DVASPECT_CONTENT;
2150 fmtetc.lindex = -1;
2151 fmtetc.tymed = TYMED_NULL;
2152 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
2153 ok_ole_success(hr, "IDataObject_DAdvise");
2155 fmtetc.cfFormat = CF_ENHMETAFILE;
2156 fmtetc.ptd = NULL;
2157 fmtetc.dwAspect = DVASPECT_CONTENT;
2158 fmtetc.lindex = -1;
2159 fmtetc.tymed = TYMED_ENHMF;
2160 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
2161 ok_ole_success(hr, "IDataObject_DAdvise");
2163 fmtetc.cfFormat = CF_ENHMETAFILE;
2164 fmtetc.ptd = NULL;
2165 fmtetc.dwAspect = DVASPECT_CONTENT;
2166 fmtetc.lindex = -1;
2167 fmtetc.tymed = TYMED_ENHMF;
2168 hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
2169 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2171 fmtetc.cfFormat = CF_TEXT;
2172 fmtetc.ptd = NULL;
2173 fmtetc.dwAspect = DVASPECT_CONTENT;
2174 fmtetc.lindex = -1;
2175 fmtetc.tymed = TYMED_NULL;
2176 hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
2177 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2179 hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject);
2180 ok_ole_success(hr, "IOleObject_QueryInterface");
2182 hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE);
2183 ok_ole_success(hr, "IRunnableObject_SetContainedObject");
2185 hr = IRunnableObject_Run(pRunnableObject, NULL);
2186 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2188 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
2189 ok_ole_success(hr, "IOleObject_Close");
2191 IRunnableObject_Release(pRunnableObject);
2192 IOleObject_Release(pObject);
2194 /* Test failure propagation from delegate ::QueryInterface */
2195 hr = CoRegisterClassObject(&CLSID_WineTest, (IUnknown*)&OleObjectCF,
2196 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
2197 ok_ole_success(hr, "CoRegisterClassObject");
2198 if(SUCCEEDED(hr))
2200 expected_method_list = methods_embeddinghelper;
2201 hr = OleCreateEmbeddingHelper(&CLSID_WineTest, NULL, EMBDHLP_INPROC_SERVER,
2202 &OleObjectCF, &IID_IOleObject, (void**)&pObject);
2203 ok_ole_success(hr, "OleCreateEmbeddingHelper");
2204 if(SUCCEEDED(hr))
2206 IUnknown *punk;
2208 g_QIFailsWith = E_FAIL;
2209 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2210 ok(hr == E_FAIL, "Got 0x%08x\n", hr);
2212 g_QIFailsWith = E_NOINTERFACE;
2213 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2214 ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
2216 g_QIFailsWith = CO_E_OBJNOTCONNECTED;
2217 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2218 ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr);
2220 g_QIFailsWith = 0x87654321;
2221 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2222 ok(hr == 0x87654321, "Got 0x%08x\n", hr);
2224 IOleObject_Release(pObject);
2227 CHECK_NO_EXTRA_METHODS();
2229 hr = CoRevokeClassObject(dwRegister);
2230 ok_ole_success(hr, "CoRevokeClassObject");
2234 static void test_runnable(void)
2236 static const struct expected_method methods_query_runnable[] =
2238 { "OleObject_QueryInterface", 0 },
2239 { "OleObjectRunnable_AddRef", 0 },
2240 { "OleObjectRunnable_IsRunning", 0 },
2241 { "OleObjectRunnable_Release", 0 },
2242 { NULL, 0 }
2245 static const struct expected_method methods_no_runnable[] =
2247 { "OleObject_QueryInterface", 0 },
2248 { NULL, 0 }
2251 BOOL ret;
2252 IOleObject *object = &OleObject;
2254 /* null argument */
2255 ret = OleIsRunning(NULL);
2256 ok(ret == FALSE, "got %d\n", ret);
2258 expected_method_list = methods_query_runnable;
2259 ret = OleIsRunning(object);
2260 ok(ret == TRUE, "Object should be running\n");
2261 CHECK_NO_EXTRA_METHODS();
2263 g_isRunning = FALSE;
2264 expected_method_list = methods_query_runnable;
2265 ret = OleIsRunning(object);
2266 ok(ret == FALSE, "Object should not be running\n");
2267 CHECK_NO_EXTRA_METHODS();
2269 g_showRunnable = FALSE; /* QueryInterface(IID_IRunnableObject, ...) will fail */
2270 expected_method_list = methods_no_runnable;
2271 ret = OleIsRunning(object);
2272 ok(ret == TRUE, "Object without IRunnableObject should be running\n");
2273 CHECK_NO_EXTRA_METHODS();
2275 g_isRunning = TRUE;
2276 g_showRunnable = TRUE;
2280 static HRESULT WINAPI OleRun_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
2282 *ppv = NULL;
2284 if (IsEqualIID(riid, &IID_IUnknown) ||
2285 IsEqualIID(riid, &IID_IRunnableObject)) {
2286 *ppv = iface;
2289 if (*ppv)
2291 IUnknown_AddRef((IUnknown *)*ppv);
2292 return S_OK;
2295 return E_NOINTERFACE;
2298 static ULONG WINAPI OleRun_AddRef(IRunnableObject *iface)
2300 return 2;
2303 static ULONG WINAPI OleRun_Release(IRunnableObject *iface)
2305 return 1;
2308 static HRESULT WINAPI OleRun_GetRunningClass(IRunnableObject *iface, CLSID *clsid)
2310 ok(0, "unexpected\n");
2311 return E_NOTIMPL;
2314 static HRESULT WINAPI OleRun_Run(IRunnableObject *iface, LPBINDCTX ctx)
2316 ok(ctx == NULL, "got %p\n", ctx);
2317 return 0xdeadc0de;
2320 static BOOL WINAPI OleRun_IsRunning(IRunnableObject *iface)
2322 ok(0, "unexpected\n");
2323 return FALSE;
2326 static HRESULT WINAPI OleRun_LockRunning(IRunnableObject *iface, BOOL lock,
2327 BOOL last_unlock_closes)
2329 ok(0, "unexpected\n");
2330 return E_NOTIMPL;
2333 static HRESULT WINAPI OleRun_SetContainedObject(IRunnableObject *iface, BOOL contained)
2335 ok(0, "unexpected\n");
2336 return E_NOTIMPL;
2339 static const IRunnableObjectVtbl oleruntestvtbl =
2341 OleRun_QueryInterface,
2342 OleRun_AddRef,
2343 OleRun_Release,
2344 OleRun_GetRunningClass,
2345 OleRun_Run,
2346 OleRun_IsRunning,
2347 OleRun_LockRunning,
2348 OleRun_SetContainedObject
2351 static IRunnableObject testrunnable = { &oleruntestvtbl };
2353 static void test_OleRun(void)
2355 HRESULT hr;
2357 /* doesn't support IRunnableObject */
2358 hr = OleRun(&unknown);
2359 ok(hr == S_OK, "OleRun failed 0x%08x\n", hr);
2361 hr = OleRun((IUnknown*)&testrunnable);
2362 ok(hr == 0xdeadc0de, "got 0x%08x\n", hr);
2365 static void test_OleLockRunning(void)
2367 HRESULT hr;
2369 hr = OleLockRunning(&unknown, TRUE, FALSE);
2370 ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
2373 static void test_OleDraw(void)
2375 HRESULT hr;
2376 RECT rect;
2378 hr = OleDraw((IUnknown*)&viewobject, 0, (HDC)0x1, NULL);
2379 ok(hr == S_OK, "got 0x%08x\n", hr);
2381 hr = OleDraw(NULL, 0, (HDC)0x1, NULL);
2382 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2384 hr = OleDraw(NULL, 0, (HDC)0x1, &rect);
2385 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2388 static const WCHAR comp_objW[] = {1,'C','o','m','p','O','b','j',0};
2389 static IStream *comp_obj_stream;
2390 static IStream *ole_stream;
2392 static HRESULT WINAPI Storage_QueryInterface(IStorage *iface, REFIID riid, void **ppvObject)
2394 ok(0, "unexpected call to QueryInterface\n");
2395 return E_NOTIMPL;
2398 static ULONG WINAPI Storage_AddRef(IStorage *iface)
2400 ok(0, "unexpected call to AddRef\n");
2401 return 2;
2404 static ULONG WINAPI Storage_Release(IStorage *iface)
2406 ok(0, "unexpected call to Release\n");
2407 return 1;
2410 static HRESULT WINAPI Storage_CreateStream(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm)
2412 ULARGE_INTEGER size = {{0}};
2413 LARGE_INTEGER pos = {{0}};
2414 HRESULT hr;
2416 CHECK_EXPECT(Storage_CreateStream_CompObj);
2417 ok(!lstrcmpW(pwcsName, comp_objW), "pwcsName = %s\n", wine_dbgstr_w(pwcsName));
2418 todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
2419 ok(!reserved1, "reserved1 = %x\n", reserved1);
2420 ok(!reserved2, "reserved2 = %x\n", reserved2);
2421 ok(!!ppstm, "ppstm = NULL\n");
2423 *ppstm = comp_obj_stream;
2424 IStream_AddRef(comp_obj_stream);
2425 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2426 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2427 hr = IStream_SetSize(comp_obj_stream, size);
2428 ok(hr == S_OK, "IStream_SetSize returned %x\n", hr);
2429 return S_OK;
2432 static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm)
2434 static const WCHAR ole1W[] = {1,'O','l','e',0};
2436 LARGE_INTEGER pos = {{0}};
2437 HRESULT hr;
2439 ok(!reserved1, "reserved1 = %p\n", reserved1);
2440 ok(!reserved2, "reserved2 = %x\n", reserved2);
2441 ok(!!ppstm, "ppstm = NULL\n");
2443 if(!lstrcmpW(pwcsName, comp_objW)) {
2444 CHECK_EXPECT2(Storage_OpenStream_CompObj);
2445 ok(grfMode == STGM_SHARE_EXCLUSIVE, "grfMode = %x\n", grfMode);
2447 *ppstm = comp_obj_stream;
2448 IStream_AddRef(comp_obj_stream);
2449 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2450 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2451 return S_OK;
2452 }else if(!lstrcmpW(pwcsName, ole1W)) {
2453 CHECK_EXPECT(Storage_OpenStream_Ole);
2454 ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
2456 *ppstm = ole_stream;
2457 IStream_AddRef(ole_stream);
2458 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
2459 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2460 return S_OK;
2463 ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName));
2464 return E_NOTIMPL;
2467 static HRESULT WINAPI Storage_CreateStorage(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD dwStgFmt, DWORD reserved2, IStorage **ppstg)
2469 ok(0, "unexpected call to CreateStorage\n");
2470 return E_NOTIMPL;
2473 static HRESULT WINAPI Storage_OpenStorage(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg)
2475 ok(0, "unexpected call to OpenStorage\n");
2476 return E_NOTIMPL;
2479 static HRESULT WINAPI Storage_CopyTo(IStorage *iface, DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest)
2481 ok(0, "unexpected call to CopyTo\n");
2482 return E_NOTIMPL;
2485 static HRESULT WINAPI Storage_MoveElementTo(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgDest, LPCOLESTR pwcsNewName, DWORD grfFlags)
2487 ok(0, "unexpected call to MoveElementTo\n");
2488 return E_NOTIMPL;
2491 static HRESULT WINAPI Storage_Commit(IStorage *iface, DWORD grfCommitFlags)
2493 ok(0, "unexpected call to Commit\n");
2494 return E_NOTIMPL;
2497 static HRESULT WINAPI Storage_Revert(IStorage *iface)
2499 ok(0, "unexpected call to Revert\n");
2500 return E_NOTIMPL;
2503 static HRESULT WINAPI Storage_EnumElements(IStorage *iface, DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum)
2505 ok(0, "unexpected call to EnumElements\n");
2506 return E_NOTIMPL;
2509 static HRESULT WINAPI Storage_DestroyElement(IStorage *iface, LPCOLESTR pwcsName)
2511 ok(0, "unexpected call to DestroyElement\n");
2512 return E_NOTIMPL;
2515 static HRESULT WINAPI Storage_RenameElement(IStorage *iface, LPCOLESTR pwcsOldName, LPCOLESTR pwcsNewName)
2517 ok(0, "unexpected call to RenameElement\n");
2518 return E_NOTIMPL;
2521 static HRESULT WINAPI Storage_SetElementTimes(IStorage *iface, LPCOLESTR pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime)
2523 ok(0, "unexpected call to SetElementTimes\n");
2524 return E_NOTIMPL;
2527 static HRESULT WINAPI Storage_SetClass(IStorage *iface, REFCLSID clsid)
2529 CHECK_EXPECT(Storage_SetClass);
2530 ok(IsEqualIID(clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(clsid));
2531 return S_OK;
2534 static HRESULT WINAPI Storage_SetStateBits(IStorage *iface, DWORD grfStateBits, DWORD grfMask)
2536 ok(0, "unexpected call to SetStateBits\n");
2537 return E_NOTIMPL;
2540 static HRESULT WINAPI Storage_Stat(IStorage *iface, STATSTG *pstatstg, DWORD grfStatFlag)
2542 CHECK_EXPECT2(Storage_Stat);
2543 ok(pstatstg != NULL, "pstatstg = NULL\n");
2544 ok(grfStatFlag == STATFLAG_NONAME, "grfStatFlag = %x\n", grfStatFlag);
2546 memset(pstatstg, 0, sizeof(STATSTG));
2547 pstatstg->type = STGTY_STORAGE;
2548 pstatstg->clsid = CLSID_WineTestOld;
2549 return S_OK;
2552 static IStorageVtbl StorageVtbl =
2554 Storage_QueryInterface,
2555 Storage_AddRef,
2556 Storage_Release,
2557 Storage_CreateStream,
2558 Storage_OpenStream,
2559 Storage_CreateStorage,
2560 Storage_OpenStorage,
2561 Storage_CopyTo,
2562 Storage_MoveElementTo,
2563 Storage_Commit,
2564 Storage_Revert,
2565 Storage_EnumElements,
2566 Storage_DestroyElement,
2567 Storage_RenameElement,
2568 Storage_SetElementTimes,
2569 Storage_SetClass,
2570 Storage_SetStateBits,
2571 Storage_Stat
2574 static IStorage Storage = { &StorageVtbl };
2576 static void test_OleDoAutoConvert(void)
2578 static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0};
2579 static struct {
2580 DWORD reserved1;
2581 DWORD version;
2582 DWORD reserved2[5];
2583 DWORD ansi_user_type_len;
2584 DWORD ansi_clipboard_format_len;
2585 DWORD reserved3;
2586 DWORD unicode_marker;
2587 DWORD unicode_user_type_len;
2588 DWORD unicode_clipboard_format_len;
2589 DWORD reserved4;
2590 } comp_obj_data;
2591 static struct {
2592 DWORD version;
2593 DWORD flags;
2594 DWORD link_update_option;
2595 DWORD reserved1;
2596 DWORD reserved_moniker_stream_size;
2597 DWORD relative_source_moniker_stream_size;
2598 DWORD absolute_source_moniker_stream_size;
2599 DWORD clsid_indicator;
2600 CLSID clsid;
2601 DWORD reserved_display_name;
2602 DWORD reserved2;
2603 DWORD local_update_time;
2604 DWORD local_check_update_time;
2605 DWORD remote_update_time;
2606 } ole_data;
2608 LARGE_INTEGER pos = {{0}};
2609 WCHAR buf[39+6];
2610 DWORD i, ret;
2611 HKEY root;
2612 CLSID clsid;
2613 HRESULT hr;
2615 hr = CreateStreamOnHGlobal(NULL, TRUE, &comp_obj_stream);
2616 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
2617 hr = IStream_Write(comp_obj_stream, (char*)&comp_obj_data, sizeof(comp_obj_data), NULL);
2618 ok(hr == S_OK, "IStream_Write returned %x\n", hr);
2620 hr = CreateStreamOnHGlobal(NULL, TRUE, &ole_stream);
2621 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
2622 hr = IStream_Write(ole_stream, (char*)&ole_data, sizeof(ole_data), NULL);
2623 ok(hr == S_OK, "IStream_Write returned %x\n", hr);
2625 clsid = IID_WineTest;
2626 hr = OleDoAutoConvert(NULL, &clsid);
2627 ok(hr == E_INVALIDARG, "OleDoAutoConvert returned %x\n", hr);
2628 ok(IsEqualIID(&clsid, &IID_NULL), "clsid = %s\n", wine_dbgstr_guid(&clsid));
2630 if(0) /* crashes on Win7 */
2631 OleDoAutoConvert(&Storage, NULL);
2633 clsid = IID_WineTest;
2634 SET_EXPECT(Storage_Stat);
2635 hr = OleDoAutoConvert(&Storage, &clsid);
2636 ok(hr == REGDB_E_CLASSNOTREG, "OleDoAutoConvert returned %x\n", hr);
2637 CHECK_CALLED(Storage_Stat);
2638 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
2640 lstrcpyW(buf, clsidW);
2641 StringFromGUID2(&CLSID_WineTestOld, buf+6, 39);
2643 ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
2644 KEY_READ | KEY_WRITE | KEY_CREATE_SUB_KEY, NULL, &root, NULL);
2645 if(ret != ERROR_SUCCESS) {
2646 win_skip("not enough permissions to create CLSID key (%u)\n", ret);
2647 return;
2650 clsid = IID_WineTest;
2651 SET_EXPECT(Storage_Stat);
2652 hr = OleDoAutoConvert(&Storage, &clsid);
2653 ok(hr == REGDB_E_KEYMISSING, "OleDoAutoConvert returned %x\n", hr);
2654 CHECK_CALLED(Storage_Stat);
2655 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
2657 hr = OleSetAutoConvert(&CLSID_WineTestOld, &CLSID_WineTest);
2658 ok_ole_success(hr, "OleSetAutoConvert");
2660 hr = OleGetAutoConvert(&CLSID_WineTestOld, &clsid);
2661 ok_ole_success(hr, "OleGetAutoConvert");
2662 ok(IsEqualIID(&clsid, &CLSID_WineTest), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid));
2664 clsid = IID_WineTest;
2665 SET_EXPECT(Storage_Stat);
2666 SET_EXPECT(Storage_OpenStream_CompObj);
2667 SET_EXPECT(Storage_SetClass);
2668 SET_EXPECT(Storage_CreateStream_CompObj);
2669 SET_EXPECT(Storage_OpenStream_Ole);
2670 hr = OleDoAutoConvert(&Storage, &clsid);
2671 ok(hr == S_OK, "OleDoAutoConvert returned %x\n", hr);
2672 CHECK_CALLED(Storage_Stat);
2673 CHECK_CALLED(Storage_OpenStream_CompObj);
2674 CHECK_CALLED(Storage_SetClass);
2675 CHECK_CALLED(Storage_CreateStream_CompObj);
2676 CHECK_CALLED(Storage_OpenStream_Ole);
2677 ok(IsEqualIID(&clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(&clsid));
2679 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2680 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2681 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
2682 ok(hr == S_OK, "IStream_Read returned %x\n", hr);
2683 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
2684 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
2685 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
2686 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
2687 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
2688 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
2689 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
2690 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
2691 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
2692 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
2693 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
2695 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
2696 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2697 hr = IStream_Read(ole_stream, &ole_data, sizeof(ole_data), NULL);
2698 ok(hr == S_OK, "IStream_Read returned %x\n", hr);
2699 ok(ole_data.version == 0, "version = %x\n", ole_data.version);
2700 ok(ole_data.flags == 4, "flags = %x\n", ole_data.flags);
2701 for(i=2; i<sizeof(ole_data)/sizeof(DWORD); i++)
2702 ok(((DWORD*)&ole_data)[i] == 0, "ole_data[%d] = %x\n", i, ((DWORD*)&ole_data)[i]);
2704 SET_EXPECT(Storage_OpenStream_Ole);
2705 hr = SetConvertStg(&Storage, TRUE);
2706 ok(hr == S_OK, "SetConvertStg returned %x\n", hr);
2707 CHECK_CALLED(Storage_OpenStream_Ole);
2709 SET_EXPECT(Storage_OpenStream_CompObj);
2710 SET_EXPECT(Storage_Stat);
2711 SET_EXPECT(Storage_CreateStream_CompObj);
2712 hr = WriteFmtUserTypeStg(&Storage, 0, NULL);
2713 ok(hr == S_OK, "WriteFmtUserTypeStg returned %x\n", hr);
2714 todo_wine CHECK_CALLED(Storage_OpenStream_CompObj);
2715 CHECK_CALLED(Storage_Stat);
2716 CHECK_CALLED(Storage_CreateStream_CompObj);
2717 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2718 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2719 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
2720 ok(hr == S_OK, "IStream_Read returned %x\n", hr);
2721 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
2722 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
2723 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
2724 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
2725 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
2726 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
2727 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
2728 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
2729 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
2730 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
2731 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
2733 ret = IStream_Release(comp_obj_stream);
2734 ok(!ret, "comp_obj_stream was not freed\n");
2735 ret = IStream_Release(ole_stream);
2736 ok(!ret, "ole_stream was not freed\n");
2738 ret = RegDeleteKeyA(root, "AutoConvertTo");
2739 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
2740 ret = RegDeleteKeyA(root, "");
2741 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
2742 RegCloseKey(root);
2745 START_TEST(ole2)
2747 DWORD dwRegister;
2748 IStorage *pStorage;
2749 STATSTG statstg;
2750 HRESULT hr;
2752 cf_test_1 = RegisterClipboardFormatA("cf_winetest_1");
2753 cf_test_2 = RegisterClipboardFormatA("cf_winetest_2");
2754 cf_test_3 = RegisterClipboardFormatA("cf_winetest_3");
2756 CoInitialize(NULL);
2758 hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
2759 ok_ole_success(hr, "CoRegisterClassObject");
2761 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
2762 ok_ole_success(hr, "StgCreateDocfile");
2764 test_OleCreate(pStorage);
2766 hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME);
2767 ok_ole_success(hr, "IStorage_Stat");
2768 ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n");
2770 test_OleLoad(pStorage);
2772 IStorage_Release(pStorage);
2774 hr = CoRevokeClassObject(dwRegister);
2775 ok_ole_success(hr, "CoRevokeClassObject");
2777 test_data_cache();
2778 test_data_cache_dib_contents_stream( 0 );
2779 test_data_cache_dib_contents_stream( 1 );
2780 test_default_handler();
2781 test_runnable();
2782 test_OleRun();
2783 test_OleLockRunning();
2784 test_OleDraw();
2785 test_OleDoAutoConvert();
2787 CoUninitialize();