ole32: In the non-aggregated case a request for IUnknown actually returns IOleCache2.
[wine.git] / dlls / ole32 / tests / ole2.c
blob1e5ca65bf21fb81f38ff863be408de2df0c744c0
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);
39 DEFINE_GUID(CLSID_Picture_EnhMetafile,0x319,0,0,0xc0,0,0,0,0,0,0,0x46);
41 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
43 #define DEFINE_EXPECT(func) \
44 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
46 #define SET_EXPECT(func) \
47 expect_ ## func = TRUE
49 #define CHECK_EXPECT2(func) \
50 do { \
51 ok(expect_ ##func, "unexpected call " #func "\n"); \
52 called_ ## func = TRUE; \
53 }while(0)
55 #define CHECK_EXPECT(func) \
56 do { \
57 CHECK_EXPECT2(func); \
58 expect_ ## func = FALSE; \
59 }while(0)
61 #define CHECK_CALLED(func) \
62 do { \
63 ok(called_ ## func, "expected " #func "\n"); \
64 expect_ ## func = called_ ## func = FALSE; \
65 }while(0)
67 DEFINE_EXPECT(Storage_Stat);
68 DEFINE_EXPECT(Storage_OpenStream_CompObj);
69 DEFINE_EXPECT(Storage_SetClass);
70 DEFINE_EXPECT(Storage_CreateStream_CompObj);
71 DEFINE_EXPECT(Storage_OpenStream_Ole);
73 static IPersistStorage OleObjectPersistStg;
74 static IOleCache *cache;
75 static IRunnableObject *runnable;
77 static const CLSID CLSID_WineTestOld =
78 { /* 9474ba1a-258b-490b-bc13-516e9239acd0 */
79 0x9474ba1a,
80 0x258b,
81 0x490b,
82 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xd0}
85 static const CLSID CLSID_WineTest =
86 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
87 0x9474ba1a,
88 0x258b,
89 0x490b,
90 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
93 static const IID IID_WineTest =
94 { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */
95 0x9474ba1a,
96 0x258b,
97 0x490b,
98 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1}
101 #define TEST_OPTIONAL 0x1
102 #define TEST_TODO 0x2
104 struct expected_method
106 const char *method;
107 unsigned int flags;
110 static const struct expected_method *expected_method_list;
111 static FORMATETC *g_expected_fetc = NULL;
113 static BOOL g_showRunnable = TRUE;
114 static BOOL g_isRunning = TRUE;
115 static HRESULT g_GetMiscStatusFailsWith = S_OK;
116 static HRESULT g_QIFailsWith;
118 static UINT cf_test_1, cf_test_2, cf_test_3;
120 /****************************************************************************
121 * PresentationDataHeader
123 * This structure represents the header of the \002OlePresXXX stream in
124 * the OLE object storage.
126 typedef struct PresentationDataHeader
128 /* clipformat:
129 * - standard clipformat:
130 * DWORD length = 0xffffffff;
131 * DWORD cfFormat;
132 * - or custom clipformat:
133 * DWORD length;
134 * CHAR format_name[length]; (null-terminated)
136 DWORD unknown3; /* 4, possibly TYMED_ISTREAM */
137 DVASPECT dvAspect;
138 DWORD lindex;
139 DWORD advf;
140 DWORD unknown7; /* 0 */
141 DWORD dwObjectExtentX;
142 DWORD dwObjectExtentY;
143 DWORD dwSize;
144 } PresentationDataHeader;
146 #define CHECK_EXPECTED_METHOD(method_name) \
147 do { \
148 trace("%s\n", method_name); \
149 ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \
150 if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \
152 todo_wine ok(0, "Too many method calls.\n"); \
153 break; \
155 if (expected_method_list->method) \
157 while (expected_method_list->flags & TEST_OPTIONAL && \
158 strcmp(expected_method_list->method, method_name) != 0) \
159 expected_method_list++; \
160 todo_wine_if (expected_method_list->flags & TEST_TODO) \
161 ok(!strcmp(expected_method_list->method, method_name), \
162 "Expected %s to be called instead of %s\n", \
163 expected_method_list->method, method_name); \
164 expected_method_list++; \
166 } while(0)
168 #define CHECK_NO_EXTRA_METHODS() \
169 do { \
170 while (expected_method_list->flags & TEST_OPTIONAL) \
171 expected_method_list++; \
172 ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
173 } while (0)
175 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
177 CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
179 *ppv = NULL;
181 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject))
182 *ppv = iface;
183 else if (IsEqualIID(riid, &IID_IPersistStorage))
184 *ppv = &OleObjectPersistStg;
185 else if (IsEqualIID(riid, &IID_IOleCache))
186 *ppv = cache;
187 else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable)
188 *ppv = runnable;
189 else if (IsEqualIID(riid, &IID_WineTest))
190 return g_QIFailsWith;
192 if(*ppv) {
193 IUnknown_AddRef((IUnknown*)*ppv);
194 return S_OK;
197 trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
198 return E_NOINTERFACE;
201 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
203 CHECK_EXPECTED_METHOD("OleObject_AddRef");
204 return 2;
207 static ULONG WINAPI OleObject_Release(IOleObject *iface)
209 CHECK_EXPECTED_METHOD("OleObject_Release");
210 return 1;
213 static HRESULT WINAPI OleObject_SetClientSite
215 IOleObject *iface,
216 IOleClientSite *pClientSite
219 CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
220 return S_OK;
223 static HRESULT WINAPI OleObject_GetClientSite
225 IOleObject *iface,
226 IOleClientSite **ppClientSite
229 CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
230 return E_NOTIMPL;
233 static HRESULT WINAPI OleObject_SetHostNames
235 IOleObject *iface,
236 LPCOLESTR szContainerApp,
237 LPCOLESTR szContainerObj
240 CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
241 return S_OK;
244 static HRESULT WINAPI OleObject_Close
246 IOleObject *iface,
247 DWORD dwSaveOption
250 CHECK_EXPECTED_METHOD("OleObject_Close");
251 return S_OK;
254 static HRESULT WINAPI OleObject_SetMoniker
256 IOleObject *iface,
257 DWORD dwWhichMoniker,
258 IMoniker *pmk
261 CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
262 return S_OK;
265 static HRESULT WINAPI OleObject_GetMoniker
267 IOleObject *iface,
268 DWORD dwAssign,
269 DWORD dwWhichMoniker,
270 IMoniker **ppmk
273 CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
274 return S_OK;
277 static HRESULT WINAPI OleObject_InitFromData
279 IOleObject *iface,
280 IDataObject *pDataObject,
281 BOOL fCreation,
282 DWORD dwReserved
285 CHECK_EXPECTED_METHOD("OleObject_InitFromData");
286 return S_OK;
289 static HRESULT WINAPI OleObject_GetClipboardData
291 IOleObject *iface,
292 DWORD dwReserved,
293 IDataObject **ppDataObject
296 CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
297 return E_NOTIMPL;
300 static HRESULT WINAPI OleObject_DoVerb
302 IOleObject *iface,
303 LONG iVerb,
304 LPMSG lpmsg,
305 IOleClientSite *pActiveSite,
306 LONG lindex,
307 HWND hwndParent,
308 LPCRECT lprcPosRect
311 CHECK_EXPECTED_METHOD("OleObject_DoVerb");
312 return S_OK;
315 static HRESULT WINAPI OleObject_EnumVerbs
317 IOleObject *iface,
318 IEnumOLEVERB **ppEnumOleVerb
321 CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
322 return E_NOTIMPL;
325 static HRESULT WINAPI OleObject_Update
327 IOleObject *iface
330 CHECK_EXPECTED_METHOD("OleObject_Update");
331 return S_OK;
334 static HRESULT WINAPI OleObject_IsUpToDate
336 IOleObject *iface
339 CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
340 return S_OK;
343 static HRESULT WINAPI OleObject_GetUserClassID
345 IOleObject *iface,
346 CLSID *pClsid
349 CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
350 return E_NOTIMPL;
353 static HRESULT WINAPI OleObject_GetUserType
355 IOleObject *iface,
356 DWORD dwFormOfType,
357 LPOLESTR *pszUserType
360 CHECK_EXPECTED_METHOD("OleObject_GetUserType");
361 return E_NOTIMPL;
364 static HRESULT WINAPI OleObject_SetExtent
366 IOleObject *iface,
367 DWORD dwDrawAspect,
368 SIZEL *psizel
371 CHECK_EXPECTED_METHOD("OleObject_SetExtent");
372 return S_OK;
375 static HRESULT WINAPI OleObject_GetExtent
377 IOleObject *iface,
378 DWORD dwDrawAspect,
379 SIZEL *psizel
382 CHECK_EXPECTED_METHOD("OleObject_GetExtent");
383 return E_NOTIMPL;
386 static HRESULT WINAPI OleObject_Advise
388 IOleObject *iface,
389 IAdviseSink *pAdvSink,
390 DWORD *pdwConnection
393 CHECK_EXPECTED_METHOD("OleObject_Advise");
394 return S_OK;
397 static HRESULT WINAPI OleObject_Unadvise
399 IOleObject *iface,
400 DWORD dwConnection
403 CHECK_EXPECTED_METHOD("OleObject_Unadvise");
404 return S_OK;
407 static HRESULT WINAPI OleObject_EnumAdvise
409 IOleObject *iface,
410 IEnumSTATDATA **ppenumAdvise
413 CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
414 return E_NOTIMPL;
417 static HRESULT WINAPI OleObject_GetMiscStatus
419 IOleObject *iface,
420 DWORD aspect,
421 DWORD *pdwStatus
424 CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
426 ok(aspect == DVASPECT_CONTENT, "got aspect %d\n", aspect);
428 if (g_GetMiscStatusFailsWith == S_OK)
430 *pdwStatus = OLEMISC_RECOMPOSEONRESIZE;
431 return S_OK;
433 else
435 *pdwStatus = 0x1234;
436 return g_GetMiscStatusFailsWith;
440 static HRESULT WINAPI OleObject_SetColorScheme
442 IOleObject *iface,
443 LOGPALETTE *pLogpal
446 CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
447 return E_NOTIMPL;
450 static const IOleObjectVtbl OleObjectVtbl =
452 OleObject_QueryInterface,
453 OleObject_AddRef,
454 OleObject_Release,
455 OleObject_SetClientSite,
456 OleObject_GetClientSite,
457 OleObject_SetHostNames,
458 OleObject_Close,
459 OleObject_SetMoniker,
460 OleObject_GetMoniker,
461 OleObject_InitFromData,
462 OleObject_GetClipboardData,
463 OleObject_DoVerb,
464 OleObject_EnumVerbs,
465 OleObject_Update,
466 OleObject_IsUpToDate,
467 OleObject_GetUserClassID,
468 OleObject_GetUserType,
469 OleObject_SetExtent,
470 OleObject_GetExtent,
471 OleObject_Advise,
472 OleObject_Unadvise,
473 OleObject_EnumAdvise,
474 OleObject_GetMiscStatus,
475 OleObject_SetColorScheme
478 static IOleObject OleObject = { &OleObjectVtbl };
480 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv)
482 trace("OleObjectPersistStg_QueryInterface\n");
483 return IOleObject_QueryInterface(&OleObject, riid, ppv);
486 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface)
488 CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
489 return 2;
492 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface)
494 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
495 return 1;
498 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid)
500 CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
501 return E_NOTIMPL;
504 static HRESULT WINAPI OleObjectPersistStg_IsDirty
506 IPersistStorage *iface
509 CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
510 return S_OK;
513 static HRESULT WINAPI OleObjectPersistStg_InitNew
515 IPersistStorage *iface,
516 IStorage *pStg
519 CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
520 return S_OK;
523 static HRESULT WINAPI OleObjectPersistStg_Load
525 IPersistStorage *iface,
526 IStorage *pStg
529 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
530 return S_OK;
533 static HRESULT WINAPI OleObjectPersistStg_Save
535 IPersistStorage *iface,
536 IStorage *pStgSave,
537 BOOL fSameAsLoad
540 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
541 return S_OK;
544 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
546 IPersistStorage *iface,
547 IStorage *pStgNew
550 CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
551 return S_OK;
554 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
556 IPersistStorage *iface
559 CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
560 return S_OK;
563 static const IPersistStorageVtbl OleObjectPersistStgVtbl =
565 OleObjectPersistStg_QueryInterface,
566 OleObjectPersistStg_AddRef,
567 OleObjectPersistStg_Release,
568 OleObjectPersistStg_GetClassId,
569 OleObjectPersistStg_IsDirty,
570 OleObjectPersistStg_InitNew,
571 OleObjectPersistStg_Load,
572 OleObjectPersistStg_Save,
573 OleObjectPersistStg_SaveCompleted,
574 OleObjectPersistStg_HandsOffStorage
577 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl };
579 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv)
581 return IOleObject_QueryInterface(&OleObject, riid, ppv);
584 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface)
586 CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
587 return 2;
590 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface)
592 CHECK_EXPECTED_METHOD("OleObjectCache_Release");
593 return 1;
596 static HRESULT WINAPI OleObjectCache_Cache
598 IOleCache *iface,
599 FORMATETC *pformatetc,
600 DWORD advf,
601 DWORD *pdwConnection
604 CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
605 if (g_expected_fetc) {
606 ok(pformatetc != NULL, "pformatetc should not be NULL\n");
607 if (pformatetc) {
608 ok(pformatetc->cfFormat == g_expected_fetc->cfFormat,
609 "cfFormat: %x\n", pformatetc->cfFormat);
610 ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL),
611 "ptd: %p\n", pformatetc->ptd);
612 ok(pformatetc->dwAspect == g_expected_fetc->dwAspect,
613 "dwAspect: %x\n", pformatetc->dwAspect);
614 ok(pformatetc->lindex == g_expected_fetc->lindex,
615 "lindex: %x\n", pformatetc->lindex);
616 ok(pformatetc->tymed == g_expected_fetc->tymed,
617 "tymed: %x\n", pformatetc->tymed);
619 } else
620 ok(pformatetc == NULL, "pformatetc should be NULL\n");
621 return S_OK;
624 static HRESULT WINAPI OleObjectCache_Uncache
626 IOleCache *iface,
627 DWORD dwConnection
630 CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
631 return S_OK;
634 static HRESULT WINAPI OleObjectCache_EnumCache
636 IOleCache *iface,
637 IEnumSTATDATA **ppenumSTATDATA
640 CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
641 return S_OK;
645 static HRESULT WINAPI OleObjectCache_InitCache
647 IOleCache *iface,
648 IDataObject *pDataObject
651 CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
652 return S_OK;
656 static HRESULT WINAPI OleObjectCache_SetData
658 IOleCache *iface,
659 FORMATETC *pformatetc,
660 STGMEDIUM *pmedium,
661 BOOL fRelease
664 CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
665 return S_OK;
669 static const IOleCacheVtbl OleObjectCacheVtbl =
671 OleObjectCache_QueryInterface,
672 OleObjectCache_AddRef,
673 OleObjectCache_Release,
674 OleObjectCache_Cache,
675 OleObjectCache_Uncache,
676 OleObjectCache_EnumCache,
677 OleObjectCache_InitCache,
678 OleObjectCache_SetData
681 static IOleCache OleObjectCache = { &OleObjectCacheVtbl };
683 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
685 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
687 *ppv = iface;
688 IClassFactory_AddRef(iface);
689 return S_OK;
691 *ppv = NULL;
692 return E_NOINTERFACE;
695 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface)
697 return 2;
700 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface)
702 return 1;
705 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv)
707 return IOleObject_QueryInterface(&OleObject, riid, ppv);
710 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock)
712 return S_OK;
715 static const IClassFactoryVtbl OleObjectCFVtbl =
717 OleObjectCF_QueryInterface,
718 OleObjectCF_AddRef,
719 OleObjectCF_Release,
720 OleObjectCF_CreateInstance,
721 OleObjectCF_LockServer
724 static IClassFactory OleObjectCF = { &OleObjectCFVtbl };
726 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
728 return IOleObject_QueryInterface(&OleObject, riid, ppv);
731 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface)
733 CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
734 return 2;
737 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface)
739 CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
740 return 1;
743 static HRESULT WINAPI OleObjectRunnable_GetRunningClass(
744 IRunnableObject *iface,
745 LPCLSID lpClsid)
747 CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
748 return E_NOTIMPL;
751 static HRESULT WINAPI OleObjectRunnable_Run(
752 IRunnableObject *iface,
753 LPBINDCTX pbc)
755 CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
756 return S_OK;
759 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface)
761 CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
762 return g_isRunning;
765 static HRESULT WINAPI OleObjectRunnable_LockRunning(
766 IRunnableObject *iface,
767 BOOL fLock,
768 BOOL fLastUnlockCloses)
770 CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
771 return S_OK;
774 static HRESULT WINAPI OleObjectRunnable_SetContainedObject(
775 IRunnableObject *iface,
776 BOOL fContained)
778 CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
779 return S_OK;
782 static const IRunnableObjectVtbl OleObjectRunnableVtbl =
784 OleObjectRunnable_QueryInterface,
785 OleObjectRunnable_AddRef,
786 OleObjectRunnable_Release,
787 OleObjectRunnable_GetRunningClass,
788 OleObjectRunnable_Run,
789 OleObjectRunnable_IsRunning,
790 OleObjectRunnable_LockRunning,
791 OleObjectRunnable_SetContainedObject
794 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl };
796 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
798 static HRESULT WINAPI viewobject_QueryInterface(IViewObject *iface, REFIID riid, void **obj)
800 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IViewObject))
802 *obj = iface;
803 return S_OK;
806 *obj = NULL;
807 return E_NOINTERFACE;
810 static ULONG WINAPI viewobject_AddRef(IViewObject *iface)
812 return 2;
815 static ULONG WINAPI viewobject_Release(IViewObject *iface)
817 return 1;
820 static HRESULT WINAPI viewobject_Draw(IViewObject *iface, DWORD aspect, LONG index,
821 void *paspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw,
822 LPCRECTL bounds, LPCRECTL wbounds, BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue),
823 ULONG_PTR dwContinue)
825 ok(index == -1, "index=%d\n", index);
826 return S_OK;
829 static HRESULT WINAPI viewobject_GetColorSet(IViewObject *iface, DWORD draw_aspect, LONG index,
830 void *aspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **colorset)
832 ok(0, "unexpected call GetColorSet\n");
833 return E_NOTIMPL;
836 static HRESULT WINAPI viewobject_Freeze(IViewObject *iface, DWORD draw_aspect, LONG index,
837 void *aspect, DWORD *freeze)
839 ok(0, "unexpected call Freeze\n");
840 return E_NOTIMPL;
843 static HRESULT WINAPI viewobject_Unfreeze(IViewObject *iface, DWORD freeze)
845 ok(0, "unexpected call Unfreeze\n");
846 return E_NOTIMPL;
849 static HRESULT WINAPI viewobject_SetAdvise(IViewObject *iface, DWORD aspects, DWORD advf, IAdviseSink *sink)
851 ok(0, "unexpected call SetAdvise\n");
852 return E_NOTIMPL;
855 static HRESULT WINAPI viewobject_GetAdvise(IViewObject *iface, DWORD *aspects, DWORD *advf,
856 IAdviseSink **sink)
858 ok(0, "unexpected call GetAdvise\n");
859 return E_NOTIMPL;
862 static const struct IViewObjectVtbl viewobjectvtbl = {
863 viewobject_QueryInterface,
864 viewobject_AddRef,
865 viewobject_Release,
866 viewobject_Draw,
867 viewobject_GetColorSet,
868 viewobject_Freeze,
869 viewobject_Unfreeze,
870 viewobject_SetAdvise,
871 viewobject_GetAdvise
874 static IViewObject viewobject = { &viewobjectvtbl };
876 static void test_OleCreate(IStorage *pStorage)
878 HRESULT hr;
879 IOleObject *pObject;
880 FORMATETC formatetc;
881 static const struct expected_method methods_olerender_none[] =
883 { "OleObject_QueryInterface", 0 },
884 { "OleObject_AddRef", 0 },
885 { "OleObject_QueryInterface", 0 },
886 { "OleObject_AddRef", TEST_OPTIONAL },
887 { "OleObject_Release", TEST_OPTIONAL },
888 { "OleObject_QueryInterface", TEST_OPTIONAL },
889 { "OleObjectPersistStg_AddRef", 0 },
890 { "OleObjectPersistStg_InitNew", 0 },
891 { "OleObjectPersistStg_Release", 0 },
892 { "OleObject_Release", 0 },
893 { "OleObject_Release", TEST_OPTIONAL },
894 { NULL, 0 }
896 static const struct expected_method methods_olerender_draw[] =
898 { "OleObject_QueryInterface", 0 },
899 { "OleObject_AddRef", 0 },
900 { "OleObject_QueryInterface", 0 },
901 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
902 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
903 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
904 { "OleObjectPersistStg_AddRef", 0 },
905 { "OleObjectPersistStg_InitNew", 0 },
906 { "OleObjectPersistStg_Release", 0 },
907 { "OleObject_QueryInterface", 0 },
908 { "OleObjectRunnable_AddRef", 0 },
909 { "OleObjectRunnable_Run", 0 },
910 { "OleObjectRunnable_Release", 0 },
911 { "OleObject_QueryInterface", 0 },
912 { "OleObjectCache_AddRef", 0 },
913 { "OleObjectCache_Cache", 0 },
914 { "OleObjectCache_Release", 0 },
915 { "OleObject_Release", 0 },
916 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
917 { NULL, 0 }
919 static const struct expected_method methods_olerender_draw_with_site[] =
921 { "OleObject_QueryInterface", 0 },
922 { "OleObject_AddRef", 0 },
923 { "OleObject_QueryInterface", 0 },
924 { "OleObject_AddRef", 0 },
925 { "OleObject_GetMiscStatus", 0 },
926 { "OleObject_QueryInterface", 0 },
927 { "OleObjectPersistStg_AddRef", 0 },
928 { "OleObjectPersistStg_InitNew", 0 },
929 { "OleObjectPersistStg_Release", 0 },
930 { "OleObject_SetClientSite", 0 },
931 { "OleObject_Release", 0 },
932 { "OleObject_QueryInterface", 0 },
933 { "OleObjectRunnable_AddRef", 0 },
934 { "OleObjectRunnable_Run", 0 },
935 { "OleObjectRunnable_Release", 0 },
936 { "OleObject_QueryInterface", 0 },
937 { "OleObjectCache_AddRef", 0 },
938 { "OleObjectCache_Cache", 0 },
939 { "OleObjectCache_Release", 0 },
940 { "OleObject_Release", 0 },
941 { NULL, 0 }
943 static const struct expected_method methods_olerender_format[] =
945 { "OleObject_QueryInterface", 0 },
946 { "OleObject_AddRef", 0 },
947 { "OleObject_QueryInterface", 0 },
948 { "OleObject_AddRef", 0 },
949 { "OleObject_GetMiscStatus", 0 },
950 { "OleObject_QueryInterface", 0 },
951 { "OleObjectPersistStg_AddRef", 0 },
952 { "OleObjectPersistStg_InitNew", 0 },
953 { "OleObjectPersistStg_Release", 0 },
954 { "OleObject_SetClientSite", 0 },
955 { "OleObject_Release", 0 },
956 { "OleObject_QueryInterface", 0 },
957 { "OleObjectRunnable_AddRef", 0 },
958 { "OleObjectRunnable_Run", 0 },
959 { "OleObjectRunnable_Release", 0 },
960 { "OleObject_QueryInterface", 0 },
961 { "OleObjectCache_AddRef", 0 },
962 { "OleObjectCache_Cache", 0 },
963 { "OleObjectCache_Release", 0 },
964 { "OleObject_Release", 0 },
965 { NULL, 0 }
967 static const struct expected_method methods_olerender_asis[] =
969 { "OleObject_QueryInterface", 0 },
970 { "OleObject_AddRef", 0 },
971 { "OleObject_QueryInterface", 0 },
972 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
973 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
974 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
975 { "OleObjectPersistStg_AddRef", 0 },
976 { "OleObjectPersistStg_InitNew", 0 },
977 { "OleObjectPersistStg_Release", 0 },
978 { "OleObject_Release", 0 },
979 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
980 { NULL, 0 }
982 static const struct expected_method methods_olerender_draw_no_runnable[] =
984 { "OleObject_QueryInterface", 0 },
985 { "OleObject_AddRef", 0 },
986 { "OleObject_QueryInterface", 0 },
987 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
988 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
989 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
990 { "OleObjectPersistStg_AddRef", 0 },
991 { "OleObjectPersistStg_InitNew", 0 },
992 { "OleObjectPersistStg_Release", 0 },
993 { "OleObject_QueryInterface", 0 },
994 { "OleObject_QueryInterface", 0 },
995 { "OleObjectCache_AddRef", 0 },
996 { "OleObjectCache_Cache", 0 },
997 { "OleObjectCache_Release", 0 },
998 { "OleObject_Release", 0 },
999 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1000 { NULL, 0 },
1002 static const struct expected_method methods_olerender_draw_no_cache[] =
1004 { "OleObject_QueryInterface", 0 },
1005 { "OleObject_AddRef", 0 },
1006 { "OleObject_QueryInterface", 0 },
1007 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
1008 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1009 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
1010 { "OleObjectPersistStg_AddRef", 0 },
1011 { "OleObjectPersistStg_InitNew", 0 },
1012 { "OleObjectPersistStg_Release", 0 },
1013 { "OleObject_QueryInterface", 0 },
1014 { "OleObjectRunnable_AddRef", 0 },
1015 { "OleObjectRunnable_Run", 0 },
1016 { "OleObjectRunnable_Release", 0 },
1017 { "OleObject_QueryInterface", 0 },
1018 { "OleObject_Release", 0 },
1019 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
1020 { NULL, 0 }
1023 g_expected_fetc = &formatetc;
1024 formatetc.cfFormat = 0;
1025 formatetc.ptd = NULL;
1026 formatetc.dwAspect = DVASPECT_CONTENT;
1027 formatetc.lindex = -1;
1028 formatetc.tymed = TYMED_NULL;
1029 runnable = &OleObjectRunnable;
1030 cache = &OleObjectCache;
1031 expected_method_list = methods_olerender_none;
1032 trace("OleCreate with OLERENDER_NONE:\n");
1033 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject);
1034 ok_ole_success(hr, "OleCreate");
1035 IOleObject_Release(pObject);
1036 CHECK_NO_EXTRA_METHODS();
1038 expected_method_list = methods_olerender_draw;
1039 trace("OleCreate with OLERENDER_DRAW:\n");
1040 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1041 ok_ole_success(hr, "OleCreate");
1042 IOleObject_Release(pObject);
1043 CHECK_NO_EXTRA_METHODS();
1045 expected_method_list = methods_olerender_draw_with_site;
1046 trace("OleCreate with OLERENDER_DRAW, with site:\n");
1047 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject);
1048 ok_ole_success(hr, "OleCreate");
1049 IOleObject_Release(pObject);
1050 CHECK_NO_EXTRA_METHODS();
1052 /* GetMiscStatus fails */
1053 g_GetMiscStatusFailsWith = 0x8fafefaf;
1054 expected_method_list = methods_olerender_draw_with_site;
1055 trace("OleCreate with OLERENDER_DRAW, with site:\n");
1056 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject);
1057 ok_ole_success(hr, "OleCreate");
1058 IOleObject_Release(pObject);
1059 CHECK_NO_EXTRA_METHODS();
1060 g_GetMiscStatusFailsWith = S_OK;
1062 formatetc.cfFormat = CF_TEXT;
1063 formatetc.ptd = NULL;
1064 formatetc.dwAspect = DVASPECT_CONTENT;
1065 formatetc.lindex = -1;
1066 formatetc.tymed = TYMED_HGLOBAL;
1067 expected_method_list = methods_olerender_format;
1068 trace("OleCreate with OLERENDER_FORMAT:\n");
1069 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject);
1070 ok(hr == S_OK ||
1071 broken(hr == E_INVALIDARG), /* win2k */
1072 "OleCreate failed with error 0x%08x\n", hr);
1073 if (pObject)
1075 IOleObject_Release(pObject);
1076 CHECK_NO_EXTRA_METHODS();
1079 expected_method_list = methods_olerender_asis;
1080 trace("OleCreate with OLERENDER_ASIS:\n");
1081 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject);
1082 ok_ole_success(hr, "OleCreate");
1083 IOleObject_Release(pObject);
1084 CHECK_NO_EXTRA_METHODS();
1086 formatetc.cfFormat = 0;
1087 formatetc.tymed = TYMED_NULL;
1088 runnable = NULL;
1089 expected_method_list = methods_olerender_draw_no_runnable;
1090 trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
1091 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1092 ok_ole_success(hr, "OleCreate");
1093 IOleObject_Release(pObject);
1094 CHECK_NO_EXTRA_METHODS();
1096 runnable = &OleObjectRunnable;
1097 cache = NULL;
1098 expected_method_list = methods_olerender_draw_no_cache;
1099 trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n");
1100 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1101 ok_ole_success(hr, "OleCreate");
1102 IOleObject_Release(pObject);
1103 CHECK_NO_EXTRA_METHODS();
1104 trace("end\n");
1105 g_expected_fetc = NULL;
1108 static void test_OleLoad(IStorage *pStorage)
1110 HRESULT hr;
1111 IOleObject *pObject;
1112 DWORD fmt;
1114 static const struct expected_method methods_oleload[] =
1116 { "OleObject_QueryInterface", 0 },
1117 { "OleObject_AddRef", 0 },
1118 { "OleObject_QueryInterface", 0 },
1119 { "OleObject_AddRef", 0 },
1120 { "OleObject_GetMiscStatus", 0 },
1121 { "OleObject_QueryInterface", 0 },
1122 { "OleObjectPersistStg_AddRef", 0 },
1123 { "OleObjectPersistStg_Load", 0 },
1124 { "OleObjectPersistStg_Release", 0 },
1125 { "OleObject_SetClientSite", 0 },
1126 { "OleObject_Release", 0 },
1127 { "OleObject_QueryInterface", 0 },
1128 { "OleObject_GetMiscStatus", 0 },
1129 { "OleObject_Release", 0 },
1130 { NULL, 0 }
1133 /* Test once with IOleObject_GetMiscStatus failing */
1134 expected_method_list = methods_oleload;
1135 g_GetMiscStatusFailsWith = E_FAIL;
1136 trace("OleLoad:\n");
1137 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1138 ok(hr == S_OK ||
1139 broken(hr == E_INVALIDARG), /* win98 and win2k */
1140 "OleLoad failed with error 0x%08x\n", hr);
1141 if(pObject)
1143 DWORD dwStatus = 0xdeadbeef;
1144 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1145 ok(hr == E_FAIL, "Got 0x%08x\n", hr);
1146 ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus);
1148 IOleObject_Release(pObject);
1149 CHECK_NO_EXTRA_METHODS();
1151 g_GetMiscStatusFailsWith = S_OK;
1153 /* Test again, let IOleObject_GetMiscStatus succeed. */
1154 expected_method_list = methods_oleload;
1155 trace("OleLoad:\n");
1156 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1157 ok(hr == S_OK ||
1158 broken(hr == E_INVALIDARG), /* win98 and win2k */
1159 "OleLoad failed with error 0x%08x\n", hr);
1160 if (pObject)
1162 DWORD dwStatus = 0xdeadbeef;
1163 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1164 ok(hr == S_OK, "Got 0x%08x\n", hr);
1165 ok(dwStatus == 1, "Got 0x%08x\n", dwStatus);
1167 IOleObject_Release(pObject);
1168 CHECK_NO_EXTRA_METHODS();
1171 for (fmt = CF_TEXT; fmt < CF_MAX; fmt++)
1173 static const WCHAR olrepres[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 };
1174 IStorage *stg;
1175 IStream *stream;
1176 IUnknown *obj;
1177 DWORD data, i, data_size;
1178 PresentationDataHeader header;
1179 HDC hdc;
1180 HGDIOBJ hobj;
1181 RECT rc;
1182 char buf[256];
1184 for (i = 0; i < 7; i++)
1186 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &stg);
1187 ok(hr == S_OK, "StgCreateDocfile error %#x\n", hr);
1189 hr = IStorage_SetClass(stg, &CLSID_WineTest);
1190 ok(hr == S_OK, "SetClass error %#x\n", hr);
1192 hr = IStorage_CreateStream(stg, olrepres, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stream);
1193 ok(hr == S_OK, "CreateStream error %#x\n", hr);
1195 data = ~0;
1196 hr = IStream_Write(stream, &data, sizeof(data), NULL);
1197 ok(hr == S_OK, "Write error %#x\n", hr);
1199 data = fmt;
1200 hr = IStream_Write(stream, &data, sizeof(data), NULL);
1201 ok(hr == S_OK, "Write error %#x\n", hr);
1203 switch (fmt)
1205 case CF_BITMAP:
1206 /* FIXME: figure out stream format */
1207 hobj = CreateBitmap(1, 1, 1, 1, NULL);
1208 data_size = GetBitmapBits(hobj, sizeof(buf), buf);
1209 DeleteObject(hobj);
1210 break;
1212 case CF_METAFILEPICT:
1213 case CF_ENHMETAFILE:
1214 hdc = CreateMetaFileA(NULL);
1215 hobj = CloseMetaFile(hdc);
1216 data_size = GetMetaFileBitsEx(hobj, sizeof(buf), buf);
1217 DeleteMetaFile(hobj);
1218 break;
1220 default:
1221 data_size = sizeof(buf);
1222 memset(buf, 'A', sizeof(buf));
1223 break;
1226 header.unknown3 = 4;
1227 header.dvAspect = DVASPECT_CONTENT;
1228 header.lindex = -1;
1229 header.advf = 1 << i;
1230 header.unknown7 = 0;
1231 header.dwObjectExtentX = 1;
1232 header.dwObjectExtentY = 1;
1233 header.dwSize = data_size;
1234 hr = IStream_Write(stream, &header, sizeof(header), NULL);
1235 ok(hr == S_OK, "Write error %#x\n", hr);
1237 hr = IStream_Write(stream, buf, data_size, NULL);
1238 ok(hr == S_OK, "Write error %#x\n", hr);
1240 IStream_Release(stream);
1242 hr = OleLoad(stg, &IID_IUnknown, NULL, (void **)&obj);
1243 /* FIXME: figure out stream format */
1244 if (fmt == CF_BITMAP && hr != S_OK)
1246 IStorage_Release(stg);
1247 continue;
1249 ok(hr == S_OK, "OleLoad error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1251 hdc = CreateCompatibleDC(0);
1252 SetRect(&rc, 0, 0, 100, 100);
1253 hr = OleDraw(obj, DVASPECT_CONTENT, hdc, &rc);
1254 DeleteDC(hdc);
1255 if (fmt == CF_METAFILEPICT)
1256 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1257 else if (fmt == CF_ENHMETAFILE)
1258 todo_wine
1259 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1260 else
1261 ok(hr == OLE_E_BLANK || hr == OLE_E_NOTRUNNING || hr == E_FAIL, "OleDraw should fail: %#x, cfFormat = %u, advf = %#x\n", hr, fmt, header.advf);
1263 IUnknown_Release(obj);
1264 IStorage_Release(stg);
1269 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param)
1271 CHECK_EXPECTED_METHOD("draw_continue");
1272 return TRUE;
1275 static BOOL STDMETHODCALLTYPE draw_continue_false(ULONG_PTR param)
1277 CHECK_EXPECTED_METHOD("draw_continue_false");
1278 return FALSE;
1281 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv)
1283 if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown))
1285 *ppv = iface;
1286 IAdviseSink_AddRef(iface);
1287 return S_OK;
1289 *ppv = NULL;
1290 return E_NOINTERFACE;
1293 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface)
1295 return 2;
1298 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface)
1300 return 1;
1304 static void WINAPI AdviseSink_OnDataChange(
1305 IAdviseSink *iface,
1306 FORMATETC *pFormatetc,
1307 STGMEDIUM *pStgmed)
1309 CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
1312 static void WINAPI AdviseSink_OnViewChange(
1313 IAdviseSink *iface,
1314 DWORD dwAspect,
1315 LONG lindex)
1317 CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
1320 static void WINAPI AdviseSink_OnRename(
1321 IAdviseSink *iface,
1322 IMoniker *pmk)
1324 CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
1327 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface)
1329 CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
1332 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface)
1334 CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
1337 static const IAdviseSinkVtbl AdviseSinkVtbl =
1339 AdviseSink_QueryInterface,
1340 AdviseSink_AddRef,
1341 AdviseSink_Release,
1342 AdviseSink_OnDataChange,
1343 AdviseSink_OnViewChange,
1344 AdviseSink_OnRename,
1345 AdviseSink_OnSave,
1346 AdviseSink_OnClose
1349 static IAdviseSink AdviseSink = { &AdviseSinkVtbl };
1351 static HRESULT WINAPI DataObject_QueryInterface(
1352 IDataObject* iface,
1353 REFIID riid,
1354 void** ppvObject)
1356 CHECK_EXPECTED_METHOD("DataObject_QueryInterface");
1358 if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
1360 *ppvObject = iface;
1361 return S_OK;
1363 *ppvObject = NULL;
1364 return S_OK;
1367 static ULONG WINAPI DataObject_AddRef(
1368 IDataObject* iface)
1370 CHECK_EXPECTED_METHOD("DataObject_AddRef");
1371 return 2;
1374 static ULONG WINAPI DataObject_Release(
1375 IDataObject* iface)
1377 CHECK_EXPECTED_METHOD("DataObject_Release");
1378 return 1;
1381 static HRESULT WINAPI DataObject_GetData(
1382 IDataObject* iface,
1383 LPFORMATETC pformatetcIn,
1384 STGMEDIUM* pmedium)
1386 CHECK_EXPECTED_METHOD("DataObject_GetData");
1387 return E_NOTIMPL;
1390 static HRESULT WINAPI DataObject_GetDataHere(
1391 IDataObject* iface,
1392 LPFORMATETC pformatetc,
1393 STGMEDIUM* pmedium)
1395 CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1396 return E_NOTIMPL;
1399 static HRESULT WINAPI DataObject_QueryGetData(
1400 IDataObject* iface,
1401 LPFORMATETC pformatetc)
1403 CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
1404 return S_OK;
1407 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
1408 IDataObject* iface,
1409 LPFORMATETC pformatectIn,
1410 LPFORMATETC pformatetcOut)
1412 CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1413 return E_NOTIMPL;
1416 static HRESULT WINAPI DataObject_SetData(
1417 IDataObject* iface,
1418 LPFORMATETC pformatetc,
1419 STGMEDIUM* pmedium,
1420 BOOL fRelease)
1422 CHECK_EXPECTED_METHOD("DataObject_SetData");
1423 return E_NOTIMPL;
1426 static HRESULT WINAPI DataObject_EnumFormatEtc(
1427 IDataObject* iface,
1428 DWORD dwDirection,
1429 IEnumFORMATETC** ppenumFormatEtc)
1431 CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1432 return E_NOTIMPL;
1435 static HRESULT WINAPI DataObject_DAdvise(
1436 IDataObject* iface,
1437 FORMATETC* pformatetc,
1438 DWORD advf,
1439 IAdviseSink* pAdvSink,
1440 DWORD* pdwConnection)
1442 STGMEDIUM stgmedium;
1444 CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1445 *pdwConnection = 1;
1447 if(advf & ADVF_PRIMEFIRST)
1449 ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat);
1450 stgmedium.tymed = TYMED_HGLOBAL;
1451 U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4);
1452 stgmedium.pUnkForRelease = NULL;
1453 IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium);
1456 return S_OK;
1459 static HRESULT WINAPI DataObject_DUnadvise(
1460 IDataObject* iface,
1461 DWORD dwConnection)
1463 CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1464 return S_OK;
1467 static HRESULT WINAPI DataObject_EnumDAdvise(
1468 IDataObject* iface,
1469 IEnumSTATDATA** ppenumAdvise)
1471 CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1472 return OLE_E_ADVISENOTSUPPORTED;
1475 static IDataObjectVtbl DataObjectVtbl =
1477 DataObject_QueryInterface,
1478 DataObject_AddRef,
1479 DataObject_Release,
1480 DataObject_GetData,
1481 DataObject_GetDataHere,
1482 DataObject_QueryGetData,
1483 DataObject_GetCanonicalFormatEtc,
1484 DataObject_SetData,
1485 DataObject_EnumFormatEtc,
1486 DataObject_DAdvise,
1487 DataObject_DUnadvise,
1488 DataObject_EnumDAdvise
1491 static IDataObject DataObject = { &DataObjectVtbl };
1493 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
1495 *ppv = NULL;
1496 if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface;
1497 if (*ppv)
1499 IUnknown_AddRef((IUnknown *)*ppv);
1500 return S_OK;
1502 return E_NOINTERFACE;
1505 static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
1507 return 2;
1510 static ULONG WINAPI Unknown_Release(IUnknown *iface)
1512 return 1;
1515 static const IUnknownVtbl UnknownVtbl =
1517 Unknown_QueryInterface,
1518 Unknown_AddRef,
1519 Unknown_Release
1522 static IUnknown unknown = { &UnknownVtbl };
1524 static void check_enum_cache(IOleCache2 *cache, const STATDATA *expect, int num)
1526 IEnumSTATDATA *enum_stat;
1527 STATDATA stat;
1528 HRESULT hr;
1530 hr = IOleCache2_EnumCache( cache, &enum_stat );
1531 ok( hr == S_OK, "got %08x\n", hr );
1533 while (IEnumSTATDATA_Next(enum_stat, 1, &stat, NULL) == S_OK)
1535 ok( stat.formatetc.cfFormat == expect->formatetc.cfFormat, "got %d expect %d\n",
1536 stat.formatetc.cfFormat, expect->formatetc.cfFormat );
1537 ok( !stat.formatetc.ptd == !expect->formatetc.ptd, "got %p expect %p\n",
1538 stat.formatetc.ptd, expect->formatetc.ptd );
1539 ok( stat.formatetc.dwAspect == expect->formatetc.dwAspect, "got %d expect %d\n",
1540 stat.formatetc.dwAspect, expect->formatetc.dwAspect );
1541 ok( stat.formatetc.lindex == expect->formatetc.lindex, "got %d expect %d\n",
1542 stat.formatetc.lindex, expect->formatetc.lindex );
1543 ok( stat.formatetc.tymed == expect->formatetc.tymed, "got %d expect %d\n",
1544 stat.formatetc.tymed, expect->formatetc.tymed );
1545 ok( stat.advf == expect->advf, "got %d expect %d\n", stat.advf, expect->advf );
1546 ok( stat.pAdvSink == 0, "got %p\n", stat.pAdvSink );
1547 ok( stat.dwConnection == expect->dwConnection, "got %d expect %d\n", stat.dwConnection, expect->dwConnection );
1548 num--;
1549 expect++;
1552 ok( num == 0, "incorrect number. num %d\n", num );
1554 IEnumSTATDATA_Release( enum_stat );
1557 static void test_data_cache(void)
1559 HRESULT hr;
1560 IOleCache2 *pOleCache;
1561 IOleCache *olecache;
1562 IStorage *pStorage;
1563 IUnknown *unk, *unk2;
1564 IPersistStorage *pPS;
1565 IViewObject *pViewObject;
1566 IOleCacheControl *pOleCacheControl;
1567 IDataObject *pCacheDataObject;
1568 FORMATETC fmtetc;
1569 STGMEDIUM stgmedium;
1570 DWORD dwConnection;
1571 DWORD dwFreeze;
1572 RECTL rcBounds;
1573 HDC hdcMem;
1574 CLSID clsid;
1575 char szSystemDir[MAX_PATH];
1576 WCHAR wszPath[MAX_PATH];
1577 static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1579 static const struct expected_method methods_cacheinitnew[] =
1581 { "AdviseSink_OnViewChange", 0 },
1582 { "AdviseSink_OnViewChange", 0 },
1583 { "draw_continue", 1 },
1584 { "draw_continue_false", 1 },
1585 { "DataObject_DAdvise", 0 },
1586 { "DataObject_DAdvise", 0 },
1587 { "DataObject_DUnadvise", 0 },
1588 { "DataObject_DUnadvise", 0 },
1589 { NULL, 0 }
1591 static const struct expected_method methods_cacheload[] =
1593 { "AdviseSink_OnViewChange", 0 },
1594 { "draw_continue", 1 },
1595 { "draw_continue", 1 },
1596 { "draw_continue", 1 },
1597 { "DataObject_GetData", 0 },
1598 { "DataObject_GetData", 0 },
1599 { "DataObject_GetData", 0 },
1600 { NULL, 0 }
1602 static const struct expected_method methods_cachethenrun[] =
1604 { "DataObject_DAdvise", 0 },
1605 { "DataObject_DAdvise", 0 },
1606 { "DataObject_DAdvise", 0 },
1607 { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */
1608 { "DataObject_DAdvise", 0 },
1609 { "DataObject_DUnadvise", 0 },
1610 { "DataObject_DUnadvise", 0 },
1611 { "DataObject_DUnadvise", 0 },
1612 { "DataObject_DUnadvise", 0 },
1613 { NULL, 0 }
1616 GetSystemDirectoryA(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
1618 expected_method_list = methods_cacheinitnew;
1620 fmtetc.cfFormat = CF_METAFILEPICT;
1621 fmtetc.dwAspect = DVASPECT_ICON;
1622 fmtetc.lindex = -1;
1623 fmtetc.ptd = NULL;
1624 fmtetc.tymed = TYMED_MFPICT;
1626 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1627 ok_ole_success(hr, "StgCreateDocfile");
1629 /* aggregation */
1631 /* requested is not IUnknown */
1632 hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IOleCache2, (void**)&pOleCache);
1633 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1635 hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IUnknown, (void**)&unk);
1636 ok(hr == S_OK, "got 0x%08x\n", hr);
1638 hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache);
1639 ok(hr == S_OK, "got 0x%08x\n", hr);
1640 hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache);
1641 ok(hr == S_OK, "got 0x%08x\n", hr);
1642 ok(unk != (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk);
1643 ok(unk != (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk);
1644 IOleCache2_Release(pOleCache);
1645 IOleCache_Release(olecache);
1646 IUnknown_Release(unk);
1648 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void**)&unk);
1649 ok(hr == S_OK, "got 0x%08x\n", hr);
1650 hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache);
1651 ok(hr == S_OK, "got 0x%08x\n", hr);
1652 hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache);
1653 ok(hr == S_OK, "got 0x%08x\n", hr);
1654 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void**)&unk2);
1655 ok(hr == S_OK, "got 0x%08x\n", hr);
1656 ok(unk == (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk);
1657 ok(unk == (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk);
1658 ok(unk == unk2, "got %p, expected %p\n", unk2, unk);
1659 IUnknown_Release(unk2);
1660 IOleCache2_Release(pOleCache);
1661 IOleCache_Release(olecache);
1662 IUnknown_Release(unk);
1664 /* Test with new data */
1666 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1667 ok_ole_success(hr, "CreateDataCache");
1669 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1670 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1671 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1672 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1673 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1674 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1676 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1677 ok_ole_success(hr, "IViewObject_SetAdvise");
1679 hr = IPersistStorage_InitNew(pPS, pStorage);
1680 ok_ole_success(hr, "IPersistStorage_InitNew");
1682 hr = IPersistStorage_IsDirty(pPS);
1683 ok_ole_success(hr, "IPersistStorage_IsDirty");
1685 hr = IPersistStorage_GetClassID(pPS, &clsid);
1686 ok_ole_success(hr, "IPersistStorage_GetClassID");
1687 ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n");
1689 hr = IOleCache2_Uncache(pOleCache, 0xdeadbeef);
1690 ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr);
1692 /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1693 if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
1695 hr = IOleCache2_Cache(pOleCache, NULL, 0, &dwConnection);
1696 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1698 hr = IOleCache2_Cache(pOleCache, NULL, 0, NULL);
1699 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1701 else
1703 skip("tests with NULL parameters will crash on NT4 and below\n");
1706 for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++)
1708 int i;
1709 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1710 for (i = 0; i < 7; i++)
1712 fmtetc.tymed = 1 << i;
1713 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1714 if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) ||
1715 (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) ||
1716 (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) ||
1717 (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF))
1718 ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1719 fmtetc.cfFormat, fmtetc.tymed, hr);
1720 else if (fmtetc.tymed == TYMED_HGLOBAL)
1721 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED ||
1722 broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */,
1723 "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1724 fmtetc.cfFormat, fmtetc.tymed, hr);
1725 else
1726 ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1727 fmtetc.cfFormat, fmtetc.tymed, hr);
1728 if (SUCCEEDED(hr))
1730 hr = IOleCache2_Uncache(pOleCache, dwConnection);
1731 ok_ole_success(hr, "IOleCache_Uncache");
1736 fmtetc.cfFormat = CF_BITMAP;
1737 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1738 fmtetc.tymed = TYMED_GDI;
1739 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1740 ok_ole_success(hr, "IOleCache_Cache");
1742 fmtetc.cfFormat = 0;
1743 fmtetc.dwAspect = DVASPECT_ICON;
1744 fmtetc.tymed = TYMED_MFPICT;
1745 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1746 ok_ole_success(hr, "IOleCache_Cache");
1748 MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
1749 memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
1751 fmtetc.cfFormat = CF_METAFILEPICT;
1752 stgmedium.tymed = TYMED_MFPICT;
1753 U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel(
1754 LoadIconA(NULL, (LPSTR)IDI_APPLICATION), wszPath, wszPath, 0);
1755 stgmedium.pUnkForRelease = NULL;
1757 fmtetc.dwAspect = DVASPECT_CONTENT;
1758 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1759 ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr);
1761 fmtetc.dwAspect = DVASPECT_ICON;
1762 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1763 ok_ole_success(hr, "IOleCache_SetData");
1764 ReleaseStgMedium(&stgmedium);
1766 hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze);
1767 todo_wine {
1768 ok_ole_success(hr, "IViewObject_Freeze");
1769 hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze);
1770 ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1773 rcBounds.left = 0;
1774 rcBounds.top = 0;
1775 rcBounds.right = 100;
1776 rcBounds.bottom = 100;
1777 hdcMem = CreateCompatibleDC(NULL);
1779 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1780 ok_ole_success(hr, "IViewObject_Draw");
1782 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1783 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1785 /* a NULL draw_continue fn ptr */
1786 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef);
1787 ok_ole_success(hr, "IViewObject_Draw");
1789 /* draw_continue that returns FALSE to abort drawing */
1790 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef);
1791 ok(hr == E_ABORT ||
1792 broken(hr == S_OK), /* win9x may skip the callbacks */
1793 "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr);
1795 DeleteDC(hdcMem);
1797 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1798 ok_ole_success(hr, "IOleCacheControl_OnRun");
1800 hr = IPersistStorage_Save(pPS, pStorage, TRUE);
1801 ok_ole_success(hr, "IPersistStorage_Save");
1803 hr = IPersistStorage_SaveCompleted(pPS, NULL);
1804 ok_ole_success(hr, "IPersistStorage_SaveCompleted");
1806 hr = IPersistStorage_IsDirty(pPS);
1807 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1809 IPersistStorage_Release(pPS);
1810 IViewObject_Release(pViewObject);
1811 IOleCache2_Release(pOleCache);
1812 IOleCacheControl_Release(pOleCacheControl);
1814 CHECK_NO_EXTRA_METHODS();
1816 /* Test with loaded data */
1817 trace("Testing loaded data with CreateDataCache:\n");
1818 expected_method_list = methods_cacheload;
1820 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1821 ok_ole_success(hr, "CreateDataCache");
1823 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1824 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1825 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1826 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1828 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1829 ok_ole_success(hr, "IViewObject_SetAdvise");
1831 hr = IPersistStorage_Load(pPS, pStorage);
1832 ok_ole_success(hr, "IPersistStorage_Load");
1834 hr = IPersistStorage_IsDirty(pPS);
1835 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1837 fmtetc.cfFormat = 0;
1838 fmtetc.dwAspect = DVASPECT_ICON;
1839 fmtetc.lindex = -1;
1840 fmtetc.ptd = NULL;
1841 fmtetc.tymed = TYMED_MFPICT;
1842 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1843 ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr);
1845 rcBounds.left = 0;
1846 rcBounds.top = 0;
1847 rcBounds.right = 100;
1848 rcBounds.bottom = 100;
1849 hdcMem = CreateCompatibleDC(NULL);
1851 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1852 ok_ole_success(hr, "IViewObject_Draw");
1854 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1855 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1857 /* unload the cached storage object, causing it to be reloaded */
1858 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1859 ok_ole_success(hr, "IOleCache2_DiscardCache");
1860 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1861 ok_ole_success(hr, "IViewObject_Draw");
1863 /* unload the cached storage object, but don't allow it to be reloaded */
1864 hr = IPersistStorage_HandsOffStorage(pPS);
1865 ok_ole_success(hr, "IPersistStorage_HandsOffStorage");
1866 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1867 ok_ole_success(hr, "IViewObject_Draw");
1868 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1869 ok_ole_success(hr, "IOleCache2_DiscardCache");
1870 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1871 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1873 DeleteDC(hdcMem);
1875 todo_wine {
1876 hr = IOleCache2_InitCache(pOleCache, &DataObject);
1877 ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr);
1880 IPersistStorage_Release(pPS);
1881 IViewObject_Release(pViewObject);
1882 IOleCache2_Release(pOleCache);
1884 todo_wine {
1885 CHECK_NO_EXTRA_METHODS();
1888 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1889 ok_ole_success(hr, "CreateDataCache");
1891 expected_method_list = methods_cachethenrun;
1893 hr = IOleCache2_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject);
1894 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)");
1895 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1896 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1898 fmtetc.cfFormat = CF_METAFILEPICT;
1899 fmtetc.dwAspect = DVASPECT_CONTENT;
1900 fmtetc.tymed = TYMED_MFPICT;
1902 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1903 ok_ole_success(hr, "IOleCache_Cache");
1905 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1906 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1908 fmtetc.cfFormat = cf_test_1;
1909 fmtetc.dwAspect = DVASPECT_CONTENT;
1910 fmtetc.tymed = TYMED_HGLOBAL;
1912 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1913 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1915 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1916 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1918 fmtetc.cfFormat = cf_test_2;
1919 hr = IOleCache2_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection);
1920 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1922 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1923 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1925 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1926 ok_ole_success(hr, "IOleCacheControl_OnRun");
1928 fmtetc.cfFormat = cf_test_3;
1929 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1930 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1932 fmtetc.cfFormat = cf_test_1;
1933 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1934 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1936 fmtetc.cfFormat = cf_test_2;
1937 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1938 ok(hr == S_OK, "got %08x\n", hr);
1939 ReleaseStgMedium(&stgmedium);
1941 fmtetc.cfFormat = cf_test_3;
1942 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1943 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1945 IOleCacheControl_Release(pOleCacheControl);
1946 IDataObject_Release(pCacheDataObject);
1947 IOleCache2_Release(pOleCache);
1949 CHECK_NO_EXTRA_METHODS();
1951 IStorage_Release(pStorage);
1955 static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
1957 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
1958 static BYTE dib[] =
1960 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
1961 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
1963 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
1964 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
1966 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
1967 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
1969 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1970 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1973 static IStorage *create_storage( int num )
1975 IStorage *stg;
1976 IStream *stm;
1977 HRESULT hr;
1978 ULONG written;
1980 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg );
1981 ok( hr == S_OK, "got %08x\n", hr);
1982 hr = IStorage_SetClass( stg, &CLSID_Picture_Dib );
1983 ok( hr == S_OK, "got %08x\n", hr);
1984 hr = IStorage_CreateStream( stg, CONTENTS, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stm );
1985 ok( hr == S_OK, "got %08x\n", hr);
1986 if (num == 1) /* Set biXPelsPerMeter = 0 */
1988 dib[0x26] = 0;
1989 dib[0x27] = 0;
1991 hr = IStream_Write( stm, dib, sizeof(dib), &written );
1992 ok( hr == S_OK, "got %08x\n", hr);
1993 IStream_Release( stm );
1994 return stg;
1997 static HGLOBAL create_dib( void )
1999 HGLOBAL h;
2000 void *ptr;
2002 h = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) - sizeof(BITMAPFILEHEADER) );
2003 ptr = GlobalLock( h );
2004 memcpy( ptr, dib + sizeof(BITMAPFILEHEADER), sizeof(dib) - sizeof(BITMAPFILEHEADER) );
2005 GlobalUnlock( h );
2006 return h;
2009 static void test_data_cache_dib_contents_stream(int num)
2011 HRESULT hr;
2012 IUnknown *unk;
2013 IPersistStorage *persist;
2014 IDataObject *data;
2015 IViewObject2 *view;
2016 IStorage *stg;
2017 IOleCache2 *cache;
2018 FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
2019 STGMEDIUM med;
2020 CLSID cls;
2021 SIZEL sz;
2022 BYTE *ptr;
2023 BITMAPINFOHEADER expect_info;
2024 STATDATA enum_expect[] =
2026 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2027 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 },
2030 hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk );
2031 ok( SUCCEEDED(hr), "got %08x\n", hr );
2032 hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void **)&persist );
2033 ok( SUCCEEDED(hr), "got %08x\n", hr );
2034 hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void **)&data );
2035 ok( SUCCEEDED(hr), "got %08x\n", hr );
2036 hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view );
2037 ok( SUCCEEDED(hr), "got %08x\n", hr );
2038 hr = IUnknown_QueryInterface( unk, &IID_IOleCache2, (void **)&cache );
2039 ok( SUCCEEDED(hr), "got %08x\n", hr );
2041 stg = create_storage( num );
2043 hr = IPersistStorage_Load( persist, stg );
2044 ok( SUCCEEDED(hr), "got %08x\n", hr );
2045 IStorage_Release( stg );
2047 hr = IPersistStorage_GetClassID( persist, &cls );
2048 ok( SUCCEEDED(hr), "got %08x\n", hr );
2049 ok( IsEqualCLSID( &cls, &CLSID_Picture_Dib ), "class id mismatch\n" );
2051 hr = IDataObject_GetData( data, &fmt, &med );
2052 ok( SUCCEEDED(hr), "got %08x\n", hr );
2053 ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed );
2054 ok( GlobalSize( U(med).hGlobal ) >= sizeof(dib) - sizeof(BITMAPFILEHEADER),
2055 "got %lu\n", GlobalSize( U(med).hGlobal ) );
2056 ptr = GlobalLock( U(med).hGlobal );
2058 expect_info = *(BITMAPINFOHEADER *)(dib + sizeof(BITMAPFILEHEADER));
2059 if (expect_info.biXPelsPerMeter == 0 || expect_info.biYPelsPerMeter == 0)
2061 HDC hdc = GetDC( 0 );
2062 expect_info.biXPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSX ), 10000, 254 );
2063 expect_info.biYPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSY ), 10000, 254 );
2064 ReleaseDC( 0, hdc );
2066 ok( !memcmp( ptr, &expect_info, sizeof(expect_info) ), "mismatch\n" );
2067 ok( !memcmp( ptr + sizeof(expect_info), dib + sizeof(BITMAPFILEHEADER) + sizeof(expect_info),
2068 sizeof(dib) - sizeof(BITMAPFILEHEADER) - sizeof(expect_info) ), "mismatch\n" );
2069 GlobalUnlock( U(med).hGlobal );
2070 ReleaseStgMedium( &med );
2072 check_enum_cache( cache, enum_expect, 2 );
2074 hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz );
2075 ok( SUCCEEDED(hr), "got %08x\n", hr );
2076 if (num == 0)
2078 ok( sz.cx == 1000, "got %d\n", sz.cx );
2079 ok( sz.cy == 250, "got %d\n", sz.cy );
2081 else
2083 HDC hdc = GetDC( 0 );
2084 LONG x = 2 * 2540 / GetDeviceCaps( hdc, LOGPIXELSX );
2085 LONG y = 1 * 2540 / GetDeviceCaps( hdc, LOGPIXELSY );
2086 ok( sz.cx == x, "got %d %d\n", sz.cx, x );
2087 ok( sz.cy == y, "got %d %d\n", sz.cy, y );
2089 ReleaseDC( 0, hdc );
2092 IOleCache2_Release( cache );
2093 IViewObject2_Release( view );
2094 IDataObject_Release( data );
2095 IPersistStorage_Release( persist );
2096 IUnknown_Release( unk );
2099 static void check_bitmap_size( HBITMAP h, int cx, int cy )
2101 BITMAP bm;
2103 GetObjectW( h, sizeof(bm), &bm );
2104 ok( bm.bmWidth == cx, "got %d expect %d\n", bm.bmWidth, cx );
2105 ok( bm.bmHeight == cy, "got %d expect %d\n", bm.bmHeight, cy );
2108 static void check_dib_size( HGLOBAL h, int cx, int cy )
2110 BITMAPINFO *info;
2112 info = GlobalLock( h );
2113 ok( info->bmiHeader.biWidth == cx, "got %d expect %d\n", info->bmiHeader.biWidth, cx );
2114 ok( info->bmiHeader.biHeight == cy, "got %d expect %d\n", info->bmiHeader.biHeight, cy );
2115 GlobalUnlock( h );
2118 static void test_data_cache_bitmap(void)
2120 HRESULT hr;
2121 IOleCache2 *cache;
2122 IDataObject *data;
2123 FORMATETC fmt;
2124 DWORD conn;
2125 STGMEDIUM med;
2126 STATDATA expect[] =
2128 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 },
2129 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 },
2130 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 0 },
2131 {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 }
2134 hr = CreateDataCache( NULL, &CLSID_NULL, &IID_IOleCache2, (void **)&cache );
2135 ok( hr == S_OK, "got %08x\n", hr );
2137 /* create a dib entry which will also create a bitmap entry too */
2138 fmt.cfFormat = CF_DIB;
2139 fmt.ptd = NULL;
2140 fmt.dwAspect = DVASPECT_CONTENT;
2141 fmt.lindex = -1;
2142 fmt.tymed = TYMED_HGLOBAL;
2144 hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2145 ok( hr == S_OK, "got %08x\n", hr );
2146 ok( conn == 2, "got %d\n", conn );
2147 expect[0].dwConnection = conn;
2148 expect[1].dwConnection = conn;
2150 check_enum_cache( cache, expect, 2 );
2152 /* now try to add a bitmap */
2153 fmt.cfFormat = CF_BITMAP;
2154 fmt.tymed = TYMED_GDI;
2156 hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2157 ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr );
2159 /* metafile */
2160 fmt.cfFormat = CF_METAFILEPICT;
2161 fmt.tymed = TYMED_MFPICT;
2163 hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2164 ok( hr == S_OK, "got %08x\n", hr );
2165 ok( conn == 3, "got %d\n", conn );
2166 expect[2].dwConnection = conn;
2168 check_enum_cache( cache, expect, 3);
2170 /* enhmetafile */
2171 fmt.cfFormat = CF_ENHMETAFILE;
2172 fmt.tymed = TYMED_ENHMF;
2174 hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2175 ok( hr == S_OK, "got %08x\n", hr );
2176 ok( conn == 4, "got %d\n", conn );
2177 expect[3].dwConnection = conn;
2179 check_enum_cache( cache, expect, 4 );
2181 /* uncache everything */
2182 hr = IOleCache2_Uncache( cache, expect[3].dwConnection );
2183 ok( hr == S_OK, "got %08x\n", hr );
2184 hr = IOleCache2_Uncache( cache, expect[2].dwConnection );
2185 ok( hr == S_OK, "got %08x\n", hr );
2186 hr = IOleCache2_Uncache( cache, expect[0].dwConnection );
2187 ok( hr == S_OK, "got %08x\n", hr );
2188 hr = IOleCache2_Uncache( cache, expect[0].dwConnection );
2189 ok( hr == OLE_E_NOCONNECTION, "got %08x\n", hr );
2191 check_enum_cache( cache, expect, 0 );
2193 /* just create a bitmap entry which again adds both dib and bitmap */
2194 fmt.cfFormat = CF_BITMAP;
2195 fmt.tymed = TYMED_GDI;
2197 hr = IOleCache2_Cache( cache, &fmt, 0, &conn );
2198 ok( hr == S_OK, "got %08x\n", hr );
2200 expect[0].dwConnection = conn;
2201 expect[1].dwConnection = conn;
2203 check_enum_cache( cache, expect, 2 );
2205 /* Try setting a 1x1 bitmap */
2206 hr = IOleCache2_QueryInterface( cache, &IID_IDataObject, (void **) &data );
2207 ok( hr == S_OK, "got %08x\n", hr );
2209 med.tymed = TYMED_GDI;
2210 U(med).hBitmap = CreateBitmap( 1, 1, 1, 1, NULL );
2211 med.pUnkForRelease = NULL;
2213 hr = IOleCache2_SetData( cache, &fmt, &med, TRUE );
2214 ok( hr == S_OK, "got %08x\n", hr );
2216 hr = IDataObject_GetData( data, &fmt, &med );
2217 ok( hr == S_OK, "got %08x\n", hr );
2218 ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed );
2219 check_bitmap_size( U(med).hBitmap, 1, 1 );
2220 ReleaseStgMedium( &med );
2222 fmt.cfFormat = CF_DIB;
2223 fmt.tymed = TYMED_HGLOBAL;
2224 hr = IDataObject_GetData( data, &fmt, &med );
2225 ok( hr == S_OK, "got %08x\n", hr );
2226 ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed );
2227 check_dib_size( U(med).hGlobal, 1, 1 );
2228 ReleaseStgMedium( &med );
2230 /* Now set a 2x1 dib */
2231 fmt.cfFormat = CF_DIB;
2232 fmt.tymed = TYMED_HGLOBAL;
2233 med.tymed = TYMED_HGLOBAL;
2234 U(med).hGlobal = create_dib();
2236 hr = IOleCache2_SetData( cache, &fmt, &med, TRUE );
2237 ok( hr == S_OK, "got %08x\n", hr );
2239 fmt.cfFormat = CF_BITMAP;
2240 fmt.tymed = TYMED_GDI;
2241 hr = IDataObject_GetData( data, &fmt, &med );
2242 ok( hr == S_OK, "got %08x\n", hr );
2243 ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed );
2244 check_bitmap_size( U(med).hBitmap, 2, 1 );
2245 ReleaseStgMedium( &med );
2247 fmt.cfFormat = CF_DIB;
2248 fmt.tymed = TYMED_HGLOBAL;
2249 hr = IDataObject_GetData( data, &fmt, &med );
2250 ok( hr == S_OK, "got %08x\n", hr );
2251 ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed );
2252 check_dib_size( U(med).hGlobal, 2, 1 );
2253 ReleaseStgMedium( &med );
2255 IDataObject_Release( data );
2256 IOleCache2_Release( cache );
2259 /* The CLSID_Picture_ classes automatically create appropriate cache entries */
2260 static void test_data_cache_init(void)
2262 HRESULT hr;
2263 IOleCache2 *cache;
2264 IPersistStorage *persist;
2265 int i;
2266 CLSID clsid;
2267 static const STATDATA enum_expect[] =
2269 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2270 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 },
2271 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 },
2272 {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 1 }
2274 static const struct
2276 const CLSID *clsid;
2277 int enum_start, enum_num;
2278 } data[] =
2280 { &CLSID_NULL, 0, 0 },
2281 { &CLSID_WineTestOld, 0, 0 },
2282 { &CLSID_Picture_Dib, 0, 2 },
2283 { &CLSID_Picture_Metafile, 2, 1 },
2284 { &CLSID_Picture_EnhMetafile, 3, 1 }
2287 for (i = 0; i < sizeof(data) / sizeof(data[0]); i++)
2289 hr = CreateDataCache( NULL, data[i].clsid, &IID_IOleCache2, (void **)&cache );
2290 ok( hr == S_OK, "got %08x\n", hr );
2292 check_enum_cache( cache, enum_expect + data[i].enum_start , data[i].enum_num );
2294 IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist );
2295 hr = IPersistStorage_GetClassID( persist, &clsid );
2296 ok( hr == S_OK, "got %08x\n", hr );
2297 ok( IsEqualCLSID( &clsid, data[i].clsid ), "class id mismatch %s %s\n", wine_dbgstr_guid( &clsid ),
2298 wine_dbgstr_guid( data[i].clsid ) );
2300 IPersistStorage_Release( persist );
2301 IOleCache2_Release( cache );
2305 static void test_data_cache_initnew(void)
2307 HRESULT hr;
2308 IOleCache2 *cache;
2309 IPersistStorage *persist;
2310 IStorage *stg_dib, *stg_mf, *stg_wine;
2311 CLSID clsid;
2312 static const STATDATA initnew_expect[] =
2314 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2315 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 },
2317 static const STATDATA initnew2_expect[] =
2319 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 },
2320 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 },
2321 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 },
2323 static const STATDATA initnew3_expect[] =
2325 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 },
2326 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 },
2327 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 },
2328 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 },
2329 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 },
2331 static const STATDATA initnew4_expect[] =
2333 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 },
2334 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 },
2335 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 },
2336 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 4 },
2337 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 4 },
2340 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_dib );
2341 ok( hr == S_OK, "got %08x\n", hr);
2342 hr = IStorage_SetClass( stg_dib, &CLSID_Picture_Dib );
2343 ok( hr == S_OK, "got %08x\n", hr);
2345 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_mf );
2346 ok( hr == S_OK, "got %08x\n", hr);
2347 hr = IStorage_SetClass( stg_mf, &CLSID_Picture_Metafile );
2348 ok( hr == S_OK, "got %08x\n", hr);
2350 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_wine );
2351 ok( hr == S_OK, "got %08x\n", hr);
2352 hr = IStorage_SetClass( stg_wine, &CLSID_WineTestOld );
2353 ok( hr == S_OK, "got %08x\n", hr);
2355 hr = CreateDataCache( NULL, &CLSID_WineTestOld, &IID_IOleCache2, (void **)&cache );
2356 ok( hr == S_OK, "got %08x\n", hr );
2357 IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist );
2359 hr = IPersistStorage_InitNew( persist, stg_dib );
2360 ok( hr == S_OK, "got %08x\n", hr);
2362 hr = IPersistStorage_GetClassID( persist, &clsid );
2363 ok( hr == S_OK, "got %08x\n", hr );
2364 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2366 check_enum_cache( cache, initnew_expect, 2 );
2368 hr = IPersistStorage_InitNew( persist, stg_mf );
2369 ok( hr == CO_E_ALREADYINITIALIZED, "got %08x\n", hr);
2371 hr = IPersistStorage_HandsOffStorage( persist );
2372 ok( hr == S_OK, "got %08x\n", hr);
2374 hr = IPersistStorage_GetClassID( persist, &clsid );
2375 ok( hr == S_OK, "got %08x\n", hr );
2376 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2378 hr = IPersistStorage_InitNew( persist, stg_mf );
2379 ok( hr == S_OK, "got %08x\n", hr);
2381 hr = IPersistStorage_GetClassID( persist, &clsid );
2382 ok( hr == S_OK, "got %08x\n", hr );
2383 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Metafile ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2385 check_enum_cache( cache, initnew2_expect, 3 );
2387 hr = IPersistStorage_HandsOffStorage( persist );
2388 ok( hr == S_OK, "got %08x\n", hr);
2390 hr = IPersistStorage_InitNew( persist, stg_dib );
2391 ok( hr == S_OK, "got %08x\n", hr);
2393 hr = IPersistStorage_GetClassID( persist, &clsid );
2394 ok( hr == S_OK, "got %08x\n", hr );
2395 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2397 check_enum_cache( cache, initnew3_expect, 5 );
2399 hr = IPersistStorage_HandsOffStorage( persist );
2400 ok( hr == S_OK, "got %08x\n", hr);
2402 hr = IPersistStorage_InitNew( persist, stg_wine );
2403 ok( hr == S_OK, "got %08x\n", hr);
2405 hr = IPersistStorage_GetClassID( persist, &clsid );
2406 ok( hr == S_OK, "got %08x\n", hr );
2407 ok( IsEqualCLSID( &clsid, &CLSID_WineTestOld ), "got %s\n", wine_dbgstr_guid( &clsid ) );
2409 check_enum_cache( cache, initnew4_expect, 5 );
2411 IStorage_Release( stg_wine );
2412 IStorage_Release( stg_mf );
2413 IStorage_Release( stg_dib );
2415 IPersistStorage_Release( persist );
2416 IOleCache2_Release( cache );
2419 static void test_default_handler(void)
2421 HRESULT hr;
2422 IOleObject *pObject;
2423 IRunnableObject *pRunnableObject;
2424 IOleClientSite *pClientSite;
2425 IDataObject *pDataObject;
2426 SIZEL sizel;
2427 DWORD dwStatus;
2428 CLSID clsid;
2429 LPOLESTR pszUserType;
2430 LOGPALETTE palette;
2431 DWORD dwAdvConn;
2432 IMoniker *pMoniker;
2433 FORMATETC fmtetc;
2434 IOleInPlaceObject *pInPlaceObj;
2435 IEnumOLEVERB *pEnumVerbs;
2436 DWORD dwRegister;
2437 static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0};
2438 static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
2439 static const WCHAR wszDelim[] = {'!',0};
2441 static const struct expected_method methods_embeddinghelper[] =
2443 { "OleObject_QueryInterface", 0 },
2444 { "OleObject_AddRef", 0 },
2445 { "OleObject_QueryInterface", 0 },
2446 { "OleObject_QueryInterface", TEST_TODO },
2447 { "OleObject_QueryInterface", 0 },
2448 { "OleObject_QueryInterface", 0 },
2449 { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */
2450 { "OleObject_Release", TEST_TODO },
2451 { "WINE_EXTRA", TEST_OPTIONAL },
2452 { NULL, 0 }
2455 hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject);
2456 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2458 hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject);
2459 ok_ole_success(hr, "OleCreateDefaultHandler");
2461 hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj);
2462 ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr);
2464 hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn);
2465 ok_ole_success(hr, "IOleObject_Advise");
2467 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
2468 ok_ole_success(hr, "IOleObject_Close");
2470 /* FIXME: test IOleObject_EnumAdvise */
2472 hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs);
2473 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2475 hr = IOleObject_GetClientSite(pObject, &pClientSite);
2476 ok_ole_success(hr, "IOleObject_GetClientSite");
2478 hr = IOleObject_SetClientSite(pObject, pClientSite);
2479 ok_ole_success(hr, "IOleObject_SetClientSite");
2481 hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject);
2482 ok(hr == OLE_E_NOTRUNNING,
2483 "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
2484 hr);
2486 hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel);
2487 ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
2488 hr);
2490 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
2491 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2493 hr = IOleObject_GetUserClassID(pObject, &clsid);
2494 ok_ole_success(hr, "IOleObject_GetUserClassID");
2495 ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n");
2497 hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType);
2498 todo_wine {
2499 ok_ole_success(hr, "IOleObject_GetUserType");
2500 ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n");
2503 hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0);
2504 ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2506 hr = IOleObject_IsUpToDate(pObject);
2507 ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2509 palette.palNumEntries = 1;
2510 palette.palVersion = 2;
2511 memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0]));
2512 hr = IOleObject_SetColorScheme(pObject, &palette);
2513 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2515 sizel.cx = sizel.cy = 0;
2516 hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
2517 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2519 hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
2520 ok_ole_success(hr, "IOleObject_SetHostNames");
2522 hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker);
2523 ok_ole_success(hr, "CreateItemMoniker");
2524 hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker);
2525 ok_ole_success(hr, "IOleObject_SetMoniker");
2526 IMoniker_Release(pMoniker);
2528 hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker);
2529 ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr);
2531 hr = IOleObject_Update(pObject);
2532 todo_wine
2533 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2535 hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject);
2536 ok_ole_success(hr, "IOleObject_QueryInterface");
2538 fmtetc.cfFormat = CF_TEXT;
2539 fmtetc.ptd = NULL;
2540 fmtetc.dwAspect = DVASPECT_CONTENT;
2541 fmtetc.lindex = -1;
2542 fmtetc.tymed = TYMED_NULL;
2543 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
2544 ok_ole_success(hr, "IDataObject_DAdvise");
2546 fmtetc.cfFormat = CF_ENHMETAFILE;
2547 fmtetc.ptd = NULL;
2548 fmtetc.dwAspect = DVASPECT_CONTENT;
2549 fmtetc.lindex = -1;
2550 fmtetc.tymed = TYMED_ENHMF;
2551 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
2552 ok_ole_success(hr, "IDataObject_DAdvise");
2554 fmtetc.cfFormat = CF_ENHMETAFILE;
2555 fmtetc.ptd = NULL;
2556 fmtetc.dwAspect = DVASPECT_CONTENT;
2557 fmtetc.lindex = -1;
2558 fmtetc.tymed = TYMED_ENHMF;
2559 hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
2560 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2562 fmtetc.cfFormat = CF_TEXT;
2563 fmtetc.ptd = NULL;
2564 fmtetc.dwAspect = DVASPECT_CONTENT;
2565 fmtetc.lindex = -1;
2566 fmtetc.tymed = TYMED_NULL;
2567 hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
2568 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2570 hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject);
2571 ok_ole_success(hr, "IOleObject_QueryInterface");
2573 hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE);
2574 ok_ole_success(hr, "IRunnableObject_SetContainedObject");
2576 hr = IRunnableObject_Run(pRunnableObject, NULL);
2577 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2579 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
2580 ok_ole_success(hr, "IOleObject_Close");
2582 IRunnableObject_Release(pRunnableObject);
2583 IOleObject_Release(pObject);
2585 /* Test failure propagation from delegate ::QueryInterface */
2586 hr = CoRegisterClassObject(&CLSID_WineTest, (IUnknown*)&OleObjectCF,
2587 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
2588 ok_ole_success(hr, "CoRegisterClassObject");
2589 if(SUCCEEDED(hr))
2591 expected_method_list = methods_embeddinghelper;
2592 hr = OleCreateEmbeddingHelper(&CLSID_WineTest, NULL, EMBDHLP_INPROC_SERVER,
2593 &OleObjectCF, &IID_IOleObject, (void**)&pObject);
2594 ok_ole_success(hr, "OleCreateEmbeddingHelper");
2595 if(SUCCEEDED(hr))
2597 IUnknown *punk;
2599 g_QIFailsWith = E_FAIL;
2600 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2601 ok(hr == E_FAIL, "Got 0x%08x\n", hr);
2603 g_QIFailsWith = E_NOINTERFACE;
2604 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2605 ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
2607 g_QIFailsWith = CO_E_OBJNOTCONNECTED;
2608 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2609 ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr);
2611 g_QIFailsWith = 0x87654321;
2612 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2613 ok(hr == 0x87654321, "Got 0x%08x\n", hr);
2615 IOleObject_Release(pObject);
2618 CHECK_NO_EXTRA_METHODS();
2620 hr = CoRevokeClassObject(dwRegister);
2621 ok_ole_success(hr, "CoRevokeClassObject");
2625 static void test_runnable(void)
2627 static const struct expected_method methods_query_runnable[] =
2629 { "OleObject_QueryInterface", 0 },
2630 { "OleObjectRunnable_AddRef", 0 },
2631 { "OleObjectRunnable_IsRunning", 0 },
2632 { "OleObjectRunnable_Release", 0 },
2633 { NULL, 0 }
2636 static const struct expected_method methods_no_runnable[] =
2638 { "OleObject_QueryInterface", 0 },
2639 { NULL, 0 }
2642 BOOL ret;
2643 IOleObject *object = &OleObject;
2645 /* null argument */
2646 ret = OleIsRunning(NULL);
2647 ok(ret == FALSE, "got %d\n", ret);
2649 expected_method_list = methods_query_runnable;
2650 ret = OleIsRunning(object);
2651 ok(ret == TRUE, "Object should be running\n");
2652 CHECK_NO_EXTRA_METHODS();
2654 g_isRunning = FALSE;
2655 expected_method_list = methods_query_runnable;
2656 ret = OleIsRunning(object);
2657 ok(ret == FALSE, "Object should not be running\n");
2658 CHECK_NO_EXTRA_METHODS();
2660 g_showRunnable = FALSE; /* QueryInterface(IID_IRunnableObject, ...) will fail */
2661 expected_method_list = methods_no_runnable;
2662 ret = OleIsRunning(object);
2663 ok(ret == TRUE, "Object without IRunnableObject should be running\n");
2664 CHECK_NO_EXTRA_METHODS();
2666 g_isRunning = TRUE;
2667 g_showRunnable = TRUE;
2671 static HRESULT WINAPI OleRun_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
2673 *ppv = NULL;
2675 if (IsEqualIID(riid, &IID_IUnknown) ||
2676 IsEqualIID(riid, &IID_IRunnableObject)) {
2677 *ppv = iface;
2680 if (*ppv)
2682 IUnknown_AddRef((IUnknown *)*ppv);
2683 return S_OK;
2686 return E_NOINTERFACE;
2689 static ULONG WINAPI OleRun_AddRef(IRunnableObject *iface)
2691 return 2;
2694 static ULONG WINAPI OleRun_Release(IRunnableObject *iface)
2696 return 1;
2699 static HRESULT WINAPI OleRun_GetRunningClass(IRunnableObject *iface, CLSID *clsid)
2701 ok(0, "unexpected\n");
2702 return E_NOTIMPL;
2705 static HRESULT WINAPI OleRun_Run(IRunnableObject *iface, LPBINDCTX ctx)
2707 ok(ctx == NULL, "got %p\n", ctx);
2708 return 0xdeadc0de;
2711 static BOOL WINAPI OleRun_IsRunning(IRunnableObject *iface)
2713 ok(0, "unexpected\n");
2714 return FALSE;
2717 static HRESULT WINAPI OleRun_LockRunning(IRunnableObject *iface, BOOL lock,
2718 BOOL last_unlock_closes)
2720 ok(0, "unexpected\n");
2721 return E_NOTIMPL;
2724 static HRESULT WINAPI OleRun_SetContainedObject(IRunnableObject *iface, BOOL contained)
2726 ok(0, "unexpected\n");
2727 return E_NOTIMPL;
2730 static const IRunnableObjectVtbl oleruntestvtbl =
2732 OleRun_QueryInterface,
2733 OleRun_AddRef,
2734 OleRun_Release,
2735 OleRun_GetRunningClass,
2736 OleRun_Run,
2737 OleRun_IsRunning,
2738 OleRun_LockRunning,
2739 OleRun_SetContainedObject
2742 static IRunnableObject testrunnable = { &oleruntestvtbl };
2744 static void test_OleRun(void)
2746 HRESULT hr;
2748 /* doesn't support IRunnableObject */
2749 hr = OleRun(&unknown);
2750 ok(hr == S_OK, "OleRun failed 0x%08x\n", hr);
2752 hr = OleRun((IUnknown*)&testrunnable);
2753 ok(hr == 0xdeadc0de, "got 0x%08x\n", hr);
2756 static void test_OleLockRunning(void)
2758 HRESULT hr;
2760 hr = OleLockRunning(&unknown, TRUE, FALSE);
2761 ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
2764 static void test_OleDraw(void)
2766 HRESULT hr;
2767 RECT rect;
2769 hr = OleDraw((IUnknown*)&viewobject, 0, (HDC)0x1, NULL);
2770 ok(hr == S_OK, "got 0x%08x\n", hr);
2772 hr = OleDraw(NULL, 0, (HDC)0x1, NULL);
2773 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2775 hr = OleDraw(NULL, 0, (HDC)0x1, &rect);
2776 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2779 static const WCHAR comp_objW[] = {1,'C','o','m','p','O','b','j',0};
2780 static IStream *comp_obj_stream;
2781 static IStream *ole_stream;
2783 static HRESULT WINAPI Storage_QueryInterface(IStorage *iface, REFIID riid, void **ppvObject)
2785 ok(0, "unexpected call to QueryInterface\n");
2786 return E_NOTIMPL;
2789 static ULONG WINAPI Storage_AddRef(IStorage *iface)
2791 ok(0, "unexpected call to AddRef\n");
2792 return 2;
2795 static ULONG WINAPI Storage_Release(IStorage *iface)
2797 ok(0, "unexpected call to Release\n");
2798 return 1;
2801 static HRESULT WINAPI Storage_CreateStream(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm)
2803 ULARGE_INTEGER size = {{0}};
2804 LARGE_INTEGER pos = {{0}};
2805 HRESULT hr;
2807 CHECK_EXPECT(Storage_CreateStream_CompObj);
2808 ok(!lstrcmpW(pwcsName, comp_objW), "pwcsName = %s\n", wine_dbgstr_w(pwcsName));
2809 todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
2810 ok(!reserved1, "reserved1 = %x\n", reserved1);
2811 ok(!reserved2, "reserved2 = %x\n", reserved2);
2812 ok(!!ppstm, "ppstm = NULL\n");
2814 *ppstm = comp_obj_stream;
2815 IStream_AddRef(comp_obj_stream);
2816 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2817 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2818 hr = IStream_SetSize(comp_obj_stream, size);
2819 ok(hr == S_OK, "IStream_SetSize returned %x\n", hr);
2820 return S_OK;
2823 static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm)
2825 static const WCHAR ole1W[] = {1,'O','l','e',0};
2827 LARGE_INTEGER pos = {{0}};
2828 HRESULT hr;
2830 ok(!reserved1, "reserved1 = %p\n", reserved1);
2831 ok(!reserved2, "reserved2 = %x\n", reserved2);
2832 ok(!!ppstm, "ppstm = NULL\n");
2834 if(!lstrcmpW(pwcsName, comp_objW)) {
2835 CHECK_EXPECT2(Storage_OpenStream_CompObj);
2836 ok(grfMode == STGM_SHARE_EXCLUSIVE, "grfMode = %x\n", grfMode);
2838 *ppstm = comp_obj_stream;
2839 IStream_AddRef(comp_obj_stream);
2840 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2841 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2842 return S_OK;
2843 }else if(!lstrcmpW(pwcsName, ole1W)) {
2844 CHECK_EXPECT(Storage_OpenStream_Ole);
2845 ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
2847 *ppstm = ole_stream;
2848 IStream_AddRef(ole_stream);
2849 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
2850 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2851 return S_OK;
2854 ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName));
2855 return E_NOTIMPL;
2858 static HRESULT WINAPI Storage_CreateStorage(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD dwStgFmt, DWORD reserved2, IStorage **ppstg)
2860 ok(0, "unexpected call to CreateStorage\n");
2861 return E_NOTIMPL;
2864 static HRESULT WINAPI Storage_OpenStorage(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg)
2866 ok(0, "unexpected call to OpenStorage\n");
2867 return E_NOTIMPL;
2870 static HRESULT WINAPI Storage_CopyTo(IStorage *iface, DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest)
2872 ok(0, "unexpected call to CopyTo\n");
2873 return E_NOTIMPL;
2876 static HRESULT WINAPI Storage_MoveElementTo(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgDest, LPCOLESTR pwcsNewName, DWORD grfFlags)
2878 ok(0, "unexpected call to MoveElementTo\n");
2879 return E_NOTIMPL;
2882 static HRESULT WINAPI Storage_Commit(IStorage *iface, DWORD grfCommitFlags)
2884 ok(0, "unexpected call to Commit\n");
2885 return E_NOTIMPL;
2888 static HRESULT WINAPI Storage_Revert(IStorage *iface)
2890 ok(0, "unexpected call to Revert\n");
2891 return E_NOTIMPL;
2894 static HRESULT WINAPI Storage_EnumElements(IStorage *iface, DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum)
2896 ok(0, "unexpected call to EnumElements\n");
2897 return E_NOTIMPL;
2900 static HRESULT WINAPI Storage_DestroyElement(IStorage *iface, LPCOLESTR pwcsName)
2902 ok(0, "unexpected call to DestroyElement\n");
2903 return E_NOTIMPL;
2906 static HRESULT WINAPI Storage_RenameElement(IStorage *iface, LPCOLESTR pwcsOldName, LPCOLESTR pwcsNewName)
2908 ok(0, "unexpected call to RenameElement\n");
2909 return E_NOTIMPL;
2912 static HRESULT WINAPI Storage_SetElementTimes(IStorage *iface, LPCOLESTR pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime)
2914 ok(0, "unexpected call to SetElementTimes\n");
2915 return E_NOTIMPL;
2918 static HRESULT WINAPI Storage_SetClass(IStorage *iface, REFCLSID clsid)
2920 CHECK_EXPECT(Storage_SetClass);
2921 ok(IsEqualIID(clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(clsid));
2922 return S_OK;
2925 static HRESULT WINAPI Storage_SetStateBits(IStorage *iface, DWORD grfStateBits, DWORD grfMask)
2927 ok(0, "unexpected call to SetStateBits\n");
2928 return E_NOTIMPL;
2931 static HRESULT WINAPI Storage_Stat(IStorage *iface, STATSTG *pstatstg, DWORD grfStatFlag)
2933 CHECK_EXPECT2(Storage_Stat);
2934 ok(pstatstg != NULL, "pstatstg = NULL\n");
2935 ok(grfStatFlag == STATFLAG_NONAME, "grfStatFlag = %x\n", grfStatFlag);
2937 memset(pstatstg, 0, sizeof(STATSTG));
2938 pstatstg->type = STGTY_STORAGE;
2939 pstatstg->clsid = CLSID_WineTestOld;
2940 return S_OK;
2943 static IStorageVtbl StorageVtbl =
2945 Storage_QueryInterface,
2946 Storage_AddRef,
2947 Storage_Release,
2948 Storage_CreateStream,
2949 Storage_OpenStream,
2950 Storage_CreateStorage,
2951 Storage_OpenStorage,
2952 Storage_CopyTo,
2953 Storage_MoveElementTo,
2954 Storage_Commit,
2955 Storage_Revert,
2956 Storage_EnumElements,
2957 Storage_DestroyElement,
2958 Storage_RenameElement,
2959 Storage_SetElementTimes,
2960 Storage_SetClass,
2961 Storage_SetStateBits,
2962 Storage_Stat
2965 static IStorage Storage = { &StorageVtbl };
2967 static void test_OleDoAutoConvert(void)
2969 static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0};
2970 static struct {
2971 DWORD reserved1;
2972 DWORD version;
2973 DWORD reserved2[5];
2974 DWORD ansi_user_type_len;
2975 DWORD ansi_clipboard_format_len;
2976 DWORD reserved3;
2977 DWORD unicode_marker;
2978 DWORD unicode_user_type_len;
2979 DWORD unicode_clipboard_format_len;
2980 DWORD reserved4;
2981 } comp_obj_data;
2982 static struct {
2983 DWORD version;
2984 DWORD flags;
2985 DWORD link_update_option;
2986 DWORD reserved1;
2987 DWORD reserved_moniker_stream_size;
2988 DWORD relative_source_moniker_stream_size;
2989 DWORD absolute_source_moniker_stream_size;
2990 DWORD clsid_indicator;
2991 CLSID clsid;
2992 DWORD reserved_display_name;
2993 DWORD reserved2;
2994 DWORD local_update_time;
2995 DWORD local_check_update_time;
2996 DWORD remote_update_time;
2997 } ole_data;
2999 LARGE_INTEGER pos = {{0}};
3000 WCHAR buf[39+6];
3001 DWORD i, ret;
3002 HKEY root;
3003 CLSID clsid;
3004 HRESULT hr;
3006 hr = CreateStreamOnHGlobal(NULL, TRUE, &comp_obj_stream);
3007 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
3008 hr = IStream_Write(comp_obj_stream, (char*)&comp_obj_data, sizeof(comp_obj_data), NULL);
3009 ok(hr == S_OK, "IStream_Write returned %x\n", hr);
3011 hr = CreateStreamOnHGlobal(NULL, TRUE, &ole_stream);
3012 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
3013 hr = IStream_Write(ole_stream, (char*)&ole_data, sizeof(ole_data), NULL);
3014 ok(hr == S_OK, "IStream_Write returned %x\n", hr);
3016 clsid = IID_WineTest;
3017 hr = OleDoAutoConvert(NULL, &clsid);
3018 ok(hr == E_INVALIDARG, "OleDoAutoConvert returned %x\n", hr);
3019 ok(IsEqualIID(&clsid, &IID_NULL), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3021 if(0) /* crashes on Win7 */
3022 OleDoAutoConvert(&Storage, NULL);
3024 clsid = IID_WineTest;
3025 SET_EXPECT(Storage_Stat);
3026 hr = OleDoAutoConvert(&Storage, &clsid);
3027 ok(hr == REGDB_E_CLASSNOTREG, "OleDoAutoConvert returned %x\n", hr);
3028 CHECK_CALLED(Storage_Stat);
3029 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3031 lstrcpyW(buf, clsidW);
3032 StringFromGUID2(&CLSID_WineTestOld, buf+6, 39);
3034 ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
3035 KEY_READ | KEY_WRITE | KEY_CREATE_SUB_KEY, NULL, &root, NULL);
3036 if(ret != ERROR_SUCCESS) {
3037 win_skip("not enough permissions to create CLSID key (%u)\n", ret);
3038 return;
3041 clsid = IID_WineTest;
3042 SET_EXPECT(Storage_Stat);
3043 hr = OleDoAutoConvert(&Storage, &clsid);
3044 ok(hr == REGDB_E_KEYMISSING, "OleDoAutoConvert returned %x\n", hr);
3045 CHECK_CALLED(Storage_Stat);
3046 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3048 hr = OleSetAutoConvert(&CLSID_WineTestOld, &CLSID_WineTest);
3049 ok_ole_success(hr, "OleSetAutoConvert");
3051 hr = OleGetAutoConvert(&CLSID_WineTestOld, &clsid);
3052 ok_ole_success(hr, "OleGetAutoConvert");
3053 ok(IsEqualIID(&clsid, &CLSID_WineTest), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid));
3055 clsid = IID_WineTest;
3056 SET_EXPECT(Storage_Stat);
3057 SET_EXPECT(Storage_OpenStream_CompObj);
3058 SET_EXPECT(Storage_SetClass);
3059 SET_EXPECT(Storage_CreateStream_CompObj);
3060 SET_EXPECT(Storage_OpenStream_Ole);
3061 hr = OleDoAutoConvert(&Storage, &clsid);
3062 ok(hr == S_OK, "OleDoAutoConvert returned %x\n", hr);
3063 CHECK_CALLED(Storage_Stat);
3064 CHECK_CALLED(Storage_OpenStream_CompObj);
3065 CHECK_CALLED(Storage_SetClass);
3066 CHECK_CALLED(Storage_CreateStream_CompObj);
3067 CHECK_CALLED(Storage_OpenStream_Ole);
3068 ok(IsEqualIID(&clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(&clsid));
3070 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
3071 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3072 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
3073 ok(hr == S_OK, "IStream_Read returned %x\n", hr);
3074 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
3075 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
3076 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
3077 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
3078 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
3079 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
3080 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
3081 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
3082 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
3083 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
3084 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
3086 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
3087 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3088 hr = IStream_Read(ole_stream, &ole_data, sizeof(ole_data), NULL);
3089 ok(hr == S_OK, "IStream_Read returned %x\n", hr);
3090 ok(ole_data.version == 0, "version = %x\n", ole_data.version);
3091 ok(ole_data.flags == 4, "flags = %x\n", ole_data.flags);
3092 for(i=2; i<sizeof(ole_data)/sizeof(DWORD); i++)
3093 ok(((DWORD*)&ole_data)[i] == 0, "ole_data[%d] = %x\n", i, ((DWORD*)&ole_data)[i]);
3095 SET_EXPECT(Storage_OpenStream_Ole);
3096 hr = SetConvertStg(&Storage, TRUE);
3097 ok(hr == S_OK, "SetConvertStg returned %x\n", hr);
3098 CHECK_CALLED(Storage_OpenStream_Ole);
3100 SET_EXPECT(Storage_OpenStream_CompObj);
3101 SET_EXPECT(Storage_Stat);
3102 SET_EXPECT(Storage_CreateStream_CompObj);
3103 hr = WriteFmtUserTypeStg(&Storage, 0, NULL);
3104 ok(hr == S_OK, "WriteFmtUserTypeStg returned %x\n", hr);
3105 todo_wine CHECK_CALLED(Storage_OpenStream_CompObj);
3106 CHECK_CALLED(Storage_Stat);
3107 CHECK_CALLED(Storage_CreateStream_CompObj);
3108 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
3109 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
3110 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
3111 ok(hr == S_OK, "IStream_Read returned %x\n", hr);
3112 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
3113 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
3114 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
3115 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
3116 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
3117 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
3118 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
3119 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
3120 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
3121 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
3122 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
3124 ret = IStream_Release(comp_obj_stream);
3125 ok(!ret, "comp_obj_stream was not freed\n");
3126 ret = IStream_Release(ole_stream);
3127 ok(!ret, "ole_stream was not freed\n");
3129 ret = RegDeleteKeyA(root, "AutoConvertTo");
3130 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
3131 ret = RegDeleteKeyA(root, "");
3132 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
3133 RegCloseKey(root);
3136 START_TEST(ole2)
3138 DWORD dwRegister;
3139 IStorage *pStorage;
3140 STATSTG statstg;
3141 HRESULT hr;
3143 cf_test_1 = RegisterClipboardFormatA("cf_winetest_1");
3144 cf_test_2 = RegisterClipboardFormatA("cf_winetest_2");
3145 cf_test_3 = RegisterClipboardFormatA("cf_winetest_3");
3147 CoInitialize(NULL);
3149 hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
3150 ok_ole_success(hr, "CoRegisterClassObject");
3152 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
3153 ok_ole_success(hr, "StgCreateDocfile");
3155 test_OleCreate(pStorage);
3157 hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME);
3158 ok_ole_success(hr, "IStorage_Stat");
3159 ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n");
3161 test_OleLoad(pStorage);
3163 IStorage_Release(pStorage);
3165 hr = CoRevokeClassObject(dwRegister);
3166 ok_ole_success(hr, "CoRevokeClassObject");
3168 test_data_cache();
3169 test_data_cache_dib_contents_stream( 0 );
3170 test_data_cache_dib_contents_stream( 1 );
3171 test_data_cache_bitmap();
3172 test_data_cache_init();
3173 test_data_cache_initnew();
3174 test_default_handler();
3175 test_runnable();
3176 test_OleRun();
3177 test_OleLockRunning();
3178 test_OleDraw();
3179 test_OleDoAutoConvert();
3181 CoUninitialize();