ole32/tests: Add some tests for loading and drawing various OLE formats.
[wine.git] / dlls / ole32 / tests / ole2.c
blobed6157f7e61e5f91c826678527b550d84bb636d4
1 /*
2 * Object Linking and Embedding Tests
4 * Copyright 2005 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #define CONST_VTABLE
23 #define WIN32_LEAN_AND_MEAN
25 #include <stdarg.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "objbase.h"
31 #include "shlguid.h"
33 #include "wine/test.h"
35 #include "initguid.h"
37 DEFINE_GUID(CLSID_Picture_Metafile,0x315,0,0,0xc0,0,0,0,0,0,0,0x46);
38 DEFINE_GUID(CLSID_Picture_Dib,0x316,0,0,0xc0,0,0,0,0,0,0,0x46);
40 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
42 #define DEFINE_EXPECT(func) \
43 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
45 #define SET_EXPECT(func) \
46 expect_ ## func = TRUE
48 #define CHECK_EXPECT2(func) \
49 do { \
50 ok(expect_ ##func, "unexpected call " #func "\n"); \
51 called_ ## func = TRUE; \
52 }while(0)
54 #define CHECK_EXPECT(func) \
55 do { \
56 CHECK_EXPECT2(func); \
57 expect_ ## func = FALSE; \
58 }while(0)
60 #define CHECK_CALLED(func) \
61 do { \
62 ok(called_ ## func, "expected " #func "\n"); \
63 expect_ ## func = called_ ## func = FALSE; \
64 }while(0)
66 DEFINE_EXPECT(Storage_Stat);
67 DEFINE_EXPECT(Storage_OpenStream_CompObj);
68 DEFINE_EXPECT(Storage_SetClass);
69 DEFINE_EXPECT(Storage_CreateStream_CompObj);
70 DEFINE_EXPECT(Storage_OpenStream_Ole);
72 static IPersistStorage OleObjectPersistStg;
73 static IOleCache *cache;
74 static IRunnableObject *runnable;
76 static const CLSID CLSID_WineTestOld =
77 { /* 9474ba1a-258b-490b-bc13-516e9239acd0 */
78 0x9474ba1a,
79 0x258b,
80 0x490b,
81 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xd0}
84 static const CLSID CLSID_WineTest =
85 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
86 0x9474ba1a,
87 0x258b,
88 0x490b,
89 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
92 static const IID IID_WineTest =
93 { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */
94 0x9474ba1a,
95 0x258b,
96 0x490b,
97 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1}
100 #define TEST_OPTIONAL 0x1
101 #define TEST_TODO 0x2
103 struct expected_method
105 const char *method;
106 unsigned int flags;
109 static const struct expected_method *expected_method_list;
110 static FORMATETC *g_expected_fetc = NULL;
112 static BOOL g_showRunnable = TRUE;
113 static BOOL g_isRunning = TRUE;
114 static BOOL g_failGetMiscStatus;
115 static HRESULT g_QIFailsWith;
117 static UINT cf_test_1, cf_test_2, cf_test_3;
119 /****************************************************************************
120 * PresentationDataHeader
122 * This structure represents the header of the \002OlePresXXX stream in
123 * the OLE object storage.
125 typedef struct PresentationDataHeader
127 /* clipformat:
128 * - standard clipformat:
129 * DWORD length = 0xffffffff;
130 * DWORD cfFormat;
131 * - or custom clipformat:
132 * DWORD length;
133 * CHAR format_name[length]; (null-terminated)
135 DWORD unknown3; /* 4, possibly TYMED_ISTREAM */
136 DVASPECT dvAspect;
137 DWORD lindex;
138 DWORD tymed;
139 DWORD unknown7; /* 0 */
140 DWORD dwObjectExtentX;
141 DWORD dwObjectExtentY;
142 DWORD dwSize;
143 } PresentationDataHeader;
145 #define CHECK_EXPECTED_METHOD(method_name) \
146 do { \
147 trace("%s\n", method_name); \
148 ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \
149 if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \
151 todo_wine ok(0, "Too many method calls.\n"); \
152 break; \
154 if (expected_method_list->method) \
156 while (expected_method_list->flags & TEST_OPTIONAL && \
157 strcmp(expected_method_list->method, method_name) != 0) \
158 expected_method_list++; \
159 if (expected_method_list->flags & TEST_TODO) \
160 todo_wine \
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 else \
165 ok(!strcmp(expected_method_list->method, method_name), \
166 "Expected %s to be called instead of %s\n", \
167 expected_method_list->method, method_name); \
168 expected_method_list++; \
170 } while(0)
172 #define CHECK_NO_EXTRA_METHODS() \
173 do { \
174 while (expected_method_list->flags & TEST_OPTIONAL) \
175 expected_method_list++; \
176 ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
177 } while (0)
179 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
181 CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
183 *ppv = NULL;
185 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject))
186 *ppv = iface;
187 else if (IsEqualIID(riid, &IID_IPersistStorage))
188 *ppv = &OleObjectPersistStg;
189 else if (IsEqualIID(riid, &IID_IOleCache))
190 *ppv = cache;
191 else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable)
192 *ppv = runnable;
193 else if (IsEqualIID(riid, &IID_WineTest))
194 return g_QIFailsWith;
196 if(*ppv) {
197 IUnknown_AddRef((IUnknown*)*ppv);
198 return S_OK;
201 trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
202 return E_NOINTERFACE;
205 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
207 CHECK_EXPECTED_METHOD("OleObject_AddRef");
208 return 2;
211 static ULONG WINAPI OleObject_Release(IOleObject *iface)
213 CHECK_EXPECTED_METHOD("OleObject_Release");
214 return 1;
217 static HRESULT WINAPI OleObject_SetClientSite
219 IOleObject *iface,
220 IOleClientSite *pClientSite
223 CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
224 return S_OK;
227 static HRESULT WINAPI OleObject_GetClientSite
229 IOleObject *iface,
230 IOleClientSite **ppClientSite
233 CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
234 return E_NOTIMPL;
237 static HRESULT WINAPI OleObject_SetHostNames
239 IOleObject *iface,
240 LPCOLESTR szContainerApp,
241 LPCOLESTR szContainerObj
244 CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
245 return S_OK;
248 static HRESULT WINAPI OleObject_Close
250 IOleObject *iface,
251 DWORD dwSaveOption
254 CHECK_EXPECTED_METHOD("OleObject_Close");
255 return S_OK;
258 static HRESULT WINAPI OleObject_SetMoniker
260 IOleObject *iface,
261 DWORD dwWhichMoniker,
262 IMoniker *pmk
265 CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
266 return S_OK;
269 static HRESULT WINAPI OleObject_GetMoniker
271 IOleObject *iface,
272 DWORD dwAssign,
273 DWORD dwWhichMoniker,
274 IMoniker **ppmk
277 CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
278 return S_OK;
281 static HRESULT WINAPI OleObject_InitFromData
283 IOleObject *iface,
284 IDataObject *pDataObject,
285 BOOL fCreation,
286 DWORD dwReserved
289 CHECK_EXPECTED_METHOD("OleObject_InitFromData");
290 return S_OK;
293 static HRESULT WINAPI OleObject_GetClipboardData
295 IOleObject *iface,
296 DWORD dwReserved,
297 IDataObject **ppDataObject
300 CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
301 return E_NOTIMPL;
304 static HRESULT WINAPI OleObject_DoVerb
306 IOleObject *iface,
307 LONG iVerb,
308 LPMSG lpmsg,
309 IOleClientSite *pActiveSite,
310 LONG lindex,
311 HWND hwndParent,
312 LPCRECT lprcPosRect
315 CHECK_EXPECTED_METHOD("OleObject_DoVerb");
316 return S_OK;
319 static HRESULT WINAPI OleObject_EnumVerbs
321 IOleObject *iface,
322 IEnumOLEVERB **ppEnumOleVerb
325 CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
326 return E_NOTIMPL;
329 static HRESULT WINAPI OleObject_Update
331 IOleObject *iface
334 CHECK_EXPECTED_METHOD("OleObject_Update");
335 return S_OK;
338 static HRESULT WINAPI OleObject_IsUpToDate
340 IOleObject *iface
343 CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
344 return S_OK;
347 static HRESULT WINAPI OleObject_GetUserClassID
349 IOleObject *iface,
350 CLSID *pClsid
353 CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
354 return E_NOTIMPL;
357 static HRESULT WINAPI OleObject_GetUserType
359 IOleObject *iface,
360 DWORD dwFormOfType,
361 LPOLESTR *pszUserType
364 CHECK_EXPECTED_METHOD("OleObject_GetUserType");
365 return E_NOTIMPL;
368 static HRESULT WINAPI OleObject_SetExtent
370 IOleObject *iface,
371 DWORD dwDrawAspect,
372 SIZEL *psizel
375 CHECK_EXPECTED_METHOD("OleObject_SetExtent");
376 return S_OK;
379 static HRESULT WINAPI OleObject_GetExtent
381 IOleObject *iface,
382 DWORD dwDrawAspect,
383 SIZEL *psizel
386 CHECK_EXPECTED_METHOD("OleObject_GetExtent");
387 return E_NOTIMPL;
390 static HRESULT WINAPI OleObject_Advise
392 IOleObject *iface,
393 IAdviseSink *pAdvSink,
394 DWORD *pdwConnection
397 CHECK_EXPECTED_METHOD("OleObject_Advise");
398 return S_OK;
401 static HRESULT WINAPI OleObject_Unadvise
403 IOleObject *iface,
404 DWORD dwConnection
407 CHECK_EXPECTED_METHOD("OleObject_Unadvise");
408 return S_OK;
411 static HRESULT WINAPI OleObject_EnumAdvise
413 IOleObject *iface,
414 IEnumSTATDATA **ppenumAdvise
417 CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
418 return E_NOTIMPL;
421 static HRESULT WINAPI OleObject_GetMiscStatus
423 IOleObject *iface,
424 DWORD dwAspect,
425 DWORD *pdwStatus
428 CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
429 if(!g_failGetMiscStatus)
431 *pdwStatus = OLEMISC_RECOMPOSEONRESIZE;
432 return S_OK;
434 else
436 *pdwStatus = 0x1234;
437 return E_FAIL;
441 static HRESULT WINAPI OleObject_SetColorScheme
443 IOleObject *iface,
444 LOGPALETTE *pLogpal
447 CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
448 return E_NOTIMPL;
451 static const IOleObjectVtbl OleObjectVtbl =
453 OleObject_QueryInterface,
454 OleObject_AddRef,
455 OleObject_Release,
456 OleObject_SetClientSite,
457 OleObject_GetClientSite,
458 OleObject_SetHostNames,
459 OleObject_Close,
460 OleObject_SetMoniker,
461 OleObject_GetMoniker,
462 OleObject_InitFromData,
463 OleObject_GetClipboardData,
464 OleObject_DoVerb,
465 OleObject_EnumVerbs,
466 OleObject_Update,
467 OleObject_IsUpToDate,
468 OleObject_GetUserClassID,
469 OleObject_GetUserType,
470 OleObject_SetExtent,
471 OleObject_GetExtent,
472 OleObject_Advise,
473 OleObject_Unadvise,
474 OleObject_EnumAdvise,
475 OleObject_GetMiscStatus,
476 OleObject_SetColorScheme
479 static IOleObject OleObject = { &OleObjectVtbl };
481 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv)
483 trace("OleObjectPersistStg_QueryInterface\n");
484 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
487 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface)
489 CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
490 return 2;
493 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface)
495 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
496 return 1;
499 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid)
501 CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
502 return E_NOTIMPL;
505 static HRESULT WINAPI OleObjectPersistStg_IsDirty
507 IPersistStorage *iface
510 CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
511 return S_OK;
514 static HRESULT WINAPI OleObjectPersistStg_InitNew
516 IPersistStorage *iface,
517 IStorage *pStg
520 CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
521 return S_OK;
524 static HRESULT WINAPI OleObjectPersistStg_Load
526 IPersistStorage *iface,
527 IStorage *pStg
530 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
531 return S_OK;
534 static HRESULT WINAPI OleObjectPersistStg_Save
536 IPersistStorage *iface,
537 IStorage *pStgSave,
538 BOOL fSameAsLoad
541 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
542 return S_OK;
545 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
547 IPersistStorage *iface,
548 IStorage *pStgNew
551 CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
552 return S_OK;
555 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
557 IPersistStorage *iface
560 CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
561 return S_OK;
564 static const IPersistStorageVtbl OleObjectPersistStgVtbl =
566 OleObjectPersistStg_QueryInterface,
567 OleObjectPersistStg_AddRef,
568 OleObjectPersistStg_Release,
569 OleObjectPersistStg_GetClassId,
570 OleObjectPersistStg_IsDirty,
571 OleObjectPersistStg_InitNew,
572 OleObjectPersistStg_Load,
573 OleObjectPersistStg_Save,
574 OleObjectPersistStg_SaveCompleted,
575 OleObjectPersistStg_HandsOffStorage
578 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl };
580 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv)
582 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
585 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface)
587 CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
588 return 2;
591 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface)
593 CHECK_EXPECTED_METHOD("OleObjectCache_Release");
594 return 1;
597 static HRESULT WINAPI OleObjectCache_Cache
599 IOleCache *iface,
600 FORMATETC *pformatetc,
601 DWORD advf,
602 DWORD *pdwConnection
605 CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
606 if (g_expected_fetc) {
607 ok(pformatetc != NULL, "pformatetc should not be NULL\n");
608 if (pformatetc) {
609 ok(pformatetc->cfFormat == g_expected_fetc->cfFormat,
610 "cfFormat: %x\n", pformatetc->cfFormat);
611 ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL),
612 "ptd: %p\n", pformatetc->ptd);
613 ok(pformatetc->dwAspect == g_expected_fetc->dwAspect,
614 "dwAspect: %x\n", pformatetc->dwAspect);
615 ok(pformatetc->lindex == g_expected_fetc->lindex,
616 "lindex: %x\n", pformatetc->lindex);
617 ok(pformatetc->tymed == g_expected_fetc->tymed,
618 "tymed: %x\n", pformatetc->tymed);
620 } else
621 ok(pformatetc == NULL, "pformatetc should be NULL\n");
622 return S_OK;
625 static HRESULT WINAPI OleObjectCache_Uncache
627 IOleCache *iface,
628 DWORD dwConnection
631 CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
632 return S_OK;
635 static HRESULT WINAPI OleObjectCache_EnumCache
637 IOleCache *iface,
638 IEnumSTATDATA **ppenumSTATDATA
641 CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
642 return S_OK;
646 static HRESULT WINAPI OleObjectCache_InitCache
648 IOleCache *iface,
649 IDataObject *pDataObject
652 CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
653 return S_OK;
657 static HRESULT WINAPI OleObjectCache_SetData
659 IOleCache *iface,
660 FORMATETC *pformatetc,
661 STGMEDIUM *pmedium,
662 BOOL fRelease
665 CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
666 return S_OK;
670 static const IOleCacheVtbl OleObjectCacheVtbl =
672 OleObjectCache_QueryInterface,
673 OleObjectCache_AddRef,
674 OleObjectCache_Release,
675 OleObjectCache_Cache,
676 OleObjectCache_Uncache,
677 OleObjectCache_EnumCache,
678 OleObjectCache_InitCache,
679 OleObjectCache_SetData
682 static IOleCache OleObjectCache = { &OleObjectCacheVtbl };
684 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
686 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
688 *ppv = iface;
689 IClassFactory_AddRef(iface);
690 return S_OK;
692 *ppv = NULL;
693 return E_NOINTERFACE;
696 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface)
698 return 2;
701 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface)
703 return 1;
706 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv)
708 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
711 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock)
713 return S_OK;
716 static const IClassFactoryVtbl OleObjectCFVtbl =
718 OleObjectCF_QueryInterface,
719 OleObjectCF_AddRef,
720 OleObjectCF_Release,
721 OleObjectCF_CreateInstance,
722 OleObjectCF_LockServer
725 static IClassFactory OleObjectCF = { &OleObjectCFVtbl };
727 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
729 return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv);
732 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface)
734 CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
735 return 2;
738 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface)
740 CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
741 return 1;
744 static HRESULT WINAPI OleObjectRunnable_GetRunningClass(
745 IRunnableObject *iface,
746 LPCLSID lpClsid)
748 CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
749 return E_NOTIMPL;
752 static HRESULT WINAPI OleObjectRunnable_Run(
753 IRunnableObject *iface,
754 LPBINDCTX pbc)
756 CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
757 return S_OK;
760 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface)
762 CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
763 return g_isRunning;
766 static HRESULT WINAPI OleObjectRunnable_LockRunning(
767 IRunnableObject *iface,
768 BOOL fLock,
769 BOOL fLastUnlockCloses)
771 CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
772 return S_OK;
775 static HRESULT WINAPI OleObjectRunnable_SetContainedObject(
776 IRunnableObject *iface,
777 BOOL fContained)
779 CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
780 return S_OK;
783 static const IRunnableObjectVtbl OleObjectRunnableVtbl =
785 OleObjectRunnable_QueryInterface,
786 OleObjectRunnable_AddRef,
787 OleObjectRunnable_Release,
788 OleObjectRunnable_GetRunningClass,
789 OleObjectRunnable_Run,
790 OleObjectRunnable_IsRunning,
791 OleObjectRunnable_LockRunning,
792 OleObjectRunnable_SetContainedObject
795 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl };
797 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
799 static HRESULT WINAPI viewobject_QueryInterface(IViewObject *iface, REFIID riid, void **obj)
801 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IViewObject))
803 *obj = iface;
804 return S_OK;
807 *obj = NULL;
808 return E_NOINTERFACE;
811 static ULONG WINAPI viewobject_AddRef(IViewObject *iface)
813 return 2;
816 static ULONG WINAPI viewobject_Release(IViewObject *iface)
818 return 1;
821 static HRESULT WINAPI viewobject_Draw(IViewObject *iface, DWORD aspect, LONG index,
822 void *paspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw,
823 LPCRECTL bounds, LPCRECTL wbounds, BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue),
824 ULONG_PTR dwContinue)
826 ok(index == -1, "index=%d\n", index);
827 return S_OK;
830 static HRESULT WINAPI viewobject_GetColorSet(IViewObject *iface, DWORD draw_aspect, LONG index,
831 void *aspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **colorset)
833 ok(0, "unexpected call GetColorSet\n");
834 return E_NOTIMPL;
837 static HRESULT WINAPI viewobject_Freeze(IViewObject *iface, DWORD draw_aspect, LONG index,
838 void *aspect, DWORD *freeze)
840 ok(0, "unexpected call Freeze\n");
841 return E_NOTIMPL;
844 static HRESULT WINAPI viewobject_Unfreeze(IViewObject *iface, DWORD freeze)
846 ok(0, "unexpected call Unfreeze\n");
847 return E_NOTIMPL;
850 static HRESULT WINAPI viewobject_SetAdvise(IViewObject *iface, DWORD aspects, DWORD advf, IAdviseSink *sink)
852 ok(0, "unexpected call SetAdvise\n");
853 return E_NOTIMPL;
856 static HRESULT WINAPI viewobject_GetAdvise(IViewObject *iface, DWORD *aspects, DWORD *advf,
857 IAdviseSink **sink)
859 ok(0, "unexpected call GetAdvise\n");
860 return E_NOTIMPL;
863 static const struct IViewObjectVtbl viewobjectvtbl = {
864 viewobject_QueryInterface,
865 viewobject_AddRef,
866 viewobject_Release,
867 viewobject_Draw,
868 viewobject_GetColorSet,
869 viewobject_Freeze,
870 viewobject_Unfreeze,
871 viewobject_SetAdvise,
872 viewobject_GetAdvise
875 static IViewObject viewobject = { &viewobjectvtbl };
877 static void test_OleCreate(IStorage *pStorage)
879 HRESULT hr;
880 IOleObject *pObject;
881 FORMATETC formatetc;
882 static const struct expected_method methods_olerender_none[] =
884 { "OleObject_QueryInterface", 0 },
885 { "OleObject_AddRef", 0 },
886 { "OleObject_QueryInterface", 0 },
887 { "OleObject_AddRef", TEST_OPTIONAL },
888 { "OleObject_Release", TEST_OPTIONAL },
889 { "OleObject_QueryInterface", TEST_OPTIONAL },
890 { "OleObjectPersistStg_AddRef", 0 },
891 { "OleObjectPersistStg_InitNew", 0 },
892 { "OleObjectPersistStg_Release", 0 },
893 { "OleObject_Release", 0 },
894 { "OleObject_Release", TEST_OPTIONAL },
895 { NULL, 0 }
897 static const struct expected_method methods_olerender_draw[] =
899 { "OleObject_QueryInterface", 0 },
900 { "OleObject_AddRef", 0 },
901 { "OleObject_QueryInterface", 0 },
902 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
903 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
904 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
905 { "OleObjectPersistStg_AddRef", 0 },
906 { "OleObjectPersistStg_InitNew", 0 },
907 { "OleObjectPersistStg_Release", 0 },
908 { "OleObject_QueryInterface", 0 },
909 { "OleObjectRunnable_AddRef", 0 },
910 { "OleObjectRunnable_Run", 0 },
911 { "OleObjectRunnable_Release", 0 },
912 { "OleObject_QueryInterface", 0 },
913 { "OleObjectCache_AddRef", 0 },
914 { "OleObjectCache_Cache", 0 },
915 { "OleObjectCache_Release", 0 },
916 { "OleObject_Release", 0 },
917 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
918 { NULL, 0 }
920 static const struct expected_method methods_olerender_format[] =
922 { "OleObject_QueryInterface", 0 },
923 { "OleObject_AddRef", 0 },
924 { "OleObject_QueryInterface", 0 },
925 { "OleObject_AddRef", 0 },
926 { "OleObject_GetMiscStatus", 0 },
927 { "OleObject_QueryInterface", 0 },
928 { "OleObjectPersistStg_AddRef", 0 },
929 { "OleObjectPersistStg_InitNew", 0 },
930 { "OleObjectPersistStg_Release", 0 },
931 { "OleObject_SetClientSite", 0 },
932 { "OleObject_Release", 0 },
933 { "OleObject_QueryInterface", 0 },
934 { "OleObjectRunnable_AddRef", 0 },
935 { "OleObjectRunnable_Run", 0 },
936 { "OleObjectRunnable_Release", 0 },
937 { "OleObject_QueryInterface", 0 },
938 { "OleObjectCache_AddRef", 0 },
939 { "OleObjectCache_Cache", 0 },
940 { "OleObjectCache_Release", 0 },
941 { "OleObject_Release", 0 },
942 { NULL, 0 }
944 static const struct expected_method methods_olerender_asis[] =
946 { "OleObject_QueryInterface", 0 },
947 { "OleObject_AddRef", 0 },
948 { "OleObject_QueryInterface", 0 },
949 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
950 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
951 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
952 { "OleObjectPersistStg_AddRef", 0 },
953 { "OleObjectPersistStg_InitNew", 0 },
954 { "OleObjectPersistStg_Release", 0 },
955 { "OleObject_Release", 0 },
956 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
957 { NULL, 0 }
959 static const struct expected_method methods_olerender_draw_no_runnable[] =
961 { "OleObject_QueryInterface", 0 },
962 { "OleObject_AddRef", 0 },
963 { "OleObject_QueryInterface", 0 },
964 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
965 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
966 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
967 { "OleObjectPersistStg_AddRef", 0 },
968 { "OleObjectPersistStg_InitNew", 0 },
969 { "OleObjectPersistStg_Release", 0 },
970 { "OleObject_QueryInterface", 0 },
971 { "OleObject_QueryInterface", 0 },
972 { "OleObjectCache_AddRef", 0 },
973 { "OleObjectCache_Cache", 0 },
974 { "OleObjectCache_Release", 0 },
975 { "OleObject_Release", 0 },
976 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
977 { NULL, 0 },
979 static const struct expected_method methods_olerender_draw_no_cache[] =
981 { "OleObject_QueryInterface", 0 },
982 { "OleObject_AddRef", 0 },
983 { "OleObject_QueryInterface", 0 },
984 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ },
985 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
986 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ },
987 { "OleObjectPersistStg_AddRef", 0 },
988 { "OleObjectPersistStg_InitNew", 0 },
989 { "OleObjectPersistStg_Release", 0 },
990 { "OleObject_QueryInterface", 0 },
991 { "OleObjectRunnable_AddRef", 0 },
992 { "OleObjectRunnable_Run", 0 },
993 { "OleObjectRunnable_Release", 0 },
994 { "OleObject_QueryInterface", 0 },
995 { "OleObject_Release", 0 },
996 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ },
997 { NULL, 0 }
1000 g_expected_fetc = &formatetc;
1001 formatetc.cfFormat = 0;
1002 formatetc.ptd = NULL;
1003 formatetc.dwAspect = DVASPECT_CONTENT;
1004 formatetc.lindex = -1;
1005 formatetc.tymed = TYMED_NULL;
1006 runnable = &OleObjectRunnable;
1007 cache = &OleObjectCache;
1008 expected_method_list = methods_olerender_none;
1009 trace("OleCreate with OLERENDER_NONE:\n");
1010 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject);
1011 ok_ole_success(hr, "OleCreate");
1012 IOleObject_Release(pObject);
1013 CHECK_NO_EXTRA_METHODS();
1015 expected_method_list = methods_olerender_draw;
1016 trace("OleCreate with OLERENDER_DRAW:\n");
1017 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1018 ok_ole_success(hr, "OleCreate");
1019 IOleObject_Release(pObject);
1020 CHECK_NO_EXTRA_METHODS();
1022 formatetc.cfFormat = CF_TEXT;
1023 formatetc.ptd = NULL;
1024 formatetc.dwAspect = DVASPECT_CONTENT;
1025 formatetc.lindex = -1;
1026 formatetc.tymed = TYMED_HGLOBAL;
1027 expected_method_list = methods_olerender_format;
1028 trace("OleCreate with OLERENDER_FORMAT:\n");
1029 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject);
1030 ok(hr == S_OK ||
1031 broken(hr == E_INVALIDARG), /* win2k */
1032 "OleCreate failed with error 0x%08x\n", hr);
1033 if (pObject)
1035 IOleObject_Release(pObject);
1036 CHECK_NO_EXTRA_METHODS();
1039 expected_method_list = methods_olerender_asis;
1040 trace("OleCreate with OLERENDER_ASIS:\n");
1041 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject);
1042 ok_ole_success(hr, "OleCreate");
1043 IOleObject_Release(pObject);
1044 CHECK_NO_EXTRA_METHODS();
1046 formatetc.cfFormat = 0;
1047 formatetc.tymed = TYMED_NULL;
1048 runnable = NULL;
1049 expected_method_list = methods_olerender_draw_no_runnable;
1050 trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
1051 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1052 ok_ole_success(hr, "OleCreate");
1053 IOleObject_Release(pObject);
1054 CHECK_NO_EXTRA_METHODS();
1056 runnable = &OleObjectRunnable;
1057 cache = NULL;
1058 expected_method_list = methods_olerender_draw_no_cache;
1059 trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n");
1060 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject);
1061 ok_ole_success(hr, "OleCreate");
1062 IOleObject_Release(pObject);
1063 CHECK_NO_EXTRA_METHODS();
1064 trace("end\n");
1065 g_expected_fetc = NULL;
1068 static void test_OleLoad(IStorage *pStorage)
1070 HRESULT hr;
1071 IOleObject *pObject;
1072 DWORD fmt;
1074 static const struct expected_method methods_oleload[] =
1076 { "OleObject_QueryInterface", 0 },
1077 { "OleObject_AddRef", 0 },
1078 { "OleObject_QueryInterface", 0 },
1079 { "OleObject_AddRef", 0 },
1080 { "OleObject_GetMiscStatus", 0 },
1081 { "OleObject_QueryInterface", 0 },
1082 { "OleObjectPersistStg_AddRef", 0 },
1083 { "OleObjectPersistStg_Load", 0 },
1084 { "OleObjectPersistStg_Release", 0 },
1085 { "OleObject_SetClientSite", 0 },
1086 { "OleObject_Release", 0 },
1087 { "OleObject_QueryInterface", 0 },
1088 { "OleObject_GetMiscStatus", 0 },
1089 { "OleObject_Release", 0 },
1090 { NULL, 0 }
1093 /* Test once with IOleObject_GetMiscStatus failing */
1094 expected_method_list = methods_oleload;
1095 g_failGetMiscStatus = TRUE;
1096 trace("OleLoad:\n");
1097 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1098 ok(hr == S_OK ||
1099 broken(hr == E_INVALIDARG), /* win98 and win2k */
1100 "OleLoad failed with error 0x%08x\n", hr);
1101 if(pObject)
1103 DWORD dwStatus = 0xdeadbeef;
1104 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1105 ok(hr == E_FAIL, "Got 0x%08x\n", hr);
1106 ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus);
1108 IOleObject_Release(pObject);
1109 CHECK_NO_EXTRA_METHODS();
1112 /* Test again, let IOleObject_GetMiscStatus succeed. */
1113 g_failGetMiscStatus = FALSE;
1114 expected_method_list = methods_oleload;
1115 trace("OleLoad:\n");
1116 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject);
1117 ok(hr == S_OK ||
1118 broken(hr == E_INVALIDARG), /* win98 and win2k */
1119 "OleLoad failed with error 0x%08x\n", hr);
1120 if (pObject)
1122 DWORD dwStatus = 0xdeadbeef;
1123 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
1124 ok(hr == S_OK, "Got 0x%08x\n", hr);
1125 ok(dwStatus == 1, "Got 0x%08x\n", dwStatus);
1127 IOleObject_Release(pObject);
1128 CHECK_NO_EXTRA_METHODS();
1131 for (fmt = CF_TEXT; fmt < CF_MAX; fmt++)
1133 static const WCHAR olrepres[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 };
1134 IStorage *stg;
1135 IStream *stream;
1136 IUnknown *obj;
1137 DWORD data, i, tymed, data_size;
1138 PresentationDataHeader header;
1139 HDC hdc;
1140 HGDIOBJ hobj;
1141 RECT rc;
1142 char buf[256];
1144 for (i = 0; i < 7; i++)
1146 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &stg);
1147 ok(hr == S_OK, "StgCreateDocfile error %#x\n", hr);
1149 hr = IStorage_SetClass(stg, &CLSID_WineTest);
1150 ok(hr == S_OK, "SetClass error %#x\n", hr);
1152 hr = IStorage_CreateStream(stg, olrepres, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stream);
1153 ok(hr == S_OK, "CreateStream error %#x\n", hr);
1155 data = ~0;
1156 hr = IStream_Write(stream, &data, sizeof(data), NULL);
1157 ok(hr == S_OK, "Write error %#x\n", hr);
1159 data = fmt;
1160 hr = IStream_Write(stream, &data, sizeof(data), NULL);
1161 ok(hr == S_OK, "Write error %#x\n", hr);
1163 switch (fmt)
1165 case CF_BITMAP:
1166 /* FIXME: figure out stream format */
1167 hobj = CreateBitmap(1, 1, 1, 1, NULL);
1168 data_size = GetBitmapBits(hobj, sizeof(buf), buf);
1169 DeleteObject(hobj);
1170 break;
1172 case CF_METAFILEPICT:
1173 case CF_ENHMETAFILE:
1174 hdc = CreateMetaFileA(NULL);
1175 hobj = CloseMetaFile(hdc);
1176 data_size = GetMetaFileBitsEx(hobj, sizeof(buf), buf);
1177 DeleteMetaFile(hobj);
1178 break;
1180 default:
1181 data_size = sizeof(buf);
1182 memset(buf, 'A', sizeof(buf));
1183 break;
1186 tymed = 1 << i;
1188 header.unknown3 = 4;
1189 header.dvAspect = DVASPECT_CONTENT;
1190 header.lindex = -1;
1191 header.tymed = tymed;
1192 header.unknown7 = 0;
1193 header.dwObjectExtentX = 1;
1194 header.dwObjectExtentY = 1;
1195 header.dwSize = data_size;
1196 hr = IStream_Write(stream, &header, sizeof(header), NULL);
1197 ok(hr == S_OK, "Write error %#x\n", hr);
1199 hr = IStream_Write(stream, buf, data_size, NULL);
1200 ok(hr == S_OK, "Write error %#x\n", hr);
1202 IStream_Release(stream);
1204 hr = OleLoad(stg, &IID_IUnknown, NULL, (void **)&obj);
1205 /* FIXME: figure out stream format */
1206 if (fmt == CF_BITMAP && hr != S_OK)
1208 IStorage_Release(stg);
1209 continue;
1211 ok(hr == S_OK, "OleLoad error %#x: cfFormat = %u, tymed = %u\n", hr, fmt, tymed);
1213 hdc = CreateCompatibleDC(0);
1214 SetRect(&rc, 0, 0, 100, 100);
1215 hr = OleDraw(obj, DVASPECT_CONTENT, hdc, &rc);
1216 DeleteDC(hdc);
1217 if (fmt == CF_METAFILEPICT)
1219 if (tymed == TYMED_HGLOBAL || tymed == TYMED_MFPICT)
1220 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, tymed = %u\n", hr, fmt, tymed);
1221 else
1222 todo_wine
1223 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, tymed = %u\n", hr, fmt, tymed);
1225 else if (fmt == CF_ENHMETAFILE)
1226 todo_wine
1227 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, tymed = %u\n", hr, fmt, tymed);
1228 else
1229 ok(hr == OLE_E_BLANK || hr == OLE_E_NOTRUNNING || hr == E_FAIL, "OleDraw should fail: %#x, cfFormat = %u, tymed = %u\n", hr, fmt, header.tymed);
1231 IUnknown_Release(obj);
1232 IStorage_Release(stg);
1237 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param)
1239 CHECK_EXPECTED_METHOD("draw_continue");
1240 return TRUE;
1243 static BOOL STDMETHODCALLTYPE draw_continue_false(ULONG_PTR param)
1245 CHECK_EXPECTED_METHOD("draw_continue_false");
1246 return FALSE;
1249 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv)
1251 if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown))
1253 *ppv = iface;
1254 IAdviseSink_AddRef(iface);
1255 return S_OK;
1257 *ppv = NULL;
1258 return E_NOINTERFACE;
1261 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface)
1263 return 2;
1266 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface)
1268 return 1;
1272 static void WINAPI AdviseSink_OnDataChange(
1273 IAdviseSink *iface,
1274 FORMATETC *pFormatetc,
1275 STGMEDIUM *pStgmed)
1277 CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
1280 static void WINAPI AdviseSink_OnViewChange(
1281 IAdviseSink *iface,
1282 DWORD dwAspect,
1283 LONG lindex)
1285 CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
1288 static void WINAPI AdviseSink_OnRename(
1289 IAdviseSink *iface,
1290 IMoniker *pmk)
1292 CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
1295 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface)
1297 CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
1300 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface)
1302 CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
1305 static const IAdviseSinkVtbl AdviseSinkVtbl =
1307 AdviseSink_QueryInterface,
1308 AdviseSink_AddRef,
1309 AdviseSink_Release,
1310 AdviseSink_OnDataChange,
1311 AdviseSink_OnViewChange,
1312 AdviseSink_OnRename,
1313 AdviseSink_OnSave,
1314 AdviseSink_OnClose
1317 static IAdviseSink AdviseSink = { &AdviseSinkVtbl };
1319 static HRESULT WINAPI DataObject_QueryInterface(
1320 IDataObject* iface,
1321 REFIID riid,
1322 void** ppvObject)
1324 CHECK_EXPECTED_METHOD("DataObject_QueryInterface");
1326 if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown))
1328 *ppvObject = iface;
1329 return S_OK;
1331 *ppvObject = NULL;
1332 return S_OK;
1335 static ULONG WINAPI DataObject_AddRef(
1336 IDataObject* iface)
1338 CHECK_EXPECTED_METHOD("DataObject_AddRef");
1339 return 2;
1342 static ULONG WINAPI DataObject_Release(
1343 IDataObject* iface)
1345 CHECK_EXPECTED_METHOD("DataObject_Release");
1346 return 1;
1349 static HRESULT WINAPI DataObject_GetData(
1350 IDataObject* iface,
1351 LPFORMATETC pformatetcIn,
1352 STGMEDIUM* pmedium)
1354 CHECK_EXPECTED_METHOD("DataObject_GetData");
1355 return E_NOTIMPL;
1358 static HRESULT WINAPI DataObject_GetDataHere(
1359 IDataObject* iface,
1360 LPFORMATETC pformatetc,
1361 STGMEDIUM* pmedium)
1363 CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1364 return E_NOTIMPL;
1367 static HRESULT WINAPI DataObject_QueryGetData(
1368 IDataObject* iface,
1369 LPFORMATETC pformatetc)
1371 CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
1372 return S_OK;
1375 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc(
1376 IDataObject* iface,
1377 LPFORMATETC pformatectIn,
1378 LPFORMATETC pformatetcOut)
1380 CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1381 return E_NOTIMPL;
1384 static HRESULT WINAPI DataObject_SetData(
1385 IDataObject* iface,
1386 LPFORMATETC pformatetc,
1387 STGMEDIUM* pmedium,
1388 BOOL fRelease)
1390 CHECK_EXPECTED_METHOD("DataObject_SetData");
1391 return E_NOTIMPL;
1394 static HRESULT WINAPI DataObject_EnumFormatEtc(
1395 IDataObject* iface,
1396 DWORD dwDirection,
1397 IEnumFORMATETC** ppenumFormatEtc)
1399 CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1400 return E_NOTIMPL;
1403 static HRESULT WINAPI DataObject_DAdvise(
1404 IDataObject* iface,
1405 FORMATETC* pformatetc,
1406 DWORD advf,
1407 IAdviseSink* pAdvSink,
1408 DWORD* pdwConnection)
1410 STGMEDIUM stgmedium;
1412 CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1413 *pdwConnection = 1;
1415 if(advf & ADVF_PRIMEFIRST)
1417 ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat);
1418 stgmedium.tymed = TYMED_HGLOBAL;
1419 U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4);
1420 stgmedium.pUnkForRelease = NULL;
1421 IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium);
1424 return S_OK;
1427 static HRESULT WINAPI DataObject_DUnadvise(
1428 IDataObject* iface,
1429 DWORD dwConnection)
1431 CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1432 return S_OK;
1435 static HRESULT WINAPI DataObject_EnumDAdvise(
1436 IDataObject* iface,
1437 IEnumSTATDATA** ppenumAdvise)
1439 CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1440 return OLE_E_ADVISENOTSUPPORTED;
1443 static IDataObjectVtbl DataObjectVtbl =
1445 DataObject_QueryInterface,
1446 DataObject_AddRef,
1447 DataObject_Release,
1448 DataObject_GetData,
1449 DataObject_GetDataHere,
1450 DataObject_QueryGetData,
1451 DataObject_GetCanonicalFormatEtc,
1452 DataObject_SetData,
1453 DataObject_EnumFormatEtc,
1454 DataObject_DAdvise,
1455 DataObject_DUnadvise,
1456 DataObject_EnumDAdvise
1459 static IDataObject DataObject = { &DataObjectVtbl };
1461 static void test_data_cache(void)
1463 HRESULT hr;
1464 IOleCache2 *pOleCache;
1465 IStorage *pStorage;
1466 IPersistStorage *pPS;
1467 IViewObject *pViewObject;
1468 IOleCacheControl *pOleCacheControl;
1469 IDataObject *pCacheDataObject;
1470 FORMATETC fmtetc;
1471 STGMEDIUM stgmedium;
1472 DWORD dwConnection;
1473 DWORD dwFreeze;
1474 RECTL rcBounds;
1475 HDC hdcMem;
1476 CLSID clsid;
1477 char szSystemDir[MAX_PATH];
1478 WCHAR wszPath[MAX_PATH];
1479 static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1481 static const struct expected_method methods_cacheinitnew[] =
1483 { "AdviseSink_OnViewChange", 0 },
1484 { "AdviseSink_OnViewChange", 0 },
1485 { "draw_continue", 1 },
1486 { "draw_continue_false", 1 },
1487 { "DataObject_DAdvise", 0 },
1488 { "DataObject_DAdvise", 0 },
1489 { "DataObject_DUnadvise", 0 },
1490 { "DataObject_DUnadvise", 0 },
1491 { NULL, 0 }
1493 static const struct expected_method methods_cacheload[] =
1495 { "AdviseSink_OnViewChange", 0 },
1496 { "draw_continue", 1 },
1497 { "draw_continue", 1 },
1498 { "draw_continue", 1 },
1499 { "DataObject_GetData", 0 },
1500 { "DataObject_GetData", 0 },
1501 { "DataObject_GetData", 0 },
1502 { NULL, 0 }
1504 static const struct expected_method methods_cachethenrun[] =
1506 { "DataObject_DAdvise", 0 },
1507 { "DataObject_DAdvise", 0 },
1508 { "DataObject_DAdvise", 0 },
1509 { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */
1510 { "DataObject_DAdvise", 0 },
1511 { "DataObject_DUnadvise", 0 },
1512 { "DataObject_DUnadvise", 0 },
1513 { "DataObject_DUnadvise", 0 },
1514 { "DataObject_DUnadvise", 0 },
1515 { NULL, 0 }
1518 GetSystemDirectoryA(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
1520 expected_method_list = methods_cacheinitnew;
1522 fmtetc.cfFormat = CF_METAFILEPICT;
1523 fmtetc.dwAspect = DVASPECT_ICON;
1524 fmtetc.lindex = -1;
1525 fmtetc.ptd = NULL;
1526 fmtetc.tymed = TYMED_MFPICT;
1528 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
1529 ok_ole_success(hr, "StgCreateDocfile");
1531 /* Test with new data */
1533 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1534 ok_ole_success(hr, "CreateDataCache");
1536 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1537 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1538 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1539 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1540 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1541 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1543 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1544 ok_ole_success(hr, "IViewObject_SetAdvise");
1546 hr = IPersistStorage_InitNew(pPS, pStorage);
1547 ok_ole_success(hr, "IPersistStorage_InitNew");
1549 hr = IPersistStorage_IsDirty(pPS);
1550 ok_ole_success(hr, "IPersistStorage_IsDirty");
1552 hr = IPersistStorage_GetClassID(pPS, &clsid);
1553 ok_ole_success(hr, "IPersistStorage_GetClassID");
1554 ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n");
1556 hr = IOleCache2_Uncache(pOleCache, 0xdeadbeef);
1557 ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr);
1559 /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1560 if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
1562 hr = IOleCache2_Cache(pOleCache, NULL, 0, &dwConnection);
1563 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1565 hr = IOleCache2_Cache(pOleCache, NULL, 0, NULL);
1566 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr);
1568 else
1570 skip("tests with NULL parameters will crash on NT4 and below\n");
1573 for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++)
1575 int i;
1576 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1577 for (i = 0; i < 7; i++)
1579 fmtetc.tymed = 1 << i;
1580 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1581 if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) ||
1582 (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) ||
1583 (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) ||
1584 (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF))
1585 ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1586 fmtetc.cfFormat, fmtetc.tymed, hr);
1587 else if (fmtetc.tymed == TYMED_HGLOBAL)
1588 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED ||
1589 broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */,
1590 "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1591 fmtetc.cfFormat, fmtetc.tymed, hr);
1592 else
1593 ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1594 fmtetc.cfFormat, fmtetc.tymed, hr);
1595 if (SUCCEEDED(hr))
1597 hr = IOleCache2_Uncache(pOleCache, dwConnection);
1598 ok_ole_success(hr, "IOleCache_Uncache");
1603 fmtetc.cfFormat = CF_BITMAP;
1604 fmtetc.dwAspect = DVASPECT_THUMBNAIL;
1605 fmtetc.tymed = TYMED_GDI;
1606 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1607 ok_ole_success(hr, "IOleCache_Cache");
1609 fmtetc.cfFormat = 0;
1610 fmtetc.dwAspect = DVASPECT_ICON;
1611 fmtetc.tymed = TYMED_MFPICT;
1612 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1613 ok_ole_success(hr, "IOleCache_Cache");
1615 MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
1616 memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
1618 fmtetc.cfFormat = CF_METAFILEPICT;
1619 stgmedium.tymed = TYMED_MFPICT;
1620 U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel(
1621 LoadIconA(NULL, (LPSTR)IDI_APPLICATION), wszPath, wszPath, 0);
1622 stgmedium.pUnkForRelease = NULL;
1624 fmtetc.dwAspect = DVASPECT_CONTENT;
1625 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1626 ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr);
1628 fmtetc.dwAspect = DVASPECT_ICON;
1629 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE);
1630 ok_ole_success(hr, "IOleCache_SetData");
1631 ReleaseStgMedium(&stgmedium);
1633 hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze);
1634 todo_wine {
1635 ok_ole_success(hr, "IViewObject_Freeze");
1636 hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze);
1637 ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1640 rcBounds.left = 0;
1641 rcBounds.top = 0;
1642 rcBounds.right = 100;
1643 rcBounds.bottom = 100;
1644 hdcMem = CreateCompatibleDC(NULL);
1646 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1647 ok_ole_success(hr, "IViewObject_Draw");
1649 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1650 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1652 /* a NULL draw_continue fn ptr */
1653 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef);
1654 ok_ole_success(hr, "IViewObject_Draw");
1656 /* draw_continue that returns FALSE to abort drawing */
1657 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef);
1658 ok(hr == E_ABORT ||
1659 broken(hr == S_OK), /* win9x may skip the callbacks */
1660 "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr);
1662 DeleteDC(hdcMem);
1664 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1665 ok_ole_success(hr, "IOleCacheControl_OnRun");
1667 hr = IPersistStorage_Save(pPS, pStorage, TRUE);
1668 ok_ole_success(hr, "IPersistStorage_Save");
1670 hr = IPersistStorage_SaveCompleted(pPS, NULL);
1671 ok_ole_success(hr, "IPersistStorage_SaveCompleted");
1673 hr = IPersistStorage_IsDirty(pPS);
1674 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1676 IPersistStorage_Release(pPS);
1677 IViewObject_Release(pViewObject);
1678 IOleCache2_Release(pOleCache);
1679 IOleCacheControl_Release(pOleCacheControl);
1681 CHECK_NO_EXTRA_METHODS();
1683 /* Test with loaded data */
1684 trace("Testing loaded data with CreateDataCache:\n");
1685 expected_method_list = methods_cacheload;
1687 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1688 ok_ole_success(hr, "CreateDataCache");
1690 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS);
1691 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)");
1692 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject);
1693 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)");
1695 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink);
1696 ok_ole_success(hr, "IViewObject_SetAdvise");
1698 hr = IPersistStorage_Load(pPS, pStorage);
1699 ok_ole_success(hr, "IPersistStorage_Load");
1701 hr = IPersistStorage_IsDirty(pPS);
1702 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr);
1704 fmtetc.cfFormat = 0;
1705 fmtetc.dwAspect = DVASPECT_ICON;
1706 fmtetc.lindex = -1;
1707 fmtetc.ptd = NULL;
1708 fmtetc.tymed = TYMED_MFPICT;
1709 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1710 ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr);
1712 rcBounds.left = 0;
1713 rcBounds.top = 0;
1714 rcBounds.right = 100;
1715 rcBounds.bottom = 100;
1716 hdcMem = CreateCompatibleDC(NULL);
1718 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1719 ok_ole_success(hr, "IViewObject_Draw");
1721 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1722 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1724 /* unload the cached storage object, causing it to be reloaded */
1725 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1726 ok_ole_success(hr, "IOleCache2_DiscardCache");
1727 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1728 ok_ole_success(hr, "IViewObject_Draw");
1730 /* unload the cached storage object, but don't allow it to be reloaded */
1731 hr = IPersistStorage_HandsOffStorage(pPS);
1732 ok_ole_success(hr, "IPersistStorage_HandsOffStorage");
1733 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1734 ok_ole_success(hr, "IViewObject_Draw");
1735 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE);
1736 ok_ole_success(hr, "IOleCache2_DiscardCache");
1737 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef);
1738 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr);
1740 DeleteDC(hdcMem);
1742 todo_wine {
1743 hr = IOleCache2_InitCache(pOleCache, &DataObject);
1744 ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr);
1747 IPersistStorage_Release(pPS);
1748 IViewObject_Release(pViewObject);
1749 IOleCache2_Release(pOleCache);
1751 todo_wine {
1752 CHECK_NO_EXTRA_METHODS();
1755 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache);
1756 ok_ole_success(hr, "CreateDataCache");
1758 expected_method_list = methods_cachethenrun;
1760 hr = IOleCache2_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject);
1761 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)");
1762 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl);
1763 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1765 fmtetc.cfFormat = CF_METAFILEPICT;
1766 fmtetc.dwAspect = DVASPECT_CONTENT;
1767 fmtetc.tymed = TYMED_MFPICT;
1769 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1770 ok_ole_success(hr, "IOleCache_Cache");
1772 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1773 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1775 fmtetc.cfFormat = cf_test_1;
1776 fmtetc.dwAspect = DVASPECT_CONTENT;
1777 fmtetc.tymed = TYMED_HGLOBAL;
1779 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1780 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1782 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1783 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1785 fmtetc.cfFormat = cf_test_2;
1786 hr = IOleCache2_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection);
1787 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1789 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1790 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1792 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject);
1793 ok_ole_success(hr, "IOleCacheControl_OnRun");
1795 fmtetc.cfFormat = cf_test_3;
1796 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
1797 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr);
1799 fmtetc.cfFormat = cf_test_1;
1800 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1801 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1803 fmtetc.cfFormat = cf_test_2;
1804 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1805 ok(hr == S_OK, "got %08x\n", hr);
1806 ReleaseStgMedium(&stgmedium);
1808 fmtetc.cfFormat = cf_test_3;
1809 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium);
1810 ok(hr == OLE_E_BLANK, "got %08x\n", hr);
1812 IOleCacheControl_Release(pOleCacheControl);
1813 IDataObject_Release(pCacheDataObject);
1814 IOleCache2_Release(pOleCache);
1816 CHECK_NO_EXTRA_METHODS();
1818 IStorage_Release(pStorage);
1822 static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
1824 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
1825 static BYTE dib[] =
1827 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
1828 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
1830 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
1831 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
1833 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
1834 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1837 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1840 static IStorage *create_storage( int num )
1842 IStorage *stg;
1843 IStream *stm;
1844 HRESULT hr;
1845 ULONG written;
1847 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg );
1848 ok( hr == S_OK, "got %08x\n", hr);
1849 hr = IStorage_SetClass( stg, &CLSID_Picture_Dib );
1850 ok( hr == S_OK, "got %08x\n", hr);
1851 hr = IStorage_CreateStream( stg, CONTENTS, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stm );
1852 ok( hr == S_OK, "got %08x\n", hr);
1853 if (num == 1) /* Set biXPelsPerMeter = 0 */
1855 dib[0x26] = 0;
1856 dib[0x27] = 0;
1858 hr = IStream_Write( stm, dib, sizeof(dib), &written );
1859 ok( hr == S_OK, "got %08x\n", hr);
1860 IStream_Release( stm );
1861 return stg;
1864 static void test_data_cache_dib_contents_stream(int num)
1866 HRESULT hr;
1867 IUnknown *unk;
1868 IPersistStorage *persist;
1869 IDataObject *data;
1870 IViewObject2 *view;
1871 IStorage *stg;
1872 FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
1873 STGMEDIUM med;
1874 CLSID cls;
1875 SIZEL sz;
1877 hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void *)&unk );
1878 ok( SUCCEEDED(hr), "got %08x\n", hr );
1879 hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void *)&persist );
1880 ok( SUCCEEDED(hr), "got %08x\n", hr );
1881 hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void *)&data );
1882 ok( SUCCEEDED(hr), "got %08x\n", hr );
1883 hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void *)&view );
1884 ok( SUCCEEDED(hr), "got %08x\n", hr );
1886 stg = create_storage( num );
1888 hr = IPersistStorage_Load( persist, stg );
1889 ok( SUCCEEDED(hr), "got %08x\n", hr );
1890 IStorage_Release( stg );
1892 hr = IPersistStorage_GetClassID( persist, &cls );
1893 ok( SUCCEEDED(hr), "got %08x\n", hr );
1894 ok( IsEqualCLSID( &cls, &CLSID_Picture_Dib ), "class id mismatch\n" );
1896 hr = IDataObject_GetData( data, &fmt, &med );
1897 ok( SUCCEEDED(hr), "got %08x\n", hr );
1898 if (SUCCEEDED(hr))
1900 ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed );
1901 ReleaseStgMedium( &med );
1904 hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz );
1905 ok( SUCCEEDED(hr), "got %08x\n", hr );
1906 if (num == 0)
1908 ok( sz.cx == 1000, "got %d\n", sz.cx );
1909 ok( sz.cy == 250, "got %d\n", sz.cy );
1911 else
1913 HDC hdc = GetDC( 0 );
1914 LONG x = 2 * 2540 / GetDeviceCaps( hdc, LOGPIXELSX );
1915 LONG y = 1 * 2540 / GetDeviceCaps( hdc, LOGPIXELSY );
1916 ok( sz.cx == x, "got %d %d\n", sz.cx, x );
1917 ok( sz.cy == y, "got %d %d\n", sz.cy, y );
1919 ReleaseDC( 0, hdc );
1922 IViewObject2_Release( view );
1923 IDataObject_Release( data );
1924 IPersistStorage_Release( persist );
1925 IUnknown_Release( unk );
1928 static void test_default_handler(void)
1930 HRESULT hr;
1931 IOleObject *pObject;
1932 IRunnableObject *pRunnableObject;
1933 IOleClientSite *pClientSite;
1934 IDataObject *pDataObject;
1935 SIZEL sizel;
1936 DWORD dwStatus;
1937 CLSID clsid;
1938 LPOLESTR pszUserType;
1939 LOGPALETTE palette;
1940 DWORD dwAdvConn;
1941 IMoniker *pMoniker;
1942 FORMATETC fmtetc;
1943 IOleInPlaceObject *pInPlaceObj;
1944 IEnumOLEVERB *pEnumVerbs;
1945 DWORD dwRegister;
1946 static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0};
1947 static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
1948 static const WCHAR wszDelim[] = {'!',0};
1950 static const struct expected_method methods_embeddinghelper[] =
1952 { "OleObject_QueryInterface", 0 },
1953 { "OleObject_AddRef", 0 },
1954 { "OleObject_QueryInterface", 0 },
1955 { "OleObject_QueryInterface", TEST_TODO },
1956 { "OleObject_QueryInterface", 0 },
1957 { "OleObject_QueryInterface", 0 },
1958 { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */
1959 { "OleObject_Release", TEST_TODO },
1960 { "WINE_EXTRA", TEST_OPTIONAL },
1961 { NULL, 0 }
1964 hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject);
1965 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1967 hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject);
1968 ok_ole_success(hr, "OleCreateDefaultHandler");
1970 hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj);
1971 ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr);
1973 hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn);
1974 ok_ole_success(hr, "IOleObject_Advise");
1976 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
1977 ok_ole_success(hr, "IOleObject_Close");
1979 /* FIXME: test IOleObject_EnumAdvise */
1981 hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs);
1982 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
1984 hr = IOleObject_GetClientSite(pObject, &pClientSite);
1985 ok_ole_success(hr, "IOleObject_GetClientSite");
1987 hr = IOleObject_SetClientSite(pObject, pClientSite);
1988 ok_ole_success(hr, "IOleObject_SetClientSite");
1990 hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject);
1991 ok(hr == OLE_E_NOTRUNNING,
1992 "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
1993 hr);
1995 hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel);
1996 ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
1997 hr);
1999 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus);
2000 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2002 hr = IOleObject_GetUserClassID(pObject, &clsid);
2003 ok_ole_success(hr, "IOleObject_GetUserClassID");
2004 ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n");
2006 hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType);
2007 todo_wine {
2008 ok_ole_success(hr, "IOleObject_GetUserType");
2009 ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n");
2012 hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0);
2013 ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2015 hr = IOleObject_IsUpToDate(pObject);
2016 ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2018 palette.palNumEntries = 1;
2019 palette.palVersion = 2;
2020 memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0]));
2021 hr = IOleObject_SetColorScheme(pObject, &palette);
2022 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2024 sizel.cx = sizel.cy = 0;
2025 hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel);
2026 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2028 hr = IOleObject_SetHostNames(pObject, wszHostName, NULL);
2029 ok_ole_success(hr, "IOleObject_SetHostNames");
2031 hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker);
2032 ok_ole_success(hr, "CreateItemMoniker");
2033 hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker);
2034 ok_ole_success(hr, "IOleObject_SetMoniker");
2035 IMoniker_Release(pMoniker);
2037 hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker);
2038 ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr);
2040 hr = IOleObject_Update(pObject);
2041 todo_wine
2042 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2044 hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject);
2045 ok_ole_success(hr, "IOleObject_QueryInterface");
2047 fmtetc.cfFormat = CF_TEXT;
2048 fmtetc.ptd = NULL;
2049 fmtetc.dwAspect = DVASPECT_CONTENT;
2050 fmtetc.lindex = -1;
2051 fmtetc.tymed = TYMED_NULL;
2052 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
2053 ok_ole_success(hr, "IDataObject_DAdvise");
2055 fmtetc.cfFormat = CF_ENHMETAFILE;
2056 fmtetc.ptd = NULL;
2057 fmtetc.dwAspect = DVASPECT_CONTENT;
2058 fmtetc.lindex = -1;
2059 fmtetc.tymed = TYMED_ENHMF;
2060 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn);
2061 ok_ole_success(hr, "IDataObject_DAdvise");
2063 fmtetc.cfFormat = CF_ENHMETAFILE;
2064 fmtetc.ptd = NULL;
2065 fmtetc.dwAspect = DVASPECT_CONTENT;
2066 fmtetc.lindex = -1;
2067 fmtetc.tymed = TYMED_ENHMF;
2068 hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
2069 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2071 fmtetc.cfFormat = CF_TEXT;
2072 fmtetc.ptd = NULL;
2073 fmtetc.dwAspect = DVASPECT_CONTENT;
2074 fmtetc.lindex = -1;
2075 fmtetc.tymed = TYMED_NULL;
2076 hr = IDataObject_QueryGetData(pDataObject, &fmtetc);
2077 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr);
2079 hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject);
2080 ok_ole_success(hr, "IOleObject_QueryInterface");
2082 hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE);
2083 ok_ole_success(hr, "IRunnableObject_SetContainedObject");
2085 hr = IRunnableObject_Run(pRunnableObject, NULL);
2086 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr);
2088 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE);
2089 ok_ole_success(hr, "IOleObject_Close");
2091 IRunnableObject_Release(pRunnableObject);
2092 IOleObject_Release(pObject);
2094 /* Test failure propagation from delegate ::QueryInterface */
2095 hr = CoRegisterClassObject(&CLSID_WineTest, (IUnknown*)&OleObjectCF,
2096 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
2097 ok_ole_success(hr, "CoRegisterClassObject");
2098 if(SUCCEEDED(hr))
2100 expected_method_list = methods_embeddinghelper;
2101 hr = OleCreateEmbeddingHelper(&CLSID_WineTest, NULL, EMBDHLP_INPROC_SERVER,
2102 &OleObjectCF, &IID_IOleObject, (void**)&pObject);
2103 ok_ole_success(hr, "OleCreateEmbeddingHelper");
2104 if(SUCCEEDED(hr))
2106 IUnknown *punk;
2108 g_QIFailsWith = E_FAIL;
2109 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2110 ok(hr == E_FAIL, "Got 0x%08x\n", hr);
2112 g_QIFailsWith = E_NOINTERFACE;
2113 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2114 ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr);
2116 g_QIFailsWith = CO_E_OBJNOTCONNECTED;
2117 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2118 ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr);
2120 g_QIFailsWith = 0x87654321;
2121 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk);
2122 ok(hr == 0x87654321, "Got 0x%08x\n", hr);
2124 IOleObject_Release(pObject);
2127 CHECK_NO_EXTRA_METHODS();
2129 hr = CoRevokeClassObject(dwRegister);
2130 ok_ole_success(hr, "CoRevokeClassObject");
2134 static void test_runnable(void)
2136 static const struct expected_method methods_query_runnable[] =
2138 { "OleObject_QueryInterface", 0 },
2139 { "OleObjectRunnable_AddRef", 0 },
2140 { "OleObjectRunnable_IsRunning", 0 },
2141 { "OleObjectRunnable_Release", 0 },
2142 { NULL, 0 }
2145 static const struct expected_method methods_no_runnable[] =
2147 { "OleObject_QueryInterface", 0 },
2148 { NULL, 0 }
2151 BOOL ret;
2152 IOleObject *object = &OleObject;
2154 /* null argument */
2155 ret = OleIsRunning(NULL);
2156 ok(ret == FALSE, "got %d\n", ret);
2158 expected_method_list = methods_query_runnable;
2159 ret = OleIsRunning(object);
2160 ok(ret == TRUE, "Object should be running\n");
2161 CHECK_NO_EXTRA_METHODS();
2163 g_isRunning = FALSE;
2164 expected_method_list = methods_query_runnable;
2165 ret = OleIsRunning(object);
2166 ok(ret == FALSE, "Object should not be running\n");
2167 CHECK_NO_EXTRA_METHODS();
2169 g_showRunnable = FALSE; /* QueryInterface(IID_IRunnableObject, ...) will fail */
2170 expected_method_list = methods_no_runnable;
2171 ret = OleIsRunning(object);
2172 ok(ret == TRUE, "Object without IRunnableObject should be running\n");
2173 CHECK_NO_EXTRA_METHODS();
2175 g_isRunning = TRUE;
2176 g_showRunnable = TRUE;
2179 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
2181 *ppv = NULL;
2182 if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface;
2183 if (*ppv)
2185 IUnknown_AddRef((IUnknown *)*ppv);
2186 return S_OK;
2188 return E_NOINTERFACE;
2191 static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
2193 return 2;
2196 static ULONG WINAPI Unknown_Release(IUnknown *iface)
2198 return 1;
2201 static const IUnknownVtbl UnknownVtbl =
2203 Unknown_QueryInterface,
2204 Unknown_AddRef,
2205 Unknown_Release
2208 static HRESULT WINAPI OleRun_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv)
2210 *ppv = NULL;
2212 if (IsEqualIID(riid, &IID_IUnknown) ||
2213 IsEqualIID(riid, &IID_IRunnableObject)) {
2214 *ppv = iface;
2217 if (*ppv)
2219 IUnknown_AddRef((IUnknown *)*ppv);
2220 return S_OK;
2223 return E_NOINTERFACE;
2226 static ULONG WINAPI OleRun_AddRef(IRunnableObject *iface)
2228 return 2;
2231 static ULONG WINAPI OleRun_Release(IRunnableObject *iface)
2233 return 1;
2236 static HRESULT WINAPI OleRun_GetRunningClass(IRunnableObject *iface, CLSID *clsid)
2238 ok(0, "unexpected\n");
2239 return E_NOTIMPL;
2242 static HRESULT WINAPI OleRun_Run(IRunnableObject *iface, LPBINDCTX ctx)
2244 ok(ctx == NULL, "got %p\n", ctx);
2245 return 0xdeadc0de;
2248 static BOOL WINAPI OleRun_IsRunning(IRunnableObject *iface)
2250 ok(0, "unexpected\n");
2251 return FALSE;
2254 static HRESULT WINAPI OleRun_LockRunning(IRunnableObject *iface, BOOL lock,
2255 BOOL last_unlock_closes)
2257 ok(0, "unexpected\n");
2258 return E_NOTIMPL;
2261 static HRESULT WINAPI OleRun_SetContainedObject(IRunnableObject *iface, BOOL contained)
2263 ok(0, "unexpected\n");
2264 return E_NOTIMPL;
2267 static const IRunnableObjectVtbl oleruntestvtbl =
2269 OleRun_QueryInterface,
2270 OleRun_AddRef,
2271 OleRun_Release,
2272 OleRun_GetRunningClass,
2273 OleRun_Run,
2274 OleRun_IsRunning,
2275 OleRun_LockRunning,
2276 OleRun_SetContainedObject
2279 static IUnknown unknown = { &UnknownVtbl };
2280 static IRunnableObject testrunnable = { &oleruntestvtbl };
2282 static void test_OleRun(void)
2284 HRESULT hr;
2286 /* doesn't support IRunnableObject */
2287 hr = OleRun(&unknown);
2288 ok(hr == S_OK, "OleRun failed 0x%08x\n", hr);
2290 hr = OleRun((IUnknown*)&testrunnable);
2291 ok(hr == 0xdeadc0de, "got 0x%08x\n", hr);
2294 static void test_OleLockRunning(void)
2296 HRESULT hr;
2298 hr = OleLockRunning((LPUNKNOWN)&unknown, TRUE, FALSE);
2299 ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr);
2302 static void test_OleDraw(void)
2304 HRESULT hr;
2305 RECT rect;
2307 hr = OleDraw((IUnknown*)&viewobject, 0, (HDC)0x1, NULL);
2308 ok(hr == S_OK, "got 0x%08x\n", hr);
2310 hr = OleDraw(NULL, 0, (HDC)0x1, NULL);
2311 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2313 hr = OleDraw(NULL, 0, (HDC)0x1, &rect);
2314 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2317 static const WCHAR comp_objW[] = {1,'C','o','m','p','O','b','j',0};
2318 static IStream *comp_obj_stream;
2319 static IStream *ole_stream;
2321 static HRESULT WINAPI Storage_QueryInterface(IStorage *iface, REFIID riid, void **ppvObject)
2323 ok(0, "unexpected call to QueryInterface\n");
2324 return E_NOTIMPL;
2327 static ULONG WINAPI Storage_AddRef(IStorage *iface)
2329 ok(0, "unexpected call to AddRef\n");
2330 return 2;
2333 static ULONG WINAPI Storage_Release(IStorage *iface)
2335 ok(0, "unexpected call to Release\n");
2336 return 1;
2339 static HRESULT WINAPI Storage_CreateStream(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm)
2341 ULARGE_INTEGER size = {{0}};
2342 LARGE_INTEGER pos = {{0}};
2343 HRESULT hr;
2345 CHECK_EXPECT(Storage_CreateStream_CompObj);
2346 ok(!lstrcmpW(pwcsName, comp_objW), "pwcsName = %s\n", wine_dbgstr_w(pwcsName));
2347 todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
2348 ok(!reserved1, "reserved1 = %x\n", reserved1);
2349 ok(!reserved2, "reserved2 = %x\n", reserved2);
2350 ok(!!ppstm, "ppstm = NULL\n");
2352 *ppstm = comp_obj_stream;
2353 IStream_AddRef(comp_obj_stream);
2354 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2355 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2356 hr = IStream_SetSize(comp_obj_stream, size);
2357 ok(hr == S_OK, "IStream_SetSize returned %x\n", hr);
2358 return S_OK;
2361 static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm)
2363 static const WCHAR ole1W[] = {1,'O','l','e',0};
2365 LARGE_INTEGER pos = {{0}};
2366 HRESULT hr;
2368 ok(!reserved1, "reserved1 = %p\n", reserved1);
2369 ok(!reserved2, "reserved2 = %x\n", reserved2);
2370 ok(!!ppstm, "ppstm = NULL\n");
2372 if(!lstrcmpW(pwcsName, comp_objW)) {
2373 CHECK_EXPECT2(Storage_OpenStream_CompObj);
2374 ok(grfMode == STGM_SHARE_EXCLUSIVE, "grfMode = %x\n", grfMode);
2376 *ppstm = comp_obj_stream;
2377 IStream_AddRef(comp_obj_stream);
2378 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2379 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2380 return S_OK;
2381 }else if(!lstrcmpW(pwcsName, ole1W)) {
2382 CHECK_EXPECT(Storage_OpenStream_Ole);
2383 ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode);
2385 *ppstm = ole_stream;
2386 IStream_AddRef(ole_stream);
2387 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
2388 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2389 return S_OK;
2392 ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName));
2393 return E_NOTIMPL;
2396 static HRESULT WINAPI Storage_CreateStorage(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD dwStgFmt, DWORD reserved2, IStorage **ppstg)
2398 ok(0, "unexpected call to CreateStorage\n");
2399 return E_NOTIMPL;
2402 static HRESULT WINAPI Storage_OpenStorage(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg)
2404 ok(0, "unexpected call to OpenStorage\n");
2405 return E_NOTIMPL;
2408 static HRESULT WINAPI Storage_CopyTo(IStorage *iface, DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest)
2410 ok(0, "unexpected call to CopyTo\n");
2411 return E_NOTIMPL;
2414 static HRESULT WINAPI Storage_MoveElementTo(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgDest, LPCOLESTR pwcsNewName, DWORD grfFlags)
2416 ok(0, "unexpected call to MoveElementTo\n");
2417 return E_NOTIMPL;
2420 static HRESULT WINAPI Storage_Commit(IStorage *iface, DWORD grfCommitFlags)
2422 ok(0, "unexpected call to Commit\n");
2423 return E_NOTIMPL;
2426 static HRESULT WINAPI Storage_Revert(IStorage *iface)
2428 ok(0, "unexpected call to Revert\n");
2429 return E_NOTIMPL;
2432 static HRESULT WINAPI Storage_EnumElements(IStorage *iface, DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum)
2434 ok(0, "unexpected call to EnumElements\n");
2435 return E_NOTIMPL;
2438 static HRESULT WINAPI Storage_DestroyElement(IStorage *iface, LPCOLESTR pwcsName)
2440 ok(0, "unexpected call to DestroyElement\n");
2441 return E_NOTIMPL;
2444 static HRESULT WINAPI Storage_RenameElement(IStorage *iface, LPCOLESTR pwcsOldName, LPCOLESTR pwcsNewName)
2446 ok(0, "unexpected call to RenameElement\n");
2447 return E_NOTIMPL;
2450 static HRESULT WINAPI Storage_SetElementTimes(IStorage *iface, LPCOLESTR pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime)
2452 ok(0, "unexpected call to SetElementTimes\n");
2453 return E_NOTIMPL;
2456 static HRESULT WINAPI Storage_SetClass(IStorage *iface, REFCLSID clsid)
2458 CHECK_EXPECT(Storage_SetClass);
2459 ok(IsEqualIID(clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(clsid));
2460 return S_OK;
2463 static HRESULT WINAPI Storage_SetStateBits(IStorage *iface, DWORD grfStateBits, DWORD grfMask)
2465 ok(0, "unexpected call to SetStateBits\n");
2466 return E_NOTIMPL;
2469 static HRESULT WINAPI Storage_Stat(IStorage *iface, STATSTG *pstatstg, DWORD grfStatFlag)
2471 CHECK_EXPECT2(Storage_Stat);
2472 ok(pstatstg != NULL, "pstatstg = NULL\n");
2473 ok(grfStatFlag == STATFLAG_NONAME, "grfStatFlag = %x\n", grfStatFlag);
2475 memset(pstatstg, 0, sizeof(STATSTG));
2476 pstatstg->type = STGTY_STORAGE;
2477 pstatstg->clsid = CLSID_WineTestOld;
2478 return S_OK;
2481 static IStorageVtbl StorageVtbl =
2483 Storage_QueryInterface,
2484 Storage_AddRef,
2485 Storage_Release,
2486 Storage_CreateStream,
2487 Storage_OpenStream,
2488 Storage_CreateStorage,
2489 Storage_OpenStorage,
2490 Storage_CopyTo,
2491 Storage_MoveElementTo,
2492 Storage_Commit,
2493 Storage_Revert,
2494 Storage_EnumElements,
2495 Storage_DestroyElement,
2496 Storage_RenameElement,
2497 Storage_SetElementTimes,
2498 Storage_SetClass,
2499 Storage_SetStateBits,
2500 Storage_Stat
2503 static IStorage Storage = { &StorageVtbl };
2505 static void test_OleDoAutoConvert(void)
2507 static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0};
2508 static struct {
2509 DWORD reserved1;
2510 DWORD version;
2511 DWORD reserved2[5];
2512 DWORD ansi_user_type_len;
2513 DWORD ansi_clipboard_format_len;
2514 DWORD reserved3;
2515 DWORD unicode_marker;
2516 DWORD unicode_user_type_len;
2517 DWORD unicode_clipboard_format_len;
2518 DWORD reserved4;
2519 } comp_obj_data;
2520 static struct {
2521 DWORD version;
2522 DWORD flags;
2523 DWORD link_update_option;
2524 DWORD reserved1;
2525 DWORD reserved_moniker_stream_size;
2526 DWORD relative_source_moniker_stream_size;
2527 DWORD absolute_source_moniker_stream_size;
2528 DWORD clsid_indicator;
2529 CLSID clsid;
2530 DWORD reserved_display_name;
2531 DWORD reserved2;
2532 DWORD local_update_time;
2533 DWORD local_check_update_time;
2534 DWORD remote_update_time;
2535 } ole_data;
2537 LARGE_INTEGER pos = {{0}};
2538 WCHAR buf[39+6];
2539 DWORD i, ret;
2540 HKEY root;
2541 CLSID clsid;
2542 HRESULT hr;
2544 hr = CreateStreamOnHGlobal(NULL, TRUE, &comp_obj_stream);
2545 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
2546 hr = IStream_Write(comp_obj_stream, (char*)&comp_obj_data, sizeof(comp_obj_data), NULL);
2547 ok(hr == S_OK, "IStream_Write returned %x\n", hr);
2549 hr = CreateStreamOnHGlobal(NULL, TRUE, &ole_stream);
2550 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr);
2551 hr = IStream_Write(ole_stream, (char*)&ole_data, sizeof(ole_data), NULL);
2552 ok(hr == S_OK, "IStream_Write returned %x\n", hr);
2554 clsid = IID_WineTest;
2555 hr = OleDoAutoConvert(NULL, &clsid);
2556 ok(hr == E_INVALIDARG, "OleDoAutoConvert returned %x\n", hr);
2557 ok(IsEqualIID(&clsid, &IID_NULL), "clsid = %s\n", wine_dbgstr_guid(&clsid));
2559 if(0) /* crashes on Win7 */
2560 OleDoAutoConvert(&Storage, NULL);
2562 clsid = IID_WineTest;
2563 SET_EXPECT(Storage_Stat);
2564 hr = OleDoAutoConvert(&Storage, &clsid);
2565 ok(hr == REGDB_E_CLASSNOTREG, "OleDoAutoConvert returned %x\n", hr);
2566 CHECK_CALLED(Storage_Stat);
2567 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
2569 lstrcpyW(buf, clsidW);
2570 StringFromGUID2(&CLSID_WineTestOld, buf+6, 39);
2572 ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0,
2573 KEY_READ | KEY_WRITE | KEY_CREATE_SUB_KEY, NULL, &root, NULL);
2574 if(ret != ERROR_SUCCESS) {
2575 win_skip("not enough permissions to create CLSID key (%u)\n", ret);
2576 return;
2579 clsid = IID_WineTest;
2580 SET_EXPECT(Storage_Stat);
2581 hr = OleDoAutoConvert(&Storage, &clsid);
2582 ok(hr == REGDB_E_KEYMISSING, "OleDoAutoConvert returned %x\n", hr);
2583 CHECK_CALLED(Storage_Stat);
2584 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid));
2586 hr = OleSetAutoConvert(&CLSID_WineTestOld, &CLSID_WineTest);
2587 ok_ole_success(hr, "OleSetAutoConvert");
2589 hr = OleGetAutoConvert(&CLSID_WineTestOld, &clsid);
2590 ok_ole_success(hr, "OleGetAutoConvert");
2591 ok(IsEqualIID(&clsid, &CLSID_WineTest), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid));
2593 clsid = IID_WineTest;
2594 SET_EXPECT(Storage_Stat);
2595 SET_EXPECT(Storage_OpenStream_CompObj);
2596 SET_EXPECT(Storage_SetClass);
2597 SET_EXPECT(Storage_CreateStream_CompObj);
2598 SET_EXPECT(Storage_OpenStream_Ole);
2599 hr = OleDoAutoConvert(&Storage, &clsid);
2600 ok(hr == S_OK, "OleDoAutoConvert returned %x\n", hr);
2601 CHECK_CALLED(Storage_Stat);
2602 CHECK_CALLED(Storage_OpenStream_CompObj);
2603 CHECK_CALLED(Storage_SetClass);
2604 CHECK_CALLED(Storage_CreateStream_CompObj);
2605 CHECK_CALLED(Storage_OpenStream_Ole);
2606 ok(IsEqualIID(&clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(&clsid));
2608 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2609 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2610 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
2611 ok(hr == S_OK, "IStream_Read returned %x\n", hr);
2612 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
2613 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
2614 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
2615 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
2616 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
2617 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
2618 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
2619 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
2620 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
2621 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
2622 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
2624 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL);
2625 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2626 hr = IStream_Read(ole_stream, &ole_data, sizeof(ole_data), NULL);
2627 ok(hr == S_OK, "IStream_Read returned %x\n", hr);
2628 ok(ole_data.version == 0, "version = %x\n", ole_data.version);
2629 ok(ole_data.flags == 4, "flags = %x\n", ole_data.flags);
2630 for(i=2; i<sizeof(ole_data)/sizeof(DWORD); i++)
2631 ok(((DWORD*)&ole_data)[i] == 0, "ole_data[%d] = %x\n", i, ((DWORD*)&ole_data)[i]);
2633 SET_EXPECT(Storage_OpenStream_Ole);
2634 hr = SetConvertStg(&Storage, TRUE);
2635 ok(hr == S_OK, "SetConvertStg returned %x\n", hr);
2636 CHECK_CALLED(Storage_OpenStream_Ole);
2638 SET_EXPECT(Storage_OpenStream_CompObj);
2639 SET_EXPECT(Storage_Stat);
2640 SET_EXPECT(Storage_CreateStream_CompObj);
2641 hr = WriteFmtUserTypeStg(&Storage, 0, NULL);
2642 ok(hr == S_OK, "WriteFmtUserTypeStg returned %x\n", hr);
2643 todo_wine CHECK_CALLED(Storage_OpenStream_CompObj);
2644 CHECK_CALLED(Storage_Stat);
2645 CHECK_CALLED(Storage_CreateStream_CompObj);
2646 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL);
2647 ok(hr == S_OK, "IStream_Seek returned %x\n", hr);
2648 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL);
2649 ok(hr == S_OK, "IStream_Read returned %x\n", hr);
2650 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1);
2651 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version);
2652 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]);
2653 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1)));
2654 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len);
2655 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len);
2656 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3);
2657 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker);
2658 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len);
2659 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len);
2660 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4);
2662 ret = IStream_Release(comp_obj_stream);
2663 ok(!ret, "comp_obj_stream was not freed\n");
2664 ret = IStream_Release(ole_stream);
2665 ok(!ret, "ole_stream was not freed\n");
2667 ret = RegDeleteKeyA(root, "AutoConvertTo");
2668 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
2669 ret = RegDeleteKeyA(root, "");
2670 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret);
2671 RegCloseKey(root);
2674 START_TEST(ole2)
2676 DWORD dwRegister;
2677 IStorage *pStorage;
2678 STATSTG statstg;
2679 HRESULT hr;
2681 cf_test_1 = RegisterClipboardFormatA("cf_winetest_1");
2682 cf_test_2 = RegisterClipboardFormatA("cf_winetest_2");
2683 cf_test_3 = RegisterClipboardFormatA("cf_winetest_3");
2685 CoInitialize(NULL);
2687 hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
2688 ok_ole_success(hr, "CoRegisterClassObject");
2690 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage);
2691 ok_ole_success(hr, "StgCreateDocfile");
2693 test_OleCreate(pStorage);
2695 hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME);
2696 ok_ole_success(hr, "IStorage_Stat");
2697 ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n");
2699 test_OleLoad(pStorage);
2701 IStorage_Release(pStorage);
2703 hr = CoRevokeClassObject(dwRegister);
2704 ok_ole_success(hr, "CoRevokeClassObject");
2706 test_data_cache();
2707 test_data_cache_dib_contents_stream( 0 );
2708 test_data_cache_dib_contents_stream( 1 );
2709 test_default_handler();
2710 test_runnable();
2711 test_OleRun();
2712 test_OleLockRunning();
2713 test_OleDraw();
2714 test_OleDoAutoConvert();
2716 CoUninitialize();