2 * Object Linking and Embedding Tests
4 * Copyright 2005 Robert Shearman
5 * Copyright 2017 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define WIN32_LEAN_AND_MEAN
34 #include "wine/test.h"
38 DEFINE_GUID(CLSID_Picture_Metafile
,0x315,0,0,0xc0,0,0,0,0,0,0,0x46);
39 DEFINE_GUID(CLSID_Picture_Dib
,0x316,0,0,0xc0,0,0,0,0,0,0,0x46);
40 DEFINE_GUID(CLSID_Picture_EnhMetafile
,0x319,0,0,0xc0,0,0,0,0,0,0,0x46);
42 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
44 #define DEFINE_EXPECT(func) \
45 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
47 #define SET_EXPECT(func) \
48 expect_ ## func = TRUE
50 #define CHECK_EXPECT2(func) \
52 ok(expect_ ##func, "unexpected call " #func "\n"); \
53 called_ ## func = TRUE; \
56 #define CHECK_EXPECT(func) \
58 CHECK_EXPECT2(func); \
59 expect_ ## func = FALSE; \
62 #define CHECK_CALLED(func) \
64 ok(called_ ## func, "expected " #func "\n"); \
65 expect_ ## func = called_ ## func = FALSE; \
68 DEFINE_EXPECT(Storage_Stat
);
69 DEFINE_EXPECT(Storage_OpenStream_CompObj
);
70 DEFINE_EXPECT(Storage_OpenStream_OlePres
);
71 DEFINE_EXPECT(Storage_SetClass
);
72 DEFINE_EXPECT(Storage_CreateStream_CompObj
);
73 DEFINE_EXPECT(Storage_CreateStream_OlePres
);
74 DEFINE_EXPECT(Storage_OpenStream_Ole
);
75 DEFINE_EXPECT(Storage_DestroyElement
);
77 static const CLSID
*Storage_SetClass_CLSID
;
78 static int Storage_DestroyElement_limit
;
80 static IPersistStorage OleObjectPersistStg
;
81 static IOleCache
*cache
;
82 static IRunnableObject
*runnable
;
84 static const CLSID CLSID_WineTestOld
=
85 { /* 9474ba1a-258b-490b-bc13-516e9239acd0 */
89 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xd0}
92 static const CLSID CLSID_WineTest
=
93 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */
97 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0}
100 static const IID IID_WineTest
=
101 { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */
105 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1}
108 #define TEST_OPTIONAL 0x1
109 #define TEST_TODO 0x2
111 struct expected_method
118 static const struct expected_method
*expected_method_list
;
119 static FORMATETC
*g_expected_fetc
= NULL
;
121 static BOOL g_showRunnable
= TRUE
;
122 static BOOL g_isRunning
= TRUE
;
123 static HRESULT g_GetMiscStatusFailsWith
= S_OK
;
124 static HRESULT g_QIFailsWith
;
126 static UINT cf_test_1
, cf_test_2
, cf_test_3
;
128 static FORMATETC
*g_dataobject_fmts
;
130 /****************************************************************************
131 * PresentationDataHeader
133 * This structure represents the header of the \002OlePresXXX stream in
134 * the OLE object storage.
136 typedef struct PresentationDataHeader
139 * - standard clipformat:
140 * DWORD length = 0xffffffff;
142 * - or custom clipformat:
144 * CHAR format_name[length]; (null-terminated)
146 DWORD tdSize
; /* This is actually a truncated DVTARGETDEVICE, if tdSize > sizeof(DWORD)
147 then there are tdSize - sizeof(DWORD) more bytes before dvAspect */
151 DWORD unknown7
; /* 0 */
152 DWORD dwObjectExtentX
;
153 DWORD dwObjectExtentY
;
155 } PresentationDataHeader
;
158 static inline void check_expected_method_fmt(const char *method_name
, const FORMATETC
*fmt
)
160 static void inline check_expected_method_fmt(const char *method_name
, const FORMATETC
*fmt
)
163 trace("%s\n", method_name
);
164 ok(expected_method_list
->method
!= NULL
, "Extra method %s called\n", method_name
);
165 if (!strcmp(expected_method_list
->method
, "WINE_EXTRA"))
167 todo_wine
ok(0, "Too many method calls.\n");
170 if (expected_method_list
->method
)
172 while (expected_method_list
->flags
& TEST_OPTIONAL
&&
173 strcmp(expected_method_list
->method
, method_name
) != 0)
174 expected_method_list
++;
175 todo_wine_if (expected_method_list
->flags
& TEST_TODO
)
177 ok(!strcmp(expected_method_list
->method
, method_name
),
178 "Expected %s to be called instead of %s\n",
179 expected_method_list
->method
, method_name
);
182 ok(fmt
->cfFormat
== expected_method_list
->fmt
.cfFormat
, "got cf %04x vs %04x\n",
183 fmt
->cfFormat
, expected_method_list
->fmt
.cfFormat
);
184 ok(fmt
->dwAspect
== expected_method_list
->fmt
.dwAspect
, "got aspect %d vs %d\n",
185 fmt
->dwAspect
, expected_method_list
->fmt
.dwAspect
);
186 ok(fmt
->lindex
== expected_method_list
->fmt
.lindex
, "got lindex %d vs %d\n",
187 fmt
->lindex
, expected_method_list
->fmt
.lindex
);
188 ok(fmt
->tymed
== expected_method_list
->fmt
.tymed
, "got tymed %d vs %d\n",
189 fmt
->tymed
, expected_method_list
->fmt
.tymed
);
192 expected_method_list
++;
196 #define CHECK_EXPECTED_METHOD(method_name) check_expected_method_fmt(method_name, NULL)
197 #define CHECK_EXPECTED_METHOD_FMT(method_name, fmt) check_expected_method_fmt(method_name, fmt)
199 #define CHECK_NO_EXTRA_METHODS() \
201 while (expected_method_list->flags & TEST_OPTIONAL) \
202 expected_method_list++; \
203 ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
206 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
207 static const BYTE dib
[] =
209 0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
210 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212 0xc8, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
217 static void create_dib( STGMEDIUM
*med
)
221 med
->tymed
= TYMED_HGLOBAL
;
222 U(med
)->hGlobal
= GlobalAlloc( GMEM_MOVEABLE
, sizeof(dib
) );
223 ptr
= GlobalLock( U(med
)->hGlobal
);
224 memcpy( ptr
, dib
, sizeof(dib
) );
225 GlobalUnlock( U(med
)->hGlobal
);
226 med
->pUnkForRelease
= NULL
;
229 static void create_bitmap( STGMEDIUM
*med
)
231 med
->tymed
= TYMED_GDI
;
232 U(med
)->hBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
233 med
->pUnkForRelease
= NULL
;
236 static void create_emf(STGMEDIUM
*med
)
238 HDC hdc
= CreateEnhMetaFileW(NULL
, NULL
, NULL
, NULL
);
240 Rectangle(hdc
, 0, 0, 150, 300);
241 med
->tymed
= TYMED_ENHMF
;
242 U(med
)->hEnhMetaFile
= CloseEnhMetaFile(hdc
);
243 med
->pUnkForRelease
= NULL
;
246 static void create_mfpict(STGMEDIUM
*med
)
249 HDC hdc
= CreateMetaFileW(NULL
);
251 Rectangle(hdc
, 0, 0, 100, 200);
253 med
->tymed
= TYMED_MFPICT
;
254 U(med
)->hMetaFilePict
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(METAFILEPICT
));
255 mf
= GlobalLock(U(med
)->hMetaFilePict
);
256 mf
->mm
= MM_ANISOTROPIC
;
259 mf
->hMF
= CloseMetaFile(hdc
);
260 GlobalUnlock(U(med
)->hMetaFilePict
);
261 med
->pUnkForRelease
= NULL
;
264 static HRESULT WINAPI
OleObject_QueryInterface(IOleObject
*iface
, REFIID riid
, void **ppv
)
266 CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
270 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IOleObject
))
272 else if (IsEqualIID(riid
, &IID_IPersistStorage
))
273 *ppv
= &OleObjectPersistStg
;
274 else if (IsEqualIID(riid
, &IID_IOleCache
))
276 else if (IsEqualIID(riid
, &IID_IRunnableObject
) && g_showRunnable
)
278 else if (IsEqualIID(riid
, &IID_WineTest
))
279 return g_QIFailsWith
;
282 IUnknown_AddRef((IUnknown
*)*ppv
);
286 trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
287 return E_NOINTERFACE
;
290 static ULONG WINAPI
OleObject_AddRef(IOleObject
*iface
)
292 CHECK_EXPECTED_METHOD("OleObject_AddRef");
296 static ULONG WINAPI
OleObject_Release(IOleObject
*iface
)
298 CHECK_EXPECTED_METHOD("OleObject_Release");
302 static HRESULT WINAPI OleObject_SetClientSite
305 IOleClientSite
*pClientSite
308 CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
312 static HRESULT WINAPI OleObject_GetClientSite
315 IOleClientSite
**ppClientSite
318 CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
322 static HRESULT WINAPI OleObject_SetHostNames
325 LPCOLESTR szContainerApp
,
326 LPCOLESTR szContainerObj
329 CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
333 static HRESULT WINAPI OleObject_Close
339 CHECK_EXPECTED_METHOD("OleObject_Close");
343 static HRESULT WINAPI OleObject_SetMoniker
346 DWORD dwWhichMoniker
,
350 CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
354 static HRESULT WINAPI OleObject_GetMoniker
358 DWORD dwWhichMoniker
,
362 CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
366 static HRESULT WINAPI OleObject_InitFromData
369 IDataObject
*pDataObject
,
374 CHECK_EXPECTED_METHOD("OleObject_InitFromData");
378 static HRESULT WINAPI OleObject_GetClipboardData
382 IDataObject
**ppDataObject
385 CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
389 static HRESULT WINAPI OleObject_DoVerb
394 IOleClientSite
*pActiveSite
,
400 CHECK_EXPECTED_METHOD("OleObject_DoVerb");
404 static HRESULT WINAPI OleObject_EnumVerbs
407 IEnumOLEVERB
**ppEnumOleVerb
410 CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
414 static HRESULT WINAPI OleObject_Update
419 CHECK_EXPECTED_METHOD("OleObject_Update");
423 static HRESULT WINAPI OleObject_IsUpToDate
428 CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
432 static HRESULT WINAPI OleObject_GetUserClassID
438 CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
442 static HRESULT WINAPI OleObject_GetUserType
446 LPOLESTR
*pszUserType
449 CHECK_EXPECTED_METHOD("OleObject_GetUserType");
453 static HRESULT WINAPI OleObject_SetExtent
460 CHECK_EXPECTED_METHOD("OleObject_SetExtent");
464 static HRESULT WINAPI OleObject_GetExtent
471 CHECK_EXPECTED_METHOD("OleObject_GetExtent");
475 static HRESULT WINAPI OleObject_Advise
478 IAdviseSink
*pAdvSink
,
482 CHECK_EXPECTED_METHOD("OleObject_Advise");
486 static HRESULT WINAPI OleObject_Unadvise
492 CHECK_EXPECTED_METHOD("OleObject_Unadvise");
496 static HRESULT WINAPI OleObject_EnumAdvise
499 IEnumSTATDATA
**ppenumAdvise
502 CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
506 static HRESULT WINAPI OleObject_GetMiscStatus
513 CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
515 ok(aspect
== DVASPECT_CONTENT
, "got aspect %d\n", aspect
);
517 if (g_GetMiscStatusFailsWith
== S_OK
)
519 *pdwStatus
= OLEMISC_RECOMPOSEONRESIZE
;
525 return g_GetMiscStatusFailsWith
;
529 static HRESULT WINAPI OleObject_SetColorScheme
535 CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
539 static const IOleObjectVtbl OleObjectVtbl
=
541 OleObject_QueryInterface
,
544 OleObject_SetClientSite
,
545 OleObject_GetClientSite
,
546 OleObject_SetHostNames
,
548 OleObject_SetMoniker
,
549 OleObject_GetMoniker
,
550 OleObject_InitFromData
,
551 OleObject_GetClipboardData
,
555 OleObject_IsUpToDate
,
556 OleObject_GetUserClassID
,
557 OleObject_GetUserType
,
562 OleObject_EnumAdvise
,
563 OleObject_GetMiscStatus
,
564 OleObject_SetColorScheme
567 static IOleObject OleObject
= { &OleObjectVtbl
};
569 static HRESULT WINAPI
OleObjectPersistStg_QueryInterface(IPersistStorage
*iface
, REFIID riid
, void **ppv
)
571 trace("OleObjectPersistStg_QueryInterface\n");
572 return IOleObject_QueryInterface(&OleObject
, riid
, ppv
);
575 static ULONG WINAPI
OleObjectPersistStg_AddRef(IPersistStorage
*iface
)
577 CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
581 static ULONG WINAPI
OleObjectPersistStg_Release(IPersistStorage
*iface
)
583 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
587 static HRESULT WINAPI
OleObjectPersistStg_GetClassId(IPersistStorage
*iface
, CLSID
*clsid
)
589 CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
593 static HRESULT WINAPI OleObjectPersistStg_IsDirty
595 IPersistStorage
*iface
598 CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
602 static HRESULT WINAPI OleObjectPersistStg_InitNew
604 IPersistStorage
*iface
,
608 CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
612 static HRESULT WINAPI OleObjectPersistStg_Load
614 IPersistStorage
*iface
,
618 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
622 static HRESULT WINAPI OleObjectPersistStg_Save
624 IPersistStorage
*iface
,
629 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
633 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
635 IPersistStorage
*iface
,
639 CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
643 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
645 IPersistStorage
*iface
648 CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
652 static const IPersistStorageVtbl OleObjectPersistStgVtbl
=
654 OleObjectPersistStg_QueryInterface
,
655 OleObjectPersistStg_AddRef
,
656 OleObjectPersistStg_Release
,
657 OleObjectPersistStg_GetClassId
,
658 OleObjectPersistStg_IsDirty
,
659 OleObjectPersistStg_InitNew
,
660 OleObjectPersistStg_Load
,
661 OleObjectPersistStg_Save
,
662 OleObjectPersistStg_SaveCompleted
,
663 OleObjectPersistStg_HandsOffStorage
666 static IPersistStorage OleObjectPersistStg
= { &OleObjectPersistStgVtbl
};
668 static HRESULT WINAPI
OleObjectCache_QueryInterface(IOleCache
*iface
, REFIID riid
, void **ppv
)
670 return IOleObject_QueryInterface(&OleObject
, riid
, ppv
);
673 static ULONG WINAPI
OleObjectCache_AddRef(IOleCache
*iface
)
675 CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
679 static ULONG WINAPI
OleObjectCache_Release(IOleCache
*iface
)
681 CHECK_EXPECTED_METHOD("OleObjectCache_Release");
685 static HRESULT WINAPI OleObjectCache_Cache
688 FORMATETC
*pformatetc
,
693 CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
694 if (g_expected_fetc
) {
695 ok(pformatetc
!= NULL
, "pformatetc should not be NULL\n");
697 ok(pformatetc
->cfFormat
== g_expected_fetc
->cfFormat
,
698 "cfFormat: %x\n", pformatetc
->cfFormat
);
699 ok((pformatetc
->ptd
!= NULL
) == (g_expected_fetc
->ptd
!= NULL
),
700 "ptd: %p\n", pformatetc
->ptd
);
701 ok(pformatetc
->dwAspect
== g_expected_fetc
->dwAspect
,
702 "dwAspect: %x\n", pformatetc
->dwAspect
);
703 ok(pformatetc
->lindex
== g_expected_fetc
->lindex
,
704 "lindex: %x\n", pformatetc
->lindex
);
705 ok(pformatetc
->tymed
== g_expected_fetc
->tymed
,
706 "tymed: %x\n", pformatetc
->tymed
);
709 ok(pformatetc
== NULL
, "pformatetc should be NULL\n");
713 static HRESULT WINAPI OleObjectCache_Uncache
719 CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
723 static HRESULT WINAPI OleObjectCache_EnumCache
726 IEnumSTATDATA
**ppenumSTATDATA
729 CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
734 static HRESULT WINAPI OleObjectCache_InitCache
737 IDataObject
*pDataObject
740 CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
745 static HRESULT WINAPI OleObjectCache_SetData
748 FORMATETC
*pformatetc
,
753 CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
758 static const IOleCacheVtbl OleObjectCacheVtbl
=
760 OleObjectCache_QueryInterface
,
761 OleObjectCache_AddRef
,
762 OleObjectCache_Release
,
763 OleObjectCache_Cache
,
764 OleObjectCache_Uncache
,
765 OleObjectCache_EnumCache
,
766 OleObjectCache_InitCache
,
767 OleObjectCache_SetData
770 static IOleCache OleObjectCache
= { &OleObjectCacheVtbl
};
772 static HRESULT WINAPI
OleObjectCF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
774 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IClassFactory
))
777 IClassFactory_AddRef(iface
);
781 return E_NOINTERFACE
;
784 static ULONG WINAPI
OleObjectCF_AddRef(IClassFactory
*iface
)
789 static ULONG WINAPI
OleObjectCF_Release(IClassFactory
*iface
)
794 static HRESULT WINAPI
OleObjectCF_CreateInstance(IClassFactory
*iface
, IUnknown
*punkOuter
, REFIID riid
, void **ppv
)
796 return IOleObject_QueryInterface(&OleObject
, riid
, ppv
);
799 static HRESULT WINAPI
OleObjectCF_LockServer(IClassFactory
*iface
, BOOL lock
)
804 static const IClassFactoryVtbl OleObjectCFVtbl
=
806 OleObjectCF_QueryInterface
,
809 OleObjectCF_CreateInstance
,
810 OleObjectCF_LockServer
813 static IClassFactory OleObjectCF
= { &OleObjectCFVtbl
};
815 static HRESULT WINAPI
OleObjectRunnable_QueryInterface(IRunnableObject
*iface
, REFIID riid
, void **ppv
)
817 return IOleObject_QueryInterface(&OleObject
, riid
, ppv
);
820 static ULONG WINAPI
OleObjectRunnable_AddRef(IRunnableObject
*iface
)
822 CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
826 static ULONG WINAPI
OleObjectRunnable_Release(IRunnableObject
*iface
)
828 CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
832 static HRESULT WINAPI
OleObjectRunnable_GetRunningClass(
833 IRunnableObject
*iface
,
836 CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
840 static HRESULT WINAPI
OleObjectRunnable_Run(
841 IRunnableObject
*iface
,
844 CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
848 static BOOL WINAPI
OleObjectRunnable_IsRunning(IRunnableObject
*iface
)
850 CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
854 static HRESULT WINAPI
OleObjectRunnable_LockRunning(
855 IRunnableObject
*iface
,
857 BOOL fLastUnlockCloses
)
859 CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
863 static HRESULT WINAPI
OleObjectRunnable_SetContainedObject(
864 IRunnableObject
*iface
,
867 CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
871 static const IRunnableObjectVtbl OleObjectRunnableVtbl
=
873 OleObjectRunnable_QueryInterface
,
874 OleObjectRunnable_AddRef
,
875 OleObjectRunnable_Release
,
876 OleObjectRunnable_GetRunningClass
,
877 OleObjectRunnable_Run
,
878 OleObjectRunnable_IsRunning
,
879 OleObjectRunnable_LockRunning
,
880 OleObjectRunnable_SetContainedObject
883 static IRunnableObject OleObjectRunnable
= { &OleObjectRunnableVtbl
};
885 static const CLSID CLSID_Equation3
= {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
887 static HRESULT WINAPI
viewobject_QueryInterface(IViewObject
*iface
, REFIID riid
, void **obj
)
889 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IViewObject
))
896 return E_NOINTERFACE
;
899 static ULONG WINAPI
viewobject_AddRef(IViewObject
*iface
)
904 static ULONG WINAPI
viewobject_Release(IViewObject
*iface
)
909 static HRESULT WINAPI
viewobject_Draw(IViewObject
*iface
, DWORD aspect
, LONG index
,
910 void *paspect
, DVTARGETDEVICE
*ptd
, HDC hdcTargetDev
, HDC hdcDraw
,
911 LPCRECTL bounds
, LPCRECTL wbounds
, BOOL (STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
),
912 ULONG_PTR dwContinue
)
914 ok(index
== -1, "index=%d\n", index
);
918 static HRESULT WINAPI
viewobject_GetColorSet(IViewObject
*iface
, DWORD draw_aspect
, LONG index
,
919 void *aspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**colorset
)
921 ok(0, "unexpected call GetColorSet\n");
925 static HRESULT WINAPI
viewobject_Freeze(IViewObject
*iface
, DWORD draw_aspect
, LONG index
,
926 void *aspect
, DWORD
*freeze
)
928 ok(0, "unexpected call Freeze\n");
932 static HRESULT WINAPI
viewobject_Unfreeze(IViewObject
*iface
, DWORD freeze
)
934 ok(0, "unexpected call Unfreeze\n");
938 static HRESULT WINAPI
viewobject_SetAdvise(IViewObject
*iface
, DWORD aspects
, DWORD advf
, IAdviseSink
*sink
)
940 ok(0, "unexpected call SetAdvise\n");
944 static HRESULT WINAPI
viewobject_GetAdvise(IViewObject
*iface
, DWORD
*aspects
, DWORD
*advf
,
947 ok(0, "unexpected call GetAdvise\n");
951 static const struct IViewObjectVtbl viewobjectvtbl
= {
952 viewobject_QueryInterface
,
956 viewobject_GetColorSet
,
959 viewobject_SetAdvise
,
963 static IViewObject viewobject
= { &viewobjectvtbl
};
965 static void test_OleCreate(IStorage
*pStorage
)
970 static const struct expected_method methods_olerender_none
[] =
972 { "OleObject_QueryInterface", 0 },
973 { "OleObject_AddRef", 0 },
974 { "OleObject_QueryInterface", 0 },
975 { "OleObject_AddRef", TEST_OPTIONAL
},
976 { "OleObject_Release", TEST_OPTIONAL
},
977 { "OleObject_QueryInterface", TEST_OPTIONAL
},
978 { "OleObjectPersistStg_AddRef", 0 },
979 { "OleObjectPersistStg_InitNew", 0 },
980 { "OleObjectPersistStg_Release", 0 },
981 { "OleObject_Release", 0 },
982 { "OleObject_Release", TEST_OPTIONAL
},
985 static const struct expected_method methods_olerender_draw
[] =
987 { "OleObject_QueryInterface", 0 },
988 { "OleObject_AddRef", 0 },
989 { "OleObject_QueryInterface", 0 },
990 { "OleObject_AddRef", TEST_OPTIONAL
/* NT4 only */ },
991 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
992 { "OleObject_QueryInterface", TEST_OPTIONAL
/* NT4 only */ },
993 { "OleObjectPersistStg_AddRef", 0 },
994 { "OleObjectPersistStg_InitNew", 0 },
995 { "OleObjectPersistStg_Release", 0 },
996 { "OleObject_QueryInterface", 0 },
997 { "OleObjectRunnable_AddRef", 0 },
998 { "OleObjectRunnable_Run", 0 },
999 { "OleObjectRunnable_Release", 0 },
1000 { "OleObject_QueryInterface", 0 },
1001 { "OleObjectCache_AddRef", 0 },
1002 { "OleObjectCache_Cache", 0 },
1003 { "OleObjectCache_Release", 0 },
1004 { "OleObject_Release", 0 },
1005 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1008 static const struct expected_method methods_olerender_draw_with_site
[] =
1010 { "OleObject_QueryInterface", 0 },
1011 { "OleObject_AddRef", 0 },
1012 { "OleObject_QueryInterface", 0 },
1013 { "OleObject_AddRef", 0 },
1014 { "OleObject_GetMiscStatus", 0 },
1015 { "OleObject_QueryInterface", 0 },
1016 { "OleObjectPersistStg_AddRef", 0 },
1017 { "OleObjectPersistStg_InitNew", 0 },
1018 { "OleObjectPersistStg_Release", 0 },
1019 { "OleObject_SetClientSite", 0 },
1020 { "OleObject_Release", 0 },
1021 { "OleObject_QueryInterface", 0 },
1022 { "OleObjectRunnable_AddRef", 0 },
1023 { "OleObjectRunnable_Run", 0 },
1024 { "OleObjectRunnable_Release", 0 },
1025 { "OleObject_QueryInterface", 0 },
1026 { "OleObjectCache_AddRef", 0 },
1027 { "OleObjectCache_Cache", 0 },
1028 { "OleObjectCache_Release", 0 },
1029 { "OleObject_Release", 0 },
1032 static const struct expected_method methods_olerender_format
[] =
1034 { "OleObject_QueryInterface", 0 },
1035 { "OleObject_AddRef", 0 },
1036 { "OleObject_QueryInterface", 0 },
1037 { "OleObject_AddRef", 0 },
1038 { "OleObject_GetMiscStatus", 0 },
1039 { "OleObject_QueryInterface", 0 },
1040 { "OleObjectPersistStg_AddRef", 0 },
1041 { "OleObjectPersistStg_InitNew", 0 },
1042 { "OleObjectPersistStg_Release", 0 },
1043 { "OleObject_SetClientSite", 0 },
1044 { "OleObject_Release", 0 },
1045 { "OleObject_QueryInterface", 0 },
1046 { "OleObjectRunnable_AddRef", 0 },
1047 { "OleObjectRunnable_Run", 0 },
1048 { "OleObjectRunnable_Release", 0 },
1049 { "OleObject_QueryInterface", 0 },
1050 { "OleObjectCache_AddRef", 0 },
1051 { "OleObjectCache_Cache", 0 },
1052 { "OleObjectCache_Release", 0 },
1053 { "OleObject_Release", 0 },
1056 static const struct expected_method methods_olerender_asis
[] =
1058 { "OleObject_QueryInterface", 0 },
1059 { "OleObject_AddRef", 0 },
1060 { "OleObject_QueryInterface", 0 },
1061 { "OleObject_AddRef", TEST_OPTIONAL
/* NT4 only */ },
1062 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1063 { "OleObject_QueryInterface", TEST_OPTIONAL
/* NT4 only */ },
1064 { "OleObjectPersistStg_AddRef", 0 },
1065 { "OleObjectPersistStg_InitNew", 0 },
1066 { "OleObjectPersistStg_Release", 0 },
1067 { "OleObject_Release", 0 },
1068 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1071 static const struct expected_method methods_olerender_draw_no_runnable
[] =
1073 { "OleObject_QueryInterface", 0 },
1074 { "OleObject_AddRef", 0 },
1075 { "OleObject_QueryInterface", 0 },
1076 { "OleObject_AddRef", TEST_OPTIONAL
/* NT4 only */ },
1077 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1078 { "OleObject_QueryInterface", TEST_OPTIONAL
/* NT4 only */ },
1079 { "OleObjectPersistStg_AddRef", 0 },
1080 { "OleObjectPersistStg_InitNew", 0 },
1081 { "OleObjectPersistStg_Release", 0 },
1082 { "OleObject_QueryInterface", 0 },
1083 { "OleObject_QueryInterface", 0 },
1084 { "OleObjectCache_AddRef", 0 },
1085 { "OleObjectCache_Cache", 0 },
1086 { "OleObjectCache_Release", 0 },
1087 { "OleObject_Release", 0 },
1088 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1091 static const struct expected_method methods_olerender_draw_no_cache
[] =
1093 { "OleObject_QueryInterface", 0 },
1094 { "OleObject_AddRef", 0 },
1095 { "OleObject_QueryInterface", 0 },
1096 { "OleObject_AddRef", TEST_OPTIONAL
/* NT4 only */ },
1097 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1098 { "OleObject_QueryInterface", TEST_OPTIONAL
/* NT4 only */ },
1099 { "OleObjectPersistStg_AddRef", 0 },
1100 { "OleObjectPersistStg_InitNew", 0 },
1101 { "OleObjectPersistStg_Release", 0 },
1102 { "OleObject_QueryInterface", 0 },
1103 { "OleObjectRunnable_AddRef", 0 },
1104 { "OleObjectRunnable_Run", 0 },
1105 { "OleObjectRunnable_Release", 0 },
1106 { "OleObject_QueryInterface", 0 },
1107 { "OleObject_Release", 0 },
1108 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1112 g_expected_fetc
= &formatetc
;
1113 formatetc
.cfFormat
= 0;
1114 formatetc
.ptd
= NULL
;
1115 formatetc
.dwAspect
= DVASPECT_CONTENT
;
1116 formatetc
.lindex
= -1;
1117 formatetc
.tymed
= TYMED_NULL
;
1118 runnable
= &OleObjectRunnable
;
1119 cache
= &OleObjectCache
;
1120 expected_method_list
= methods_olerender_none
;
1121 trace("OleCreate with OLERENDER_NONE:\n");
1122 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_NONE
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1123 ok_ole_success(hr
, "OleCreate");
1124 IOleObject_Release(pObject
);
1125 CHECK_NO_EXTRA_METHODS();
1127 expected_method_list
= methods_olerender_draw
;
1128 trace("OleCreate with OLERENDER_DRAW:\n");
1129 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1130 ok_ole_success(hr
, "OleCreate");
1131 IOleObject_Release(pObject
);
1132 CHECK_NO_EXTRA_METHODS();
1134 expected_method_list
= methods_olerender_draw_with_site
;
1135 trace("OleCreate with OLERENDER_DRAW, with site:\n");
1136 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, (IOleClientSite
*)0xdeadbeef, pStorage
, (void **)&pObject
);
1137 ok_ole_success(hr
, "OleCreate");
1138 IOleObject_Release(pObject
);
1139 CHECK_NO_EXTRA_METHODS();
1141 /* GetMiscStatus fails */
1142 g_GetMiscStatusFailsWith
= 0x8fafefaf;
1143 expected_method_list
= methods_olerender_draw_with_site
;
1144 trace("OleCreate with OLERENDER_DRAW, with site:\n");
1145 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, (IOleClientSite
*)0xdeadbeef, pStorage
, (void **)&pObject
);
1146 ok_ole_success(hr
, "OleCreate");
1147 IOleObject_Release(pObject
);
1148 CHECK_NO_EXTRA_METHODS();
1149 g_GetMiscStatusFailsWith
= S_OK
;
1151 formatetc
.cfFormat
= CF_TEXT
;
1152 formatetc
.ptd
= NULL
;
1153 formatetc
.dwAspect
= DVASPECT_CONTENT
;
1154 formatetc
.lindex
= -1;
1155 formatetc
.tymed
= TYMED_HGLOBAL
;
1156 expected_method_list
= methods_olerender_format
;
1157 trace("OleCreate with OLERENDER_FORMAT:\n");
1158 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_FORMAT
, &formatetc
, (IOleClientSite
*)0xdeadbeef, pStorage
, (void **)&pObject
);
1160 broken(hr
== E_INVALIDARG
), /* win2k */
1161 "OleCreate failed with error 0x%08x\n", hr
);
1164 IOleObject_Release(pObject
);
1165 CHECK_NO_EXTRA_METHODS();
1168 expected_method_list
= methods_olerender_asis
;
1169 trace("OleCreate with OLERENDER_ASIS:\n");
1170 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_ASIS
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1171 ok_ole_success(hr
, "OleCreate");
1172 IOleObject_Release(pObject
);
1173 CHECK_NO_EXTRA_METHODS();
1175 formatetc
.cfFormat
= 0;
1176 formatetc
.tymed
= TYMED_NULL
;
1178 expected_method_list
= methods_olerender_draw_no_runnable
;
1179 trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
1180 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1181 ok_ole_success(hr
, "OleCreate");
1182 IOleObject_Release(pObject
);
1183 CHECK_NO_EXTRA_METHODS();
1185 runnable
= &OleObjectRunnable
;
1187 expected_method_list
= methods_olerender_draw_no_cache
;
1188 trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n");
1189 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1190 ok_ole_success(hr
, "OleCreate");
1191 IOleObject_Release(pObject
);
1192 CHECK_NO_EXTRA_METHODS();
1194 g_expected_fetc
= NULL
;
1197 static void test_OleLoad(IStorage
*pStorage
)
1200 IOleObject
*pObject
;
1203 static const struct expected_method methods_oleload
[] =
1205 { "OleObject_QueryInterface", 0 },
1206 { "OleObject_AddRef", 0 },
1207 { "OleObject_QueryInterface", 0 },
1208 { "OleObject_AddRef", 0 },
1209 { "OleObject_GetMiscStatus", 0 },
1210 { "OleObject_QueryInterface", 0 },
1211 { "OleObjectPersistStg_AddRef", 0 },
1212 { "OleObjectPersistStg_Load", 0 },
1213 { "OleObjectPersistStg_Release", 0 },
1214 { "OleObject_SetClientSite", 0 },
1215 { "OleObject_Release", 0 },
1216 { "OleObject_QueryInterface", 0 },
1217 { "OleObject_GetMiscStatus", 0 },
1218 { "OleObject_Release", 0 },
1222 /* Test once with IOleObject_GetMiscStatus failing */
1223 expected_method_list
= methods_oleload
;
1224 g_GetMiscStatusFailsWith
= E_FAIL
;
1225 trace("OleLoad:\n");
1226 hr
= OleLoad(pStorage
, &IID_IOleObject
, (IOleClientSite
*)0xdeadbeef, (void **)&pObject
);
1228 broken(hr
== E_INVALIDARG
), /* win98 and win2k */
1229 "OleLoad failed with error 0x%08x\n", hr
);
1232 DWORD dwStatus
= 0xdeadbeef;
1233 hr
= IOleObject_GetMiscStatus(pObject
, DVASPECT_CONTENT
, &dwStatus
);
1234 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
1235 ok(dwStatus
== 0x1234, "Got 0x%08x\n", dwStatus
);
1237 IOleObject_Release(pObject
);
1238 CHECK_NO_EXTRA_METHODS();
1240 g_GetMiscStatusFailsWith
= S_OK
;
1242 /* Test again, let IOleObject_GetMiscStatus succeed. */
1243 expected_method_list
= methods_oleload
;
1244 trace("OleLoad:\n");
1245 hr
= OleLoad(pStorage
, &IID_IOleObject
, (IOleClientSite
*)0xdeadbeef, (void **)&pObject
);
1247 broken(hr
== E_INVALIDARG
), /* win98 and win2k */
1248 "OleLoad failed with error 0x%08x\n", hr
);
1251 DWORD dwStatus
= 0xdeadbeef;
1252 hr
= IOleObject_GetMiscStatus(pObject
, DVASPECT_CONTENT
, &dwStatus
);
1253 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1254 ok(dwStatus
== 1, "Got 0x%08x\n", dwStatus
);
1256 IOleObject_Release(pObject
);
1257 CHECK_NO_EXTRA_METHODS();
1260 for (fmt
= CF_TEXT
; fmt
< CF_MAX
; fmt
++)
1262 static const WCHAR olrepres
[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 };
1266 DWORD data
, i
, data_size
;
1267 PresentationDataHeader header
;
1273 for (i
= 0; i
< 7; i
++)
1275 hr
= StgCreateDocfile(NULL
, STGM_READWRITE
| STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &stg
);
1276 ok(hr
== S_OK
, "StgCreateDocfile error %#x\n", hr
);
1278 hr
= IStorage_SetClass(stg
, &CLSID_WineTest
);
1279 ok(hr
== S_OK
, "SetClass error %#x\n", hr
);
1281 hr
= IStorage_CreateStream(stg
, olrepres
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
, 0, 0, &stream
);
1282 ok(hr
== S_OK
, "CreateStream error %#x\n", hr
);
1285 hr
= IStream_Write(stream
, &data
, sizeof(data
), NULL
);
1286 ok(hr
== S_OK
, "Write error %#x\n", hr
);
1289 hr
= IStream_Write(stream
, &data
, sizeof(data
), NULL
);
1290 ok(hr
== S_OK
, "Write error %#x\n", hr
);
1295 /* FIXME: figure out stream format */
1296 hobj
= CreateBitmap(1, 1, 1, 1, NULL
);
1297 data_size
= GetBitmapBits(hobj
, sizeof(buf
), buf
);
1301 case CF_METAFILEPICT
:
1302 case CF_ENHMETAFILE
:
1303 hdc
= CreateMetaFileA(NULL
);
1304 hobj
= CloseMetaFile(hdc
);
1305 data_size
= GetMetaFileBitsEx(hobj
, sizeof(buf
), buf
);
1306 DeleteMetaFile(hobj
);
1310 data_size
= sizeof(buf
);
1311 memset(buf
, 'A', sizeof(buf
));
1315 header
.tdSize
= sizeof(header
.tdSize
);
1316 header
.dvAspect
= DVASPECT_CONTENT
;
1318 header
.advf
= 1 << i
;
1319 header
.unknown7
= 0;
1320 header
.dwObjectExtentX
= 1;
1321 header
.dwObjectExtentY
= 1;
1322 header
.dwSize
= data_size
;
1323 hr
= IStream_Write(stream
, &header
, sizeof(header
), NULL
);
1324 ok(hr
== S_OK
, "Write error %#x\n", hr
);
1326 hr
= IStream_Write(stream
, buf
, data_size
, NULL
);
1327 ok(hr
== S_OK
, "Write error %#x\n", hr
);
1329 IStream_Release(stream
);
1331 hr
= OleLoad(stg
, &IID_IUnknown
, NULL
, (void **)&obj
);
1332 /* FIXME: figure out stream format */
1333 if (fmt
== CF_BITMAP
&& hr
!= S_OK
)
1335 IStorage_Release(stg
);
1338 ok(hr
== S_OK
, "OleLoad error %#x: cfFormat = %u, advf = %#x\n", hr
, fmt
, header
.advf
);
1340 hdc
= CreateCompatibleDC(0);
1341 SetRect(&rc
, 0, 0, 100, 100);
1342 hr
= OleDraw(obj
, DVASPECT_CONTENT
, hdc
, &rc
);
1344 if (fmt
== CF_METAFILEPICT
)
1345 ok(hr
== S_OK
, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr
, fmt
, header
.advf
);
1346 else if (fmt
== CF_ENHMETAFILE
)
1348 ok(hr
== S_OK
, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr
, fmt
, header
.advf
);
1350 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
);
1352 IUnknown_Release(obj
);
1353 IStorage_Release(stg
);
1358 static BOOL STDMETHODCALLTYPE
draw_continue(ULONG_PTR param
)
1360 CHECK_EXPECTED_METHOD("draw_continue");
1364 static BOOL STDMETHODCALLTYPE
draw_continue_false(ULONG_PTR param
)
1366 CHECK_EXPECTED_METHOD("draw_continue_false");
1370 static HRESULT WINAPI
AdviseSink_QueryInterface(IAdviseSink
*iface
, REFIID riid
, void **ppv
)
1372 if (IsEqualIID(riid
, &IID_IAdviseSink
) || IsEqualIID(riid
, &IID_IUnknown
))
1375 IAdviseSink_AddRef(iface
);
1379 return E_NOINTERFACE
;
1382 static ULONG WINAPI
AdviseSink_AddRef(IAdviseSink
*iface
)
1387 static ULONG WINAPI
AdviseSink_Release(IAdviseSink
*iface
)
1393 static void WINAPI
AdviseSink_OnDataChange(
1395 FORMATETC
*pFormatetc
,
1398 CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
1401 static void WINAPI
AdviseSink_OnViewChange(
1406 CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
1409 static void WINAPI
AdviseSink_OnRename(
1413 CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
1416 static void WINAPI
AdviseSink_OnSave(IAdviseSink
*iface
)
1418 CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
1421 static void WINAPI
AdviseSink_OnClose(IAdviseSink
*iface
)
1423 CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
1426 static const IAdviseSinkVtbl AdviseSinkVtbl
=
1428 AdviseSink_QueryInterface
,
1431 AdviseSink_OnDataChange
,
1432 AdviseSink_OnViewChange
,
1433 AdviseSink_OnRename
,
1438 static IAdviseSink AdviseSink
= { &AdviseSinkVtbl
};
1440 static HRESULT WINAPI
DataObject_QueryInterface(
1445 CHECK_EXPECTED_METHOD("DataObject_QueryInterface");
1447 if (IsEqualIID(riid
, &IID_IDataObject
) || IsEqualIID(riid
, &IID_IUnknown
))
1456 static ULONG WINAPI
DataObject_AddRef(
1459 CHECK_EXPECTED_METHOD("DataObject_AddRef");
1463 static ULONG WINAPI
DataObject_Release(
1466 CHECK_EXPECTED_METHOD("DataObject_Release");
1470 static inline BOOL
fmtetc_equal( const FORMATETC
*a
, const FORMATETC
*b
)
1473 return a
->cfFormat
== b
->cfFormat
&& a
->dwAspect
== b
->dwAspect
&&
1474 a
->lindex
== b
->lindex
&& a
->tymed
== b
->tymed
;
1478 static HRESULT WINAPI
DataObject_GetData( IDataObject
*iface
, FORMATETC
*fmt_in
,
1483 CHECK_EXPECTED_METHOD_FMT("DataObject_GetData", fmt_in
);
1485 for (fmt
= g_dataobject_fmts
; fmt
&& fmt
->cfFormat
!= 0; fmt
++)
1487 if (fmtetc_equal( fmt_in
, fmt
))
1489 switch (fmt
->cfFormat
)
1495 create_bitmap( med
);
1498 trace( "unhandled fmt %d\n", fmt
->cfFormat
);
1506 static HRESULT WINAPI
DataObject_GetDataHere(
1508 LPFORMATETC pformatetc
,
1511 CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1515 static HRESULT WINAPI
DataObject_QueryGetData( IDataObject
*iface
, FORMATETC
*fmt_in
)
1519 CHECK_EXPECTED_METHOD_FMT("DataObject_QueryGetData", fmt_in
);
1521 for (fmt
= g_dataobject_fmts
; fmt
&& fmt
->cfFormat
!= 0; fmt
++)
1522 if (fmtetc_equal( fmt_in
, fmt
)) return S_OK
;
1527 static HRESULT WINAPI
DataObject_GetCanonicalFormatEtc(
1529 LPFORMATETC pformatectIn
,
1530 LPFORMATETC pformatetcOut
)
1532 CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1536 static HRESULT WINAPI
DataObject_SetData(
1538 LPFORMATETC pformatetc
,
1542 CHECK_EXPECTED_METHOD("DataObject_SetData");
1546 static HRESULT WINAPI
DataObject_EnumFormatEtc(
1549 IEnumFORMATETC
** ppenumFormatEtc
)
1551 CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1555 static HRESULT WINAPI
DataObject_DAdvise(
1557 FORMATETC
* pformatetc
,
1559 IAdviseSink
* pAdvSink
,
1560 DWORD
* pdwConnection
)
1562 STGMEDIUM stgmedium
;
1564 CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1567 if(advf
& ADVF_PRIMEFIRST
)
1569 ok(pformatetc
->cfFormat
== cf_test_2
, "got %04x\n", pformatetc
->cfFormat
);
1570 stgmedium
.tymed
= TYMED_HGLOBAL
;
1571 U(stgmedium
).hGlobal
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_ZEROINIT
, 4);
1572 stgmedium
.pUnkForRelease
= NULL
;
1573 IAdviseSink_OnDataChange(pAdvSink
, pformatetc
, &stgmedium
);
1579 static HRESULT WINAPI
DataObject_DUnadvise(
1583 CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1587 static HRESULT WINAPI
DataObject_EnumDAdvise(
1589 IEnumSTATDATA
** ppenumAdvise
)
1591 CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1592 return OLE_E_ADVISENOTSUPPORTED
;
1595 static IDataObjectVtbl DataObjectVtbl
=
1597 DataObject_QueryInterface
,
1601 DataObject_GetDataHere
,
1602 DataObject_QueryGetData
,
1603 DataObject_GetCanonicalFormatEtc
,
1605 DataObject_EnumFormatEtc
,
1607 DataObject_DUnadvise
,
1608 DataObject_EnumDAdvise
1611 static IDataObject DataObject
= { &DataObjectVtbl
};
1613 static HRESULT WINAPI
Unknown_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
1616 if (IsEqualIID(riid
, &IID_IUnknown
)) *ppv
= iface
;
1619 IUnknown_AddRef((IUnknown
*)*ppv
);
1622 return E_NOINTERFACE
;
1625 static ULONG WINAPI
Unknown_AddRef(IUnknown
*iface
)
1630 static ULONG WINAPI
Unknown_Release(IUnknown
*iface
)
1635 static const IUnknownVtbl UnknownVtbl
=
1637 Unknown_QueryInterface
,
1642 static IUnknown unknown
= { &UnknownVtbl
};
1644 static void check_enum_cache(IOleCache2
*cache
, const STATDATA
*expect
, int num
)
1646 IEnumSTATDATA
*enum_stat
;
1650 hr
= IOleCache2_EnumCache( cache
, &enum_stat
);
1651 ok( hr
== S_OK
, "got %08x\n", hr
);
1653 while (IEnumSTATDATA_Next(enum_stat
, 1, &stat
, NULL
) == S_OK
)
1655 ok( stat
.formatetc
.cfFormat
== expect
->formatetc
.cfFormat
, "got %d expect %d\n",
1656 stat
.formatetc
.cfFormat
, expect
->formatetc
.cfFormat
);
1657 ok( !stat
.formatetc
.ptd
== !expect
->formatetc
.ptd
, "got %p expect %p\n",
1658 stat
.formatetc
.ptd
, expect
->formatetc
.ptd
);
1659 ok( stat
.formatetc
.dwAspect
== expect
->formatetc
.dwAspect
, "got %d expect %d\n",
1660 stat
.formatetc
.dwAspect
, expect
->formatetc
.dwAspect
);
1661 ok( stat
.formatetc
.lindex
== expect
->formatetc
.lindex
, "got %d expect %d\n",
1662 stat
.formatetc
.lindex
, expect
->formatetc
.lindex
);
1663 ok( stat
.formatetc
.tymed
== expect
->formatetc
.tymed
, "got %d expect %d\n",
1664 stat
.formatetc
.tymed
, expect
->formatetc
.tymed
);
1665 ok( stat
.advf
== expect
->advf
, "got %d expect %d\n", stat
.advf
, expect
->advf
);
1666 ok( stat
.pAdvSink
== 0, "got %p\n", stat
.pAdvSink
);
1667 ok( stat
.dwConnection
== expect
->dwConnection
, "got %d expect %d\n", stat
.dwConnection
, expect
->dwConnection
);
1672 ok( num
== 0, "incorrect number. num %d\n", num
);
1674 IEnumSTATDATA_Release( enum_stat
);
1677 static void test_data_cache(void)
1680 IOleCache2
*pOleCache
;
1681 IOleCache
*olecache
;
1683 IUnknown
*unk
, *unk2
;
1684 IPersistStorage
*pPS
;
1685 IViewObject
*pViewObject
;
1686 IOleCacheControl
*pOleCacheControl
;
1687 IDataObject
*pCacheDataObject
;
1689 STGMEDIUM stgmedium
;
1695 char szSystemDir
[MAX_PATH
];
1696 WCHAR wszPath
[MAX_PATH
];
1697 static const WCHAR wszShell32
[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1699 static const struct expected_method methods_cacheinitnew
[] =
1701 { "AdviseSink_OnViewChange", 0 },
1702 { "AdviseSink_OnViewChange", 0 },
1703 { "draw_continue", 1 },
1704 { "draw_continue_false", 1 },
1705 { "DataObject_DAdvise", 0 },
1706 { "DataObject_DAdvise", 0 },
1707 { "DataObject_DUnadvise", 0 },
1708 { "DataObject_DUnadvise", 0 },
1711 static const struct expected_method methods_cacheload
[] =
1713 { "AdviseSink_OnViewChange", 0 },
1714 { "draw_continue", 1 },
1715 { "draw_continue", 1 },
1716 { "draw_continue", 1 },
1717 { "DataObject_GetData", 0, { CF_DIB
, NULL
, DVASPECT_THUMBNAIL
, -1, TYMED_HGLOBAL
} },
1718 { "DataObject_GetData", 0, { CF_BITMAP
, NULL
, DVASPECT_THUMBNAIL
, -1, TYMED_GDI
} },
1719 { "DataObject_GetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_ICON
, -1, TYMED_MFPICT
} },
1722 static const struct expected_method methods_cachethenrun
[] =
1724 { "DataObject_DAdvise", 0 },
1725 { "DataObject_DAdvise", 0 },
1726 { "DataObject_DAdvise", 0 },
1727 { "DataObject_DAdvise", 0 },
1728 { "DataObject_DUnadvise", 0 },
1729 { "DataObject_DUnadvise", 0 },
1730 { "DataObject_DUnadvise", 0 },
1731 { "DataObject_DUnadvise", 0 },
1735 GetSystemDirectoryA(szSystemDir
, sizeof(szSystemDir
)/sizeof(szSystemDir
[0]));
1737 expected_method_list
= methods_cacheinitnew
;
1739 fmtetc
.cfFormat
= CF_METAFILEPICT
;
1740 fmtetc
.dwAspect
= DVASPECT_ICON
;
1743 fmtetc
.tymed
= TYMED_MFPICT
;
1745 hr
= StgCreateDocfile(NULL
, STGM_READWRITE
| STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &pStorage
);
1746 ok_ole_success(hr
, "StgCreateDocfile");
1750 /* requested is not IUnknown */
1751 hr
= CreateDataCache(&unknown
, &CLSID_NULL
, &IID_IOleCache2
, (void**)&pOleCache
);
1752 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1754 hr
= CreateDataCache(&unknown
, &CLSID_NULL
, &IID_IUnknown
, (void**)&unk
);
1755 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1757 hr
= IUnknown_QueryInterface(unk
, &IID_IOleCache
, (void**)&olecache
);
1758 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1759 hr
= IUnknown_QueryInterface(unk
, &IID_IOleCache2
, (void**)&pOleCache
);
1760 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1761 ok(unk
!= (IUnknown
*)olecache
, "got %p, expected %p\n", olecache
, unk
);
1762 ok(unk
!= (IUnknown
*)pOleCache
, "got %p, expected %p\n", pOleCache
, unk
);
1763 IOleCache2_Release(pOleCache
);
1764 IOleCache_Release(olecache
);
1765 IUnknown_Release(unk
);
1767 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IUnknown
, (void**)&unk
);
1768 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1769 hr
= IUnknown_QueryInterface(unk
, &IID_IOleCache
, (void**)&olecache
);
1770 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1771 hr
= IUnknown_QueryInterface(unk
, &IID_IOleCache2
, (void**)&pOleCache
);
1772 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1773 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, (void**)&unk2
);
1774 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1775 ok(unk
== (IUnknown
*)olecache
, "got %p, expected %p\n", olecache
, unk
);
1776 ok(unk
== (IUnknown
*)pOleCache
, "got %p, expected %p\n", pOleCache
, unk
);
1777 ok(unk
== unk2
, "got %p, expected %p\n", unk2
, unk
);
1778 IUnknown_Release(unk2
);
1779 IOleCache2_Release(pOleCache
);
1780 IOleCache_Release(olecache
);
1781 IUnknown_Release(unk
);
1783 /* Test with new data */
1785 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IOleCache2
, (LPVOID
*)&pOleCache
);
1786 ok_ole_success(hr
, "CreateDataCache");
1788 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IPersistStorage
, (LPVOID
*)&pPS
);
1789 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IPersistStorage)");
1790 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IViewObject
, (LPVOID
*)&pViewObject
);
1791 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IViewObject)");
1792 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IOleCacheControl
, (LPVOID
*)&pOleCacheControl
);
1793 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1795 hr
= IViewObject_SetAdvise(pViewObject
, DVASPECT_ICON
, ADVF_PRIMEFIRST
, &AdviseSink
);
1796 ok_ole_success(hr
, "IViewObject_SetAdvise");
1798 hr
= IPersistStorage_InitNew(pPS
, pStorage
);
1799 ok_ole_success(hr
, "IPersistStorage_InitNew");
1801 hr
= IPersistStorage_IsDirty(pPS
);
1802 ok_ole_success(hr
, "IPersistStorage_IsDirty");
1804 hr
= IPersistStorage_GetClassID(pPS
, &clsid
);
1805 ok_ole_success(hr
, "IPersistStorage_GetClassID");
1806 ok(IsEqualCLSID(&clsid
, &IID_NULL
), "clsid should be blank\n");
1808 hr
= IOleCache2_Uncache(pOleCache
, 0xdeadbeef);
1809 ok(hr
== OLE_E_NOCONNECTION
, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr
);
1811 /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1812 if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
1814 hr
= IOleCache2_Cache(pOleCache
, NULL
, 0, &dwConnection
);
1815 ok(hr
== E_INVALIDARG
, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1817 hr
= IOleCache2_Cache(pOleCache
, NULL
, 0, NULL
);
1818 ok(hr
== E_INVALIDARG
, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1822 skip("tests with NULL parameters will crash on NT4 and below\n");
1825 for (fmtetc
.cfFormat
= CF_TEXT
; fmtetc
.cfFormat
< CF_MAX
; fmtetc
.cfFormat
++)
1828 fmtetc
.dwAspect
= DVASPECT_THUMBNAIL
;
1829 for (i
= 0; i
< 7; i
++)
1831 fmtetc
.tymed
= 1 << i
;
1832 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1833 if ((fmtetc
.cfFormat
== CF_METAFILEPICT
&& fmtetc
.tymed
== TYMED_MFPICT
) ||
1834 (fmtetc
.cfFormat
== CF_BITMAP
&& fmtetc
.tymed
== TYMED_GDI
) ||
1835 (fmtetc
.cfFormat
== CF_DIB
&& fmtetc
.tymed
== TYMED_HGLOBAL
) ||
1836 (fmtetc
.cfFormat
== CF_ENHMETAFILE
&& fmtetc
.tymed
== TYMED_ENHMF
))
1837 ok(hr
== S_OK
, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1838 fmtetc
.cfFormat
, fmtetc
.tymed
, hr
);
1839 else if (fmtetc
.tymed
== TYMED_HGLOBAL
)
1840 ok(hr
== CACHE_S_FORMATETC_NOTSUPPORTED
||
1841 broken(hr
== S_OK
&& fmtetc
.cfFormat
== CF_BITMAP
) /* Win9x & NT4 */,
1842 "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1843 fmtetc
.cfFormat
, fmtetc
.tymed
, hr
);
1845 ok(hr
== DV_E_TYMED
, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1846 fmtetc
.cfFormat
, fmtetc
.tymed
, hr
);
1849 hr
= IOleCache2_Uncache(pOleCache
, dwConnection
);
1850 ok_ole_success(hr
, "IOleCache_Uncache");
1855 fmtetc
.cfFormat
= CF_BITMAP
;
1856 fmtetc
.dwAspect
= DVASPECT_THUMBNAIL
;
1857 fmtetc
.tymed
= TYMED_GDI
;
1858 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1859 ok_ole_success(hr
, "IOleCache_Cache");
1861 fmtetc
.cfFormat
= 0;
1862 fmtetc
.dwAspect
= DVASPECT_ICON
;
1863 fmtetc
.tymed
= TYMED_MFPICT
;
1864 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1865 ok_ole_success(hr
, "IOleCache_Cache");
1867 MultiByteToWideChar(CP_ACP
, 0, szSystemDir
, -1, wszPath
, sizeof(wszPath
)/sizeof(wszPath
[0]));
1868 memcpy(wszPath
+lstrlenW(wszPath
), wszShell32
, sizeof(wszShell32
));
1870 fmtetc
.cfFormat
= CF_METAFILEPICT
;
1871 stgmedium
.tymed
= TYMED_MFPICT
;
1872 U(stgmedium
).hMetaFilePict
= OleMetafilePictFromIconAndLabel(
1873 LoadIconA(NULL
, (LPSTR
)IDI_APPLICATION
), wszPath
, wszPath
, 0);
1874 stgmedium
.pUnkForRelease
= NULL
;
1876 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
1877 hr
= IOleCache2_SetData(pOleCache
, &fmtetc
, &stgmedium
, FALSE
);
1878 ok(hr
== OLE_E_BLANK
, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr
);
1880 fmtetc
.dwAspect
= DVASPECT_ICON
;
1881 hr
= IOleCache2_SetData(pOleCache
, &fmtetc
, &stgmedium
, FALSE
);
1882 ok_ole_success(hr
, "IOleCache_SetData");
1883 ReleaseStgMedium(&stgmedium
);
1885 hr
= IViewObject_Freeze(pViewObject
, DVASPECT_ICON
, -1, NULL
, &dwFreeze
);
1887 ok_ole_success(hr
, "IViewObject_Freeze");
1888 hr
= IViewObject_Freeze(pViewObject
, DVASPECT_CONTENT
, -1, NULL
, &dwFreeze
);
1889 ok(hr
== OLE_E_BLANK
, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr
);
1894 rcBounds
.right
= 100;
1895 rcBounds
.bottom
= 100;
1896 hdcMem
= CreateCompatibleDC(NULL
);
1898 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1899 ok_ole_success(hr
, "IViewObject_Draw");
1901 hr
= IViewObject_Draw(pViewObject
, DVASPECT_CONTENT
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1902 ok(hr
== OLE_E_BLANK
, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr
);
1904 /* a NULL draw_continue fn ptr */
1905 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, NULL
, 0xdeadbeef);
1906 ok_ole_success(hr
, "IViewObject_Draw");
1908 /* draw_continue that returns FALSE to abort drawing */
1909 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue_false
, 0xdeadbeef);
1911 broken(hr
== S_OK
), /* win9x may skip the callbacks */
1912 "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr
);
1916 hr
= IOleCacheControl_OnRun(pOleCacheControl
, &DataObject
);
1917 ok_ole_success(hr
, "IOleCacheControl_OnRun");
1919 hr
= IPersistStorage_Save(pPS
, pStorage
, TRUE
);
1920 ok_ole_success(hr
, "IPersistStorage_Save");
1922 hr
= IPersistStorage_SaveCompleted(pPS
, NULL
);
1923 ok_ole_success(hr
, "IPersistStorage_SaveCompleted");
1925 hr
= IPersistStorage_IsDirty(pPS
);
1926 ok(hr
== S_FALSE
, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr
);
1928 IPersistStorage_Release(pPS
);
1929 IViewObject_Release(pViewObject
);
1930 IOleCache2_Release(pOleCache
);
1931 IOleCacheControl_Release(pOleCacheControl
);
1933 CHECK_NO_EXTRA_METHODS();
1935 /* Test with loaded data */
1936 trace("Testing loaded data with CreateDataCache:\n");
1937 expected_method_list
= methods_cacheload
;
1939 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IOleCache2
, (LPVOID
*)&pOleCache
);
1940 ok_ole_success(hr
, "CreateDataCache");
1942 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IPersistStorage
, (LPVOID
*)&pPS
);
1943 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IPersistStorage)");
1944 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IViewObject
, (LPVOID
*)&pViewObject
);
1945 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IViewObject)");
1947 hr
= IViewObject_SetAdvise(pViewObject
, DVASPECT_ICON
, ADVF_PRIMEFIRST
, &AdviseSink
);
1948 ok_ole_success(hr
, "IViewObject_SetAdvise");
1950 hr
= IPersistStorage_Load(pPS
, pStorage
);
1951 ok_ole_success(hr
, "IPersistStorage_Load");
1953 hr
= IPersistStorage_IsDirty(pPS
);
1954 ok(hr
== S_FALSE
, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr
);
1956 fmtetc
.cfFormat
= 0;
1957 fmtetc
.dwAspect
= DVASPECT_ICON
;
1960 fmtetc
.tymed
= TYMED_MFPICT
;
1961 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1962 ok(hr
== CACHE_S_SAMECACHE
, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr
);
1966 rcBounds
.right
= 100;
1967 rcBounds
.bottom
= 100;
1968 hdcMem
= CreateCompatibleDC(NULL
);
1970 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1971 ok_ole_success(hr
, "IViewObject_Draw");
1973 hr
= IViewObject_Draw(pViewObject
, DVASPECT_CONTENT
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1974 ok(hr
== OLE_E_BLANK
, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr
);
1976 /* unload the cached storage object, causing it to be reloaded */
1977 hr
= IOleCache2_DiscardCache(pOleCache
, DISCARDCACHE_NOSAVE
);
1978 ok_ole_success(hr
, "IOleCache2_DiscardCache");
1979 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1980 ok_ole_success(hr
, "IViewObject_Draw");
1982 /* unload the cached storage object, but don't allow it to be reloaded */
1983 hr
= IPersistStorage_HandsOffStorage(pPS
);
1984 ok_ole_success(hr
, "IPersistStorage_HandsOffStorage");
1985 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1986 ok_ole_success(hr
, "IViewObject_Draw");
1987 hr
= IOleCache2_DiscardCache(pOleCache
, DISCARDCACHE_NOSAVE
);
1988 ok_ole_success(hr
, "IOleCache2_DiscardCache");
1989 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1990 ok(hr
== OLE_E_BLANK
, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr
);
1994 hr
= IOleCache2_InitCache(pOleCache
, &DataObject
);
1995 ok(hr
== CACHE_E_NOCACHE_UPDATED
, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr
);
1997 IPersistStorage_Release(pPS
);
1998 IViewObject_Release(pViewObject
);
1999 IOleCache2_Release(pOleCache
);
2001 CHECK_NO_EXTRA_METHODS();
2003 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IOleCache2
, (LPVOID
*)&pOleCache
);
2004 ok_ole_success(hr
, "CreateDataCache");
2006 expected_method_list
= methods_cachethenrun
;
2008 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IDataObject
, (LPVOID
*)&pCacheDataObject
);
2009 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IDataObject)");
2010 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IOleCacheControl
, (LPVOID
*)&pOleCacheControl
);
2011 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IOleCacheControl)");
2013 fmtetc
.cfFormat
= CF_METAFILEPICT
;
2014 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2015 fmtetc
.tymed
= TYMED_MFPICT
;
2017 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
2018 ok_ole_success(hr
, "IOleCache_Cache");
2020 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
2021 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
2023 fmtetc
.cfFormat
= cf_test_1
;
2024 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2025 fmtetc
.tymed
= TYMED_HGLOBAL
;
2027 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
2028 ok(hr
== CACHE_S_FORMATETC_NOTSUPPORTED
, "got %08x\n", hr
);
2030 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
2031 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
2033 fmtetc
.cfFormat
= cf_test_2
;
2034 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, ADVF_PRIMEFIRST
, &dwConnection
);
2035 ok(hr
== CACHE_S_FORMATETC_NOTSUPPORTED
, "got %08x\n", hr
);
2037 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
2038 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
2040 hr
= IOleCacheControl_OnRun(pOleCacheControl
, &DataObject
);
2041 ok_ole_success(hr
, "IOleCacheControl_OnRun");
2043 fmtetc
.cfFormat
= cf_test_3
;
2044 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
2045 ok(hr
== CACHE_S_FORMATETC_NOTSUPPORTED
, "got %08x\n", hr
);
2047 fmtetc
.cfFormat
= cf_test_1
;
2048 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
2049 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
2051 fmtetc
.cfFormat
= cf_test_2
;
2052 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
2053 ok(hr
== S_OK
, "got %08x\n", hr
);
2054 ReleaseStgMedium(&stgmedium
);
2056 fmtetc
.cfFormat
= cf_test_3
;
2057 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
2058 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
2060 IOleCacheControl_Release(pOleCacheControl
);
2061 IDataObject_Release(pCacheDataObject
);
2062 IOleCache2_Release(pOleCache
);
2064 CHECK_NO_EXTRA_METHODS();
2066 IStorage_Release(pStorage
);
2069 static const WCHAR CONTENTS
[] = {'C','O','N','T','E','N','T','S',0};
2071 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
2072 static BYTE file_dib
[] =
2074 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
2075 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
2076 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
2077 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
2078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
2079 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
2080 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
2081 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2084 static IStorage
*create_storage( int num
)
2091 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg
);
2092 ok( hr
== S_OK
, "got %08x\n", hr
);
2093 hr
= IStorage_SetClass( stg
, &CLSID_Picture_Dib
);
2094 ok( hr
== S_OK
, "got %08x\n", hr
);
2095 hr
= IStorage_CreateStream( stg
, CONTENTS
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
, 0, 0, &stm
);
2096 ok( hr
== S_OK
, "got %08x\n", hr
);
2097 if (num
== 1) /* Set biXPelsPerMeter = 0 */
2102 hr
= IStream_Write( stm
, file_dib
, sizeof(file_dib
), &written
);
2103 ok( hr
== S_OK
, "got %08x\n", hr
);
2104 IStream_Release( stm
);
2108 static void test_data_cache_dib_contents_stream(int num
)
2112 IPersistStorage
*persist
;
2117 FORMATETC fmt
= {CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
};
2122 BITMAPINFOHEADER expect_info
;
2123 STATDATA enum_expect
[] =
2125 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2126 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2129 hr
= CreateDataCache( NULL
, &CLSID_Picture_Metafile
, &IID_IUnknown
, (void **)&unk
);
2130 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2131 hr
= IUnknown_QueryInterface( unk
, &IID_IPersistStorage
, (void **)&persist
);
2132 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2133 hr
= IUnknown_QueryInterface( unk
, &IID_IDataObject
, (void **)&data
);
2134 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2135 hr
= IUnknown_QueryInterface( unk
, &IID_IViewObject2
, (void **)&view
);
2136 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2137 hr
= IUnknown_QueryInterface( unk
, &IID_IOleCache2
, (void **)&cache
);
2138 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2140 stg
= create_storage( num
);
2142 hr
= IPersistStorage_Load( persist
, stg
);
2143 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2144 IStorage_Release( stg
);
2146 hr
= IPersistStorage_GetClassID( persist
, &cls
);
2147 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2148 ok( IsEqualCLSID( &cls
, &CLSID_Picture_Dib
), "class id mismatch\n" );
2150 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2151 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2152 ok( med
.tymed
== TYMED_HGLOBAL
, "got %x\n", med
.tymed
);
2153 ok( GlobalSize( U(med
).hGlobal
) >= sizeof(dib
) - sizeof(BITMAPFILEHEADER
),
2154 "got %lu\n", GlobalSize( U(med
).hGlobal
) );
2155 ptr
= GlobalLock( U(med
).hGlobal
);
2157 expect_info
= *(BITMAPINFOHEADER
*)(file_dib
+ sizeof(BITMAPFILEHEADER
));
2158 if (expect_info
.biXPelsPerMeter
== 0 || expect_info
.biYPelsPerMeter
== 0)
2160 HDC hdc
= GetDC( 0 );
2161 expect_info
.biXPelsPerMeter
= MulDiv( GetDeviceCaps( hdc
, LOGPIXELSX
), 10000, 254 );
2162 expect_info
.biYPelsPerMeter
= MulDiv( GetDeviceCaps( hdc
, LOGPIXELSY
), 10000, 254 );
2163 ReleaseDC( 0, hdc
);
2165 ok( !memcmp( ptr
, &expect_info
, sizeof(expect_info
) ), "mismatch\n" );
2166 ok( !memcmp( ptr
+ sizeof(expect_info
), file_dib
+ sizeof(BITMAPFILEHEADER
) + sizeof(expect_info
),
2167 sizeof(file_dib
) - sizeof(BITMAPFILEHEADER
) - sizeof(expect_info
) ), "mismatch\n" );
2168 GlobalUnlock( U(med
).hGlobal
);
2169 ReleaseStgMedium( &med
);
2171 check_enum_cache( cache
, enum_expect
, 2 );
2173 hr
= IViewObject2_GetExtent( view
, DVASPECT_CONTENT
, -1, NULL
, &sz
);
2174 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2177 ok( sz
.cx
== 1000, "got %d\n", sz
.cx
);
2178 ok( sz
.cy
== 250, "got %d\n", sz
.cy
);
2182 HDC hdc
= GetDC( 0 );
2183 LONG x
= 2 * 2540 / GetDeviceCaps( hdc
, LOGPIXELSX
);
2184 LONG y
= 1 * 2540 / GetDeviceCaps( hdc
, LOGPIXELSY
);
2185 ok( sz
.cx
== x
, "got %d %d\n", sz
.cx
, x
);
2186 ok( sz
.cy
== y
, "got %d %d\n", sz
.cy
, y
);
2188 ReleaseDC( 0, hdc
);
2191 IOleCache2_Release( cache
);
2192 IViewObject2_Release( view
);
2193 IDataObject_Release( data
);
2194 IPersistStorage_Release( persist
);
2195 IUnknown_Release( unk
);
2198 static void check_bitmap_size( HBITMAP h
, int cx
, int cy
)
2202 GetObjectW( h
, sizeof(bm
), &bm
);
2203 ok( bm
.bmWidth
== cx
, "got %d expect %d\n", bm
.bmWidth
, cx
);
2204 ok( bm
.bmHeight
== cy
, "got %d expect %d\n", bm
.bmHeight
, cy
);
2207 static void check_dib_size( HGLOBAL h
, int cx
, int cy
)
2211 info
= GlobalLock( h
);
2212 ok( info
->bmiHeader
.biWidth
== cx
, "got %d expect %d\n", info
->bmiHeader
.biWidth
, cx
);
2213 ok( info
->bmiHeader
.biHeight
== cy
, "got %d expect %d\n", info
->bmiHeader
.biHeight
, cy
);
2217 static void test_data_cache_cache(void)
2227 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 0 },
2228 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 0 },
2229 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 0 },
2230 {{ CF_ENHMETAFILE
, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
}, 0, NULL
, 0 }
2232 STATDATA view_caching
[] =
2234 {{ 0, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
}, 0, NULL
, 0 },
2235 {{ 0, 0, DVASPECT_THUMBNAIL
, -1, TYMED_HGLOBAL
}, 0, NULL
, 0 },
2236 {{ 0, 0, DVASPECT_DOCPRINT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 0 },
2237 {{ CF_METAFILEPICT
, 0, DVASPECT_ICON
, -1, TYMED_MFPICT
}, 0, NULL
, 0 }
2240 hr
= CreateDataCache( NULL
, &CLSID_NULL
, &IID_IOleCache2
, (void **)&cache
);
2241 ok( hr
== S_OK
, "got %08x\n", hr
);
2243 /* create a dib entry which will also create a bitmap entry too */
2244 fmt
.cfFormat
= CF_DIB
;
2246 fmt
.dwAspect
= DVASPECT_CONTENT
;
2248 fmt
.tymed
= TYMED_HGLOBAL
;
2250 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2251 ok( hr
== S_OK
, "got %08x\n", hr
);
2252 ok( conn
== 2, "got %d\n", conn
);
2253 expect
[0].dwConnection
= conn
;
2254 expect
[1].dwConnection
= conn
;
2256 check_enum_cache( cache
, expect
, 2 );
2258 /* now try to add a bitmap */
2259 fmt
.cfFormat
= CF_BITMAP
;
2260 fmt
.tymed
= TYMED_GDI
;
2262 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2263 ok( hr
== CACHE_S_SAMECACHE
, "got %08x\n", hr
);
2266 fmt
.cfFormat
= CF_METAFILEPICT
;
2267 fmt
.tymed
= TYMED_MFPICT
;
2269 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2270 ok( hr
== S_OK
, "got %08x\n", hr
);
2271 ok( conn
== 3, "got %d\n", conn
);
2272 expect
[2].dwConnection
= conn
;
2274 check_enum_cache( cache
, expect
, 3);
2277 fmt
.cfFormat
= CF_ENHMETAFILE
;
2278 fmt
.tymed
= TYMED_ENHMF
;
2280 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2281 ok( hr
== S_OK
, "got %08x\n", hr
);
2282 ok( conn
== 4, "got %d\n", conn
);
2283 expect
[3].dwConnection
= conn
;
2285 check_enum_cache( cache
, expect
, 4 );
2287 /* uncache everything */
2288 hr
= IOleCache2_Uncache( cache
, expect
[3].dwConnection
);
2289 ok( hr
== S_OK
, "got %08x\n", hr
);
2290 hr
= IOleCache2_Uncache( cache
, expect
[2].dwConnection
);
2291 ok( hr
== S_OK
, "got %08x\n", hr
);
2292 hr
= IOleCache2_Uncache( cache
, expect
[0].dwConnection
);
2293 ok( hr
== S_OK
, "got %08x\n", hr
);
2294 hr
= IOleCache2_Uncache( cache
, expect
[0].dwConnection
);
2295 ok( hr
== OLE_E_NOCONNECTION
, "got %08x\n", hr
);
2297 check_enum_cache( cache
, expect
, 0 );
2299 /* just create a bitmap entry which again adds both dib and bitmap */
2300 fmt
.cfFormat
= CF_BITMAP
;
2301 fmt
.tymed
= TYMED_GDI
;
2303 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2304 ok( hr
== S_OK
, "got %08x\n", hr
);
2306 expect
[0].dwConnection
= conn
;
2307 expect
[1].dwConnection
= conn
;
2309 check_enum_cache( cache
, expect
, 2 );
2311 /* Try setting a 1x1 bitmap */
2312 hr
= IOleCache2_QueryInterface( cache
, &IID_IDataObject
, (void **) &data
);
2313 ok( hr
== S_OK
, "got %08x\n", hr
);
2315 create_bitmap( &med
);
2317 hr
= IOleCache2_SetData( cache
, &fmt
, &med
, TRUE
);
2318 ok( hr
== S_OK
, "got %08x\n", hr
);
2320 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2321 ok( hr
== S_OK
, "got %08x\n", hr
);
2322 ok( med
.tymed
== TYMED_GDI
, "got %d\n", med
.tymed
);
2323 check_bitmap_size( U(med
).hBitmap
, 1, 1 );
2324 ReleaseStgMedium( &med
);
2326 fmt
.cfFormat
= CF_DIB
;
2327 fmt
.tymed
= TYMED_HGLOBAL
;
2328 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2329 ok( hr
== S_OK
, "got %08x\n", hr
);
2330 ok( med
.tymed
== TYMED_HGLOBAL
, "got %d\n", med
.tymed
);
2331 check_dib_size( U(med
).hGlobal
, 1, 1 );
2332 ReleaseStgMedium( &med
);
2334 /* Now set a 2x1 dib */
2335 fmt
.cfFormat
= CF_DIB
;
2336 fmt
.tymed
= TYMED_HGLOBAL
;
2339 hr
= IOleCache2_SetData( cache
, &fmt
, &med
, TRUE
);
2340 ok( hr
== S_OK
, "got %08x\n", hr
);
2342 fmt
.cfFormat
= CF_BITMAP
;
2343 fmt
.tymed
= TYMED_GDI
;
2344 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2345 ok( hr
== S_OK
, "got %08x\n", hr
);
2346 ok( med
.tymed
== TYMED_GDI
, "got %d\n", med
.tymed
);
2347 check_bitmap_size( U(med
).hBitmap
, 2, 1 );
2348 ReleaseStgMedium( &med
);
2350 fmt
.cfFormat
= CF_DIB
;
2351 fmt
.tymed
= TYMED_HGLOBAL
;
2352 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2353 ok( hr
== S_OK
, "got %08x\n", hr
);
2354 ok( med
.tymed
== TYMED_HGLOBAL
, "got %d\n", med
.tymed
);
2355 check_dib_size( U(med
).hGlobal
, 2, 1 );
2356 ReleaseStgMedium( &med
);
2358 /* uncache everything */
2359 hr
= IOleCache2_Uncache( cache
, conn
);
2360 ok( hr
== S_OK
, "got %08x\n", hr
);
2364 fmt
.tymed
= TYMED_ENHMF
;
2365 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2366 ok( hr
== S_OK
, "got %08x\n", hr
);
2367 view_caching
[0].dwConnection
= conn
;
2369 fmt
.tymed
= TYMED_HGLOBAL
;
2370 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2371 ok( hr
== CACHE_S_SAMECACHE
, "got %08x\n", hr
);
2373 fmt
.dwAspect
= DVASPECT_THUMBNAIL
;
2374 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2375 ok( hr
== S_OK
, "got %08x\n", hr
);
2376 view_caching
[1].dwConnection
= conn
;
2378 fmt
.dwAspect
= DVASPECT_DOCPRINT
;
2379 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2380 ok( hr
== S_OK
, "got %08x\n", hr
);
2381 view_caching
[2].dwConnection
= conn
;
2383 /* DVASPECT_ICON view cache gets mapped to CF_METAFILEPICT */
2384 fmt
.dwAspect
= DVASPECT_ICON
;
2385 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2386 ok( hr
== S_OK
, "got %08x\n", hr
);
2387 view_caching
[3].dwConnection
= conn
;
2389 check_enum_cache( cache
, view_caching
, 4 );
2391 /* uncache everything */
2392 hr
= IOleCache2_Uncache( cache
, view_caching
[3].dwConnection
);
2393 ok( hr
== S_OK
, "got %08x\n", hr
);
2394 hr
= IOleCache2_Uncache( cache
, view_caching
[2].dwConnection
);
2395 ok( hr
== S_OK
, "got %08x\n", hr
);
2396 hr
= IOleCache2_Uncache( cache
, view_caching
[1].dwConnection
);
2397 ok( hr
== S_OK
, "got %08x\n", hr
);
2398 hr
= IOleCache2_Uncache( cache
, view_caching
[0].dwConnection
);
2399 ok( hr
== S_OK
, "got %08x\n", hr
);
2401 /* Only able to set cfFormat == CF_METAFILEPICT (or == 0, see above) for DVASPECT_ICON */
2402 fmt
.dwAspect
= DVASPECT_ICON
;
2403 fmt
.cfFormat
= CF_DIB
;
2404 fmt
.tymed
= TYMED_HGLOBAL
;
2405 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2406 ok( hr
== DV_E_FORMATETC
, "got %08x\n", hr
);
2407 fmt
.cfFormat
= CF_BITMAP
;
2408 fmt
.tymed
= TYMED_GDI
;
2409 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2410 ok( hr
== DV_E_FORMATETC
, "got %08x\n", hr
);
2411 fmt
.cfFormat
= CF_ENHMETAFILE
;
2412 fmt
.tymed
= TYMED_ENHMF
;
2413 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2414 ok( hr
== DV_E_FORMATETC
, "got %08x\n", hr
);
2415 fmt
.cfFormat
= CF_METAFILEPICT
;
2416 fmt
.tymed
= TYMED_MFPICT
;
2417 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2418 ok( hr
== S_OK
, "got %08x\n", hr
);
2420 /* uncache everything */
2421 hr
= IOleCache2_Uncache( cache
, conn
);
2422 ok( hr
== S_OK
, "got %08x\n", hr
);
2425 fmt
.cfFormat
= CF_ENHMETAFILE
;
2426 fmt
.dwAspect
= DVASPECT_CONTENT
;
2428 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2429 ok( hr
== DV_E_TYMED
, "got %08x\n", hr
);
2431 IDataObject_Release( data
);
2432 IOleCache2_Release( cache
);
2434 /* tests for a static class cache */
2435 hr
= CreateDataCache( NULL
, &CLSID_Picture_Dib
, &IID_IOleCache2
, (void **)&cache
);
2437 fmt
.cfFormat
= CF_DIB
;
2438 fmt
.dwAspect
= DVASPECT_CONTENT
;
2439 fmt
.tymed
= TYMED_HGLOBAL
;
2440 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2441 ok( hr
== CACHE_S_SAMECACHE
, "got %08x\n", hr
);
2443 /* aspect other than DVASPECT_CONTENT should fail */
2444 fmt
.dwAspect
= DVASPECT_THUMBNAIL
;
2445 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2446 ok( FAILED(hr
), "got %08x\n", hr
);
2448 fmt
.dwAspect
= DVASPECT_DOCPRINT
;
2449 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2450 ok( FAILED(hr
), "got %08x\n", hr
);
2452 /* try caching another clip format */
2453 fmt
.cfFormat
= CF_METAFILEPICT
;
2454 fmt
.dwAspect
= DVASPECT_CONTENT
;
2455 fmt
.tymed
= TYMED_MFPICT
;
2456 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2457 ok( FAILED(hr
), "got %08x\n", hr
);
2459 /* As an exception, it's possible to add an icon aspect */
2460 fmt
.cfFormat
= CF_METAFILEPICT
;
2461 fmt
.dwAspect
= DVASPECT_ICON
;
2462 fmt
.tymed
= TYMED_MFPICT
;
2463 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2464 ok( hr
== S_OK
, "got %08x\n", hr
);
2466 IOleCache2_Release( cache
);
2469 /* The CLSID_Picture_ classes automatically create appropriate cache entries */
2470 static void test_data_cache_init(void)
2474 IPersistStorage
*persist
;
2477 static const STATDATA enum_expect
[] =
2479 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2480 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2481 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 1 },
2482 {{ CF_ENHMETAFILE
, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
}, 0, NULL
, 1 }
2487 int enum_start
, enum_num
;
2490 { &CLSID_NULL
, 0, 0 },
2491 { &CLSID_WineTestOld
, 0, 0 },
2492 { &CLSID_Picture_Dib
, 0, 2 },
2493 { &CLSID_Picture_Metafile
, 2, 1 },
2494 { &CLSID_Picture_EnhMetafile
, 3, 1 }
2497 for (i
= 0; i
< sizeof(data
) / sizeof(data
[0]); i
++)
2499 hr
= CreateDataCache( NULL
, data
[i
].clsid
, &IID_IOleCache2
, (void **)&cache
);
2500 ok( hr
== S_OK
, "got %08x\n", hr
);
2502 check_enum_cache( cache
, enum_expect
+ data
[i
].enum_start
, data
[i
].enum_num
);
2504 IOleCache2_QueryInterface( cache
, &IID_IPersistStorage
, (void **) &persist
);
2505 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2506 ok( hr
== S_OK
, "got %08x\n", hr
);
2507 ok( IsEqualCLSID( &clsid
, data
[i
].clsid
), "class id mismatch %s %s\n", wine_dbgstr_guid( &clsid
),
2508 wine_dbgstr_guid( data
[i
].clsid
) );
2510 IPersistStorage_Release( persist
);
2511 IOleCache2_Release( cache
);
2515 static void test_data_cache_initnew(void)
2519 IPersistStorage
*persist
;
2520 IStorage
*stg_dib
, *stg_mf
, *stg_wine
;
2522 static const STATDATA initnew_expect
[] =
2524 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2525 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2527 static const STATDATA initnew2_expect
[] =
2529 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 1 },
2530 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 2 },
2531 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 2 },
2533 static const STATDATA initnew3_expect
[] =
2535 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2536 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2537 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 2 },
2538 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 2 },
2539 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 3 },
2541 static const STATDATA initnew4_expect
[] =
2543 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 2 },
2544 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 2 },
2545 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 3 },
2546 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 4 },
2547 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 4 },
2550 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg_dib
);
2551 ok( hr
== S_OK
, "got %08x\n", hr
);
2552 hr
= IStorage_SetClass( stg_dib
, &CLSID_Picture_Dib
);
2553 ok( hr
== S_OK
, "got %08x\n", hr
);
2555 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg_mf
);
2556 ok( hr
== S_OK
, "got %08x\n", hr
);
2557 hr
= IStorage_SetClass( stg_mf
, &CLSID_Picture_Metafile
);
2558 ok( hr
== S_OK
, "got %08x\n", hr
);
2560 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg_wine
);
2561 ok( hr
== S_OK
, "got %08x\n", hr
);
2562 hr
= IStorage_SetClass( stg_wine
, &CLSID_WineTestOld
);
2563 ok( hr
== S_OK
, "got %08x\n", hr
);
2565 hr
= CreateDataCache( NULL
, &CLSID_WineTestOld
, &IID_IOleCache2
, (void **)&cache
);
2566 ok( hr
== S_OK
, "got %08x\n", hr
);
2567 IOleCache2_QueryInterface( cache
, &IID_IPersistStorage
, (void **) &persist
);
2569 hr
= IPersistStorage_InitNew( persist
, stg_dib
);
2570 ok( hr
== S_OK
, "got %08x\n", hr
);
2572 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2573 ok( hr
== S_OK
, "got %08x\n", hr
);
2574 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Dib
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2576 check_enum_cache( cache
, initnew_expect
, 2 );
2578 hr
= IPersistStorage_InitNew( persist
, stg_mf
);
2579 ok( hr
== CO_E_ALREADYINITIALIZED
, "got %08x\n", hr
);
2581 hr
= IPersistStorage_HandsOffStorage( persist
);
2582 ok( hr
== S_OK
, "got %08x\n", hr
);
2584 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2585 ok( hr
== S_OK
, "got %08x\n", hr
);
2586 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Dib
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2588 hr
= IPersistStorage_InitNew( persist
, stg_mf
);
2589 ok( hr
== S_OK
, "got %08x\n", hr
);
2591 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2592 ok( hr
== S_OK
, "got %08x\n", hr
);
2593 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Metafile
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2595 check_enum_cache( cache
, initnew2_expect
, 3 );
2597 hr
= IPersistStorage_HandsOffStorage( persist
);
2598 ok( hr
== S_OK
, "got %08x\n", hr
);
2600 hr
= IPersistStorage_InitNew( persist
, stg_dib
);
2601 ok( hr
== S_OK
, "got %08x\n", hr
);
2603 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2604 ok( hr
== S_OK
, "got %08x\n", hr
);
2605 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Dib
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2607 check_enum_cache( cache
, initnew3_expect
, 5 );
2609 hr
= IPersistStorage_HandsOffStorage( persist
);
2610 ok( hr
== S_OK
, "got %08x\n", hr
);
2612 hr
= IPersistStorage_InitNew( persist
, stg_wine
);
2613 ok( hr
== S_OK
, "got %08x\n", hr
);
2615 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2616 ok( hr
== S_OK
, "got %08x\n", hr
);
2617 ok( IsEqualCLSID( &clsid
, &CLSID_WineTestOld
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2619 check_enum_cache( cache
, initnew4_expect
, 5 );
2621 IStorage_Release( stg_wine
);
2622 IStorage_Release( stg_mf
);
2623 IStorage_Release( stg_dib
);
2625 IPersistStorage_Release( persist
);
2626 IOleCache2_Release( cache
);
2629 static void test_data_cache_updatecache( void )
2636 static const struct expected_method methods_dib
[] =
2638 { "DataObject_GetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2639 { "DataObject_GetData", 0, { CF_BITMAP
, NULL
, DVASPECT_CONTENT
, -1, TYMED_GDI
} },
2643 static const struct expected_method methods_dib_emf
[] =
2645 { "DataObject_GetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2646 { "DataObject_GetData", 0, { CF_ENHMETAFILE
, NULL
, DVASPECT_CONTENT
, -1, TYMED_ENHMF
} },
2647 { "DataObject_GetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_MFPICT
} },
2650 static const struct expected_method methods_dib_wmf
[] =
2652 { "DataObject_GetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2653 { "DataObject_GetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_MFPICT
} },
2656 static const struct expected_method methods_viewcache
[] =
2658 { "DataObject_QueryGetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_MFPICT
} },
2659 { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE
, NULL
, DVASPECT_CONTENT
, -1, TYMED_ENHMF
} },
2660 { "DataObject_QueryGetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2661 { "DataObject_QueryGetData", 0, { CF_BITMAP
, NULL
, DVASPECT_CONTENT
, -1, TYMED_GDI
} },
2664 static const struct expected_method methods_viewcache_with_dib
[] =
2666 { "DataObject_QueryGetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_MFPICT
} },
2667 { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE
, NULL
, DVASPECT_CONTENT
, -1, TYMED_ENHMF
} },
2668 { "DataObject_QueryGetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2669 { "DataObject_GetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2672 static const struct expected_method methods_flags_all
[] =
2674 { "DataObject_GetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2675 { "DataObject_GetData", 0, { CF_ENHMETAFILE
, NULL
, DVASPECT_CONTENT
, -1, TYMED_ENHMF
} },
2676 { "DataObject_GetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_MFPICT
} },
2677 { "DataObject_GetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_MFPICT
} },
2680 static const struct expected_method methods_flags_ifblank_1
[] =
2682 { "DataObject_GetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_MFPICT
} },
2685 static const struct expected_method methods_flags_ifblank_2
[] =
2687 { "DataObject_GetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2688 { "DataObject_GetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_MFPICT
} },
2691 static const struct expected_method methods_flags_normal
[] =
2693 { "DataObject_GetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2696 static const struct expected_method methods_initcache
[] =
2698 { "DataObject_GetData", 0, { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
} },
2699 { "DataObject_GetData", 0, { CF_METAFILEPICT
, NULL
, DVASPECT_CONTENT
, -1, TYMED_MFPICT
} },
2702 static const struct expected_method methods_empty
[] =
2707 static STATDATA view_cache
[] =
2709 {{ 0, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 0 }
2711 static STATDATA view_cache_after_dib
[] =
2713 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 0 },
2714 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 0 }
2717 static FORMATETC dib_fmt
[] =
2719 { CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
},
2723 hr
= CreateDataCache( NULL
, &CLSID_WineTestOld
, &IID_IOleCache2
, (void **)&cache
);
2724 ok( hr
== S_OK
, "got %08x\n", hr
);
2726 /* No cache slots */
2727 g_dataobject_fmts
= NULL
;
2728 expected_method_list
= NULL
;
2730 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ALL
, NULL
);
2731 ok( hr
== S_OK
, "got %08x\n", hr
);
2733 /* A dib cache slot */
2734 fmt
.cfFormat
= CF_DIB
;
2736 fmt
.dwAspect
= DVASPECT_CONTENT
;
2738 fmt
.tymed
= TYMED_HGLOBAL
;
2740 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
[0] );
2741 ok( hr
== S_OK
, "got %08x\n", hr
);
2743 expected_method_list
= methods_dib
;
2745 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ALL
, NULL
);
2746 ok( hr
== CACHE_E_NOCACHE_UPDATED
, "got %08x\n", hr
);
2748 CHECK_NO_EXTRA_METHODS();
2750 /* Now with a dib available */
2751 g_dataobject_fmts
= dib_fmt
;
2752 expected_method_list
= methods_dib
;
2754 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ALL
, NULL
);
2755 ok( hr
== S_OK
, "got %08x\n", hr
);
2757 /* Add an EMF cache slot */
2758 fmt
.cfFormat
= CF_ENHMETAFILE
;
2760 fmt
.dwAspect
= DVASPECT_CONTENT
;
2762 fmt
.tymed
= TYMED_ENHMF
;
2764 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
[1] );
2765 ok( hr
== S_OK
, "got %08x\n", hr
);
2767 g_dataobject_fmts
= dib_fmt
;
2768 expected_method_list
= methods_dib_emf
;
2770 /* Two slots to fill, only the dib will succeed */
2771 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ALL
, NULL
);
2772 ok( hr
== S_OK
, "got %08x\n", hr
);
2774 CHECK_NO_EXTRA_METHODS();
2776 /* Replace the emf slot with a wmf */
2777 hr
= IOleCache2_Uncache( cache
, conn
[1] );
2778 ok( hr
== S_OK
, "got %08x\n", hr
);
2780 fmt
.cfFormat
= CF_METAFILEPICT
;
2782 fmt
.dwAspect
= DVASPECT_CONTENT
;
2784 fmt
.tymed
= TYMED_MFPICT
;
2786 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
[1] );
2787 ok( hr
== S_OK
, "got %08x\n", hr
);
2789 g_dataobject_fmts
= dib_fmt
;
2790 expected_method_list
= methods_dib_wmf
;
2792 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ALL
, NULL
);
2793 ok( hr
== S_OK
, "got %08x\n", hr
);
2795 hr
= IOleCache2_Uncache( cache
, conn
[1] );
2796 ok( hr
== S_OK
, "got %08x\n", hr
);
2797 hr
= IOleCache2_Uncache( cache
, conn
[0] );
2798 ok( hr
== S_OK
, "got %08x\n", hr
);
2803 fmt
.dwAspect
= DVASPECT_CONTENT
;
2805 fmt
.tymed
= TYMED_HGLOBAL
;
2807 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
[0] );
2808 ok( hr
== S_OK
, "got %08x\n", hr
);
2809 view_cache
[0].dwConnection
= conn
[0];
2811 g_dataobject_fmts
= NULL
;
2812 expected_method_list
= methods_viewcache
;
2814 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ALL
, NULL
);
2815 ok( hr
== CACHE_E_NOCACHE_UPDATED
, "got %08x\n", hr
);
2817 CHECK_NO_EXTRA_METHODS();
2818 check_enum_cache( cache
, view_cache
, 1 );
2820 g_dataobject_fmts
= dib_fmt
;
2821 expected_method_list
= methods_viewcache_with_dib
;
2823 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ALL
, NULL
);
2824 ok( hr
== S_OK
, "got %08x\n", hr
);
2826 CHECK_NO_EXTRA_METHODS();
2827 view_cache_after_dib
[0].dwConnection
= view_cache_after_dib
[1].dwConnection
= view_cache
[0].dwConnection
;
2828 check_enum_cache( cache
, view_cache_after_dib
, 2 );
2830 hr
= IOleCache2_Uncache( cache
, conn
[0] );
2831 ok( hr
== S_OK
, "got %08x\n", hr
);
2833 /* Try some different flags */
2835 fmt
.cfFormat
= CF_DIB
;
2837 fmt
.dwAspect
= DVASPECT_CONTENT
;
2839 fmt
.tymed
= TYMED_HGLOBAL
;
2841 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
[0] );
2842 ok( hr
== S_OK
, "got %08x\n", hr
);
2844 fmt
.cfFormat
= CF_ENHMETAFILE
;
2846 fmt
.dwAspect
= DVASPECT_CONTENT
;
2848 fmt
.tymed
= TYMED_ENHMF
;
2850 hr
= IOleCache2_Cache( cache
, &fmt
, ADVF_NODATA
, &conn
[1] );
2851 ok( hr
== S_OK
, "got %08x\n", hr
);
2853 fmt
.cfFormat
= CF_METAFILEPICT
;
2855 fmt
.dwAspect
= DVASPECT_CONTENT
;
2857 fmt
.tymed
= TYMED_MFPICT
;
2859 hr
= IOleCache2_Cache( cache
, &fmt
, ADVFCACHE_ONSAVE
, &conn
[2] );
2860 ok( hr
== S_OK
, "got %08x\n", hr
);
2862 g_dataobject_fmts
= dib_fmt
;
2863 expected_method_list
= methods_flags_all
;
2865 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ALL
, NULL
);
2867 CHECK_NO_EXTRA_METHODS();
2869 expected_method_list
= methods_flags_all
;
2871 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ALL
, NULL
);
2872 ok( hr
== S_OK
, "got %08x\n", hr
);
2874 CHECK_NO_EXTRA_METHODS();
2876 expected_method_list
= methods_flags_ifblank_1
;
2878 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_IFBLANK
, NULL
);
2879 ok( hr
== S_OK
, "got %08x\n", hr
);
2881 CHECK_NO_EXTRA_METHODS();
2883 hr
= IOleCache2_DiscardCache( cache
, DISCARDCACHE_NOSAVE
);
2884 ok( hr
== S_OK
, "got %08x\n", hr
);
2886 expected_method_list
= methods_flags_ifblank_2
;
2888 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_IFBLANK
, NULL
);
2889 ok( hr
== S_OK
, "got %08x\n", hr
);
2891 CHECK_NO_EXTRA_METHODS();
2893 hr
= IOleCache2_DiscardCache( cache
, DISCARDCACHE_NOSAVE
);
2894 ok( hr
== S_OK
, "got %08x\n", hr
);
2896 expected_method_list
= methods_flags_all
;
2898 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_IFBLANK
| UPDFCACHE_NODATACACHE
, NULL
);
2899 ok( hr
== S_OK
, "got %08x\n", hr
);
2901 CHECK_NO_EXTRA_METHODS();
2903 expected_method_list
= methods_empty
;
2905 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ONLYIFBLANK
| UPDFCACHE_NORMALCACHE
, NULL
);
2906 ok( hr
== S_OK
, "got %08x\n", hr
);
2908 CHECK_NO_EXTRA_METHODS();
2910 hr
= IOleCache2_DiscardCache( cache
, DISCARDCACHE_NOSAVE
);
2911 ok( hr
== S_OK
, "got %08x\n", hr
);
2913 expected_method_list
= methods_flags_normal
;
2915 hr
= IOleCache2_UpdateCache( cache
, &DataObject
, UPDFCACHE_ONLYIFBLANK
| UPDFCACHE_NORMALCACHE
, NULL
);
2916 ok( hr
== S_OK
, "got %08x\n", hr
);
2918 CHECK_NO_EXTRA_METHODS();
2920 expected_method_list
= methods_initcache
;
2922 hr
= IOleCache2_InitCache( cache
, &DataObject
);
2923 ok( hr
== S_OK
, "got %08x\n", hr
);
2925 CHECK_NO_EXTRA_METHODS();
2927 IOleCache2_Release( cache
);
2930 static void test_default_handler(void)
2933 IOleObject
*pObject
;
2934 IRunnableObject
*pRunnableObject
;
2935 IOleClientSite
*pClientSite
;
2936 IDataObject
*pDataObject
;
2940 LPOLESTR pszUserType
;
2945 IOleInPlaceObject
*pInPlaceObj
;
2946 IEnumOLEVERB
*pEnumVerbs
;
2948 static const WCHAR wszUnknown
[] = {'U','n','k','n','o','w','n',0};
2949 static const WCHAR wszHostName
[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
2950 static const WCHAR wszDelim
[] = {'!',0};
2952 static const struct expected_method methods_embeddinghelper
[] =
2954 { "OleObject_QueryInterface", 0 },
2955 { "OleObject_AddRef", 0 },
2956 { "OleObject_QueryInterface", 0 },
2957 { "OleObject_QueryInterface", TEST_TODO
},
2958 { "OleObject_QueryInterface", 0 },
2959 { "OleObject_QueryInterface", 0 },
2960 { "OleObject_QueryInterface", TEST_OPTIONAL
}, /* Win95/98/NT4 */
2961 { "OleObject_Release", TEST_TODO
},
2962 { "WINE_EXTRA", TEST_OPTIONAL
},
2966 hr
= CoCreateInstance(&CLSID_WineTest
, NULL
, CLSCTX_INPROC_HANDLER
, &IID_IOleObject
, (void **)&pObject
);
2967 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2969 hr
= OleCreateDefaultHandler(&CLSID_WineTest
, NULL
, &IID_IOleObject
, (void **)&pObject
);
2970 ok_ole_success(hr
, "OleCreateDefaultHandler");
2972 hr
= IOleObject_QueryInterface(pObject
, &IID_IOleInPlaceObject
, (void **)&pInPlaceObj
);
2973 ok(hr
== E_NOINTERFACE
, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr
);
2975 hr
= IOleObject_Advise(pObject
, &AdviseSink
, &dwAdvConn
);
2976 ok_ole_success(hr
, "IOleObject_Advise");
2978 hr
= IOleObject_Close(pObject
, OLECLOSE_NOSAVE
);
2979 ok_ole_success(hr
, "IOleObject_Close");
2981 /* FIXME: test IOleObject_EnumAdvise */
2983 hr
= IOleObject_EnumVerbs(pObject
, &pEnumVerbs
);
2984 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2986 hr
= IOleObject_GetClientSite(pObject
, &pClientSite
);
2987 ok_ole_success(hr
, "IOleObject_GetClientSite");
2989 hr
= IOleObject_SetClientSite(pObject
, pClientSite
);
2990 ok_ole_success(hr
, "IOleObject_SetClientSite");
2992 hr
= IOleObject_GetClipboardData(pObject
, 0, &pDataObject
);
2993 ok(hr
== OLE_E_NOTRUNNING
,
2994 "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
2997 hr
= IOleObject_GetExtent(pObject
, DVASPECT_CONTENT
, &sizel
);
2998 ok(hr
== OLE_E_BLANK
, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
3001 hr
= IOleObject_GetMiscStatus(pObject
, DVASPECT_CONTENT
, &dwStatus
);
3002 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
3004 hr
= IOleObject_GetUserClassID(pObject
, &clsid
);
3005 ok_ole_success(hr
, "IOleObject_GetUserClassID");
3006 ok(IsEqualCLSID(&clsid
, &CLSID_WineTest
), "clsid != CLSID_WineTest\n");
3008 hr
= IOleObject_GetUserType(pObject
, USERCLASSTYPE_FULL
, &pszUserType
);
3010 ok_ole_success(hr
, "IOleObject_GetUserType");
3011 ok(!lstrcmpW(pszUserType
, wszUnknown
), "Retrieved user type was wrong\n");
3014 hr
= IOleObject_InitFromData(pObject
, NULL
, TRUE
, 0);
3015 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
3017 hr
= IOleObject_IsUpToDate(pObject
);
3018 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
3020 palette
.palNumEntries
= 1;
3021 palette
.palVersion
= 2;
3022 memset(&palette
.palPalEntry
[0], 0, sizeof(palette
.palPalEntry
[0]));
3023 hr
= IOleObject_SetColorScheme(pObject
, &palette
);
3024 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
3026 sizel
.cx
= sizel
.cy
= 0;
3027 hr
= IOleObject_SetExtent(pObject
, DVASPECT_CONTENT
, &sizel
);
3028 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
3030 hr
= IOleObject_SetHostNames(pObject
, wszHostName
, NULL
);
3031 ok_ole_success(hr
, "IOleObject_SetHostNames");
3033 hr
= CreateItemMoniker(wszDelim
, wszHostName
, &pMoniker
);
3034 ok_ole_success(hr
, "CreateItemMoniker");
3035 hr
= IOleObject_SetMoniker(pObject
, OLEWHICHMK_CONTAINER
, pMoniker
);
3036 ok_ole_success(hr
, "IOleObject_SetMoniker");
3037 IMoniker_Release(pMoniker
);
3039 hr
= IOleObject_GetMoniker(pObject
, OLEGETMONIKER_ONLYIFTHERE
, OLEWHICHMK_CONTAINER
, &pMoniker
);
3040 ok(hr
== E_FAIL
, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr
);
3042 hr
= IOleObject_Update(pObject
);
3044 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
3046 hr
= IOleObject_QueryInterface(pObject
, &IID_IDataObject
, (void **)&pDataObject
);
3047 ok_ole_success(hr
, "IOleObject_QueryInterface");
3049 fmtetc
.cfFormat
= CF_TEXT
;
3051 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
3053 fmtetc
.tymed
= TYMED_NULL
;
3054 hr
= IDataObject_DAdvise(pDataObject
, &fmtetc
, 0, &AdviseSink
, &dwAdvConn
);
3055 ok_ole_success(hr
, "IDataObject_DAdvise");
3057 fmtetc
.cfFormat
= CF_ENHMETAFILE
;
3059 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
3061 fmtetc
.tymed
= TYMED_ENHMF
;
3062 hr
= IDataObject_DAdvise(pDataObject
, &fmtetc
, 0, &AdviseSink
, &dwAdvConn
);
3063 ok_ole_success(hr
, "IDataObject_DAdvise");
3065 fmtetc
.cfFormat
= CF_ENHMETAFILE
;
3067 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
3069 fmtetc
.tymed
= TYMED_ENHMF
;
3070 hr
= IDataObject_QueryGetData(pDataObject
, &fmtetc
);
3071 ok(hr
== OLE_E_NOTRUNNING
, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
3073 fmtetc
.cfFormat
= CF_TEXT
;
3075 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
3077 fmtetc
.tymed
= TYMED_NULL
;
3078 hr
= IDataObject_QueryGetData(pDataObject
, &fmtetc
);
3079 ok(hr
== OLE_E_NOTRUNNING
, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
3081 hr
= IOleObject_QueryInterface(pObject
, &IID_IRunnableObject
, (void **)&pRunnableObject
);
3082 ok_ole_success(hr
, "IOleObject_QueryInterface");
3084 hr
= IRunnableObject_SetContainedObject(pRunnableObject
, TRUE
);
3085 ok_ole_success(hr
, "IRunnableObject_SetContainedObject");
3087 hr
= IRunnableObject_Run(pRunnableObject
, NULL
);
3088 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
3090 hr
= IOleObject_Close(pObject
, OLECLOSE_NOSAVE
);
3091 ok_ole_success(hr
, "IOleObject_Close");
3093 IRunnableObject_Release(pRunnableObject
);
3094 IOleObject_Release(pObject
);
3096 /* Test failure propagation from delegate ::QueryInterface */
3097 hr
= CoRegisterClassObject(&CLSID_WineTest
, (IUnknown
*)&OleObjectCF
,
3098 CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, &dwRegister
);
3099 ok_ole_success(hr
, "CoRegisterClassObject");
3102 expected_method_list
= methods_embeddinghelper
;
3103 hr
= OleCreateEmbeddingHelper(&CLSID_WineTest
, NULL
, EMBDHLP_INPROC_SERVER
,
3104 &OleObjectCF
, &IID_IOleObject
, (void**)&pObject
);
3105 ok_ole_success(hr
, "OleCreateEmbeddingHelper");
3110 g_QIFailsWith
= E_FAIL
;
3111 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
3112 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
3114 g_QIFailsWith
= E_NOINTERFACE
;
3115 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
3116 ok(hr
== E_NOINTERFACE
, "Got 0x%08x\n", hr
);
3118 g_QIFailsWith
= CO_E_OBJNOTCONNECTED
;
3119 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
3120 ok(hr
== CO_E_OBJNOTCONNECTED
, "Got 0x%08x\n", hr
);
3122 g_QIFailsWith
= 0x87654321;
3123 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
3124 ok(hr
== 0x87654321, "Got 0x%08x\n", hr
);
3126 IOleObject_Release(pObject
);
3129 CHECK_NO_EXTRA_METHODS();
3131 hr
= CoRevokeClassObject(dwRegister
);
3132 ok_ole_success(hr
, "CoRevokeClassObject");
3136 static void test_runnable(void)
3138 static const struct expected_method methods_query_runnable
[] =
3140 { "OleObject_QueryInterface", 0 },
3141 { "OleObjectRunnable_AddRef", 0 },
3142 { "OleObjectRunnable_IsRunning", 0 },
3143 { "OleObjectRunnable_Release", 0 },
3147 static const struct expected_method methods_no_runnable
[] =
3149 { "OleObject_QueryInterface", 0 },
3154 IOleObject
*object
= &OleObject
;
3157 ret
= OleIsRunning(NULL
);
3158 ok(ret
== FALSE
, "got %d\n", ret
);
3160 expected_method_list
= methods_query_runnable
;
3161 ret
= OleIsRunning(object
);
3162 ok(ret
== TRUE
, "Object should be running\n");
3163 CHECK_NO_EXTRA_METHODS();
3165 g_isRunning
= FALSE
;
3166 expected_method_list
= methods_query_runnable
;
3167 ret
= OleIsRunning(object
);
3168 ok(ret
== FALSE
, "Object should not be running\n");
3169 CHECK_NO_EXTRA_METHODS();
3171 g_showRunnable
= FALSE
; /* QueryInterface(IID_IRunnableObject, ...) will fail */
3172 expected_method_list
= methods_no_runnable
;
3173 ret
= OleIsRunning(object
);
3174 ok(ret
== TRUE
, "Object without IRunnableObject should be running\n");
3175 CHECK_NO_EXTRA_METHODS();
3178 g_showRunnable
= TRUE
;
3182 static HRESULT WINAPI
OleRun_QueryInterface(IRunnableObject
*iface
, REFIID riid
, void **ppv
)
3186 if (IsEqualIID(riid
, &IID_IUnknown
) ||
3187 IsEqualIID(riid
, &IID_IRunnableObject
)) {
3193 IUnknown_AddRef((IUnknown
*)*ppv
);
3197 return E_NOINTERFACE
;
3200 static ULONG WINAPI
OleRun_AddRef(IRunnableObject
*iface
)
3205 static ULONG WINAPI
OleRun_Release(IRunnableObject
*iface
)
3210 static HRESULT WINAPI
OleRun_GetRunningClass(IRunnableObject
*iface
, CLSID
*clsid
)
3212 ok(0, "unexpected\n");
3216 static HRESULT WINAPI
OleRun_Run(IRunnableObject
*iface
, LPBINDCTX ctx
)
3218 ok(ctx
== NULL
, "got %p\n", ctx
);
3222 static BOOL WINAPI
OleRun_IsRunning(IRunnableObject
*iface
)
3224 ok(0, "unexpected\n");
3228 static HRESULT WINAPI
OleRun_LockRunning(IRunnableObject
*iface
, BOOL lock
,
3229 BOOL last_unlock_closes
)
3231 ok(0, "unexpected\n");
3235 static HRESULT WINAPI
OleRun_SetContainedObject(IRunnableObject
*iface
, BOOL contained
)
3237 ok(0, "unexpected\n");
3241 static const IRunnableObjectVtbl oleruntestvtbl
=
3243 OleRun_QueryInterface
,
3246 OleRun_GetRunningClass
,
3250 OleRun_SetContainedObject
3253 static IRunnableObject testrunnable
= { &oleruntestvtbl
};
3255 static void test_OleRun(void)
3259 /* doesn't support IRunnableObject */
3260 hr
= OleRun(&unknown
);
3261 ok(hr
== S_OK
, "OleRun failed 0x%08x\n", hr
);
3263 hr
= OleRun((IUnknown
*)&testrunnable
);
3264 ok(hr
== 0xdeadc0de, "got 0x%08x\n", hr
);
3267 static void test_OleLockRunning(void)
3271 hr
= OleLockRunning(&unknown
, TRUE
, FALSE
);
3272 ok(hr
== S_OK
, "OleLockRunning failed 0x%08x\n", hr
);
3275 static void test_OleDraw(void)
3280 hr
= OleDraw((IUnknown
*)&viewobject
, 0, (HDC
)0x1, NULL
);
3281 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3283 hr
= OleDraw(NULL
, 0, (HDC
)0x1, NULL
);
3284 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3286 hr
= OleDraw(NULL
, 0, (HDC
)0x1, &rect
);
3287 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3290 static const WCHAR olepres0W
[] = {2,'O','l','e','P','r','e','s','0','0','0',0};
3291 static const WCHAR comp_objW
[] = {1,'C','o','m','p','O','b','j',0};
3292 static IStream
*comp_obj_stream
;
3293 static IStream
*ole_stream
;
3294 static IStream
*olepres_stream
;
3295 static IStream
*contents_stream
;
3297 static HRESULT WINAPI
Storage_QueryInterface(IStorage
*iface
, REFIID riid
, void **ppvObject
)
3299 ok(0, "unexpected call to QueryInterface\n");
3303 static ULONG WINAPI
Storage_AddRef(IStorage
*iface
)
3305 ok(0, "unexpected call to AddRef\n");
3309 static ULONG WINAPI
Storage_Release(IStorage
*iface
)
3311 ok(0, "unexpected call to Release\n");
3315 static HRESULT WINAPI
Storage_CreateStream(IStorage
*iface
, LPCOLESTR pwcsName
, DWORD grfMode
, DWORD reserved1
, DWORD reserved2
, IStream
**ppstm
)
3317 ULARGE_INTEGER size
= {{0}};
3318 LARGE_INTEGER pos
= {{0}};
3321 if (!lstrcmpW(pwcsName
, comp_objW
))
3323 CHECK_EXPECT(Storage_CreateStream_CompObj
);
3324 *ppstm
= comp_obj_stream
;
3326 todo_wine
ok(grfMode
== (STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
3328 else if (!lstrcmpW(pwcsName
, olepres0W
))
3330 CHECK_EXPECT(Storage_CreateStream_OlePres
);
3331 *ppstm
= olepres_stream
;
3333 todo_wine
ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
3338 ok(0, "unexpected stream name %s\n", wine_dbgstr_w(pwcsName
));
3339 #if 0 /* FIXME: return NULL once Wine is fixed */
3343 *ppstm
= contents_stream
;
3347 ok(!reserved1
, "reserved1 = %x\n", reserved1
);
3348 ok(!reserved2
, "reserved2 = %x\n", reserved2
);
3349 ok(!!ppstm
, "ppstm = NULL\n");
3351 IStream_AddRef(*ppstm
);
3352 hr
= IStream_Seek(*ppstm
, pos
, STREAM_SEEK_SET
, NULL
);
3353 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3354 hr
= IStream_SetSize(*ppstm
, size
);
3355 ok(hr
== S_OK
, "IStream_SetSize returned %x\n", hr
);
3359 static HRESULT WINAPI
Storage_OpenStream(IStorage
*iface
, LPCOLESTR pwcsName
, void *reserved1
, DWORD grfMode
, DWORD reserved2
, IStream
**ppstm
)
3361 static const WCHAR ole1W
[] = {1,'O','l','e',0};
3363 LARGE_INTEGER pos
= {{0}};
3366 ok(!reserved1
, "reserved1 = %p\n", reserved1
);
3367 ok(!reserved2
, "reserved2 = %x\n", reserved2
);
3368 ok(!!ppstm
, "ppstm = NULL\n");
3370 if(!lstrcmpW(pwcsName
, comp_objW
)) {
3371 CHECK_EXPECT2(Storage_OpenStream_CompObj
);
3372 ok(grfMode
== STGM_SHARE_EXCLUSIVE
, "grfMode = %x\n", grfMode
);
3374 *ppstm
= comp_obj_stream
;
3375 IStream_AddRef(comp_obj_stream
);
3376 hr
= IStream_Seek(comp_obj_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3377 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3379 }else if(!lstrcmpW(pwcsName
, ole1W
)) {
3380 CHECK_EXPECT(Storage_OpenStream_Ole
);
3384 ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READ
), "grfMode = %x\n", grfMode
);
3387 return STG_E_FILENOTFOUND
;
3390 ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
3392 *ppstm
= ole_stream
;
3393 IStream_AddRef(ole_stream
);
3394 hr
= IStream_Seek(ole_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3395 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3398 }else if(!lstrcmpW(pwcsName
, olepres0W
)) {
3399 CHECK_EXPECT(Storage_OpenStream_OlePres
);
3400 ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
3402 *ppstm
= olepres_stream
;
3403 IStream_AddRef(olepres_stream
);
3404 hr
= IStream_Seek(olepres_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3405 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3409 ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName
));
3413 static HRESULT WINAPI
Storage_CreateStorage(IStorage
*iface
, LPCOLESTR pwcsName
, DWORD grfMode
, DWORD dwStgFmt
, DWORD reserved2
, IStorage
**ppstg
)
3415 ok(0, "unexpected call to CreateStorage\n");
3419 static HRESULT WINAPI
Storage_OpenStorage(IStorage
*iface
, LPCOLESTR pwcsName
, IStorage
*pstgPriority
, DWORD grfMode
, SNB snbExclude
, DWORD reserved
, IStorage
**ppstg
)
3421 ok(0, "unexpected call to OpenStorage\n");
3425 static HRESULT WINAPI
Storage_CopyTo(IStorage
*iface
, DWORD ciidExclude
, const IID
*rgiidExclude
, SNB snbExclude
, IStorage
*pstgDest
)
3427 ok(0, "unexpected call to CopyTo\n");
3431 static HRESULT WINAPI
Storage_MoveElementTo(IStorage
*iface
, LPCOLESTR pwcsName
, IStorage
*pstgDest
, LPCOLESTR pwcsNewName
, DWORD grfFlags
)
3433 ok(0, "unexpected call to MoveElementTo\n");
3437 static HRESULT WINAPI
Storage_Commit(IStorage
*iface
, DWORD grfCommitFlags
)
3439 ok(0, "unexpected call to Commit\n");
3443 static HRESULT WINAPI
Storage_Revert(IStorage
*iface
)
3445 ok(0, "unexpected call to Revert\n");
3449 static HRESULT WINAPI
Storage_EnumElements(IStorage
*iface
, DWORD reserved1
, void *reserved2
, DWORD reserved3
, IEnumSTATSTG
**ppenum
)
3451 ok(0, "unexpected call to EnumElements\n");
3455 static HRESULT WINAPI
Storage_DestroyElement(IStorage
*iface
, LPCOLESTR pwcsName
)
3460 CHECK_EXPECT2(Storage_DestroyElement
);
3461 cmp
= CompareStringW(LOCALE_NEUTRAL
, 0, pwcsName
, 8, olepres0W
, 8);
3462 ok(cmp
== CSTR_EQUAL
,
3463 "unexpected call to DestroyElement(%s)\n", wine_dbgstr_w(pwcsName
));
3465 WideCharToMultiByte(CP_ACP
, 0, pwcsName
, -1, name
, sizeof(name
), NULL
, NULL
);
3466 stream_n
= atol(name
+ 8);
3467 if (stream_n
<= Storage_DestroyElement_limit
)
3470 return STG_E_FILENOTFOUND
;
3473 static HRESULT WINAPI
Storage_RenameElement(IStorage
*iface
, LPCOLESTR pwcsOldName
, LPCOLESTR pwcsNewName
)
3475 ok(0, "unexpected call to RenameElement\n");
3479 static HRESULT WINAPI
Storage_SetElementTimes(IStorage
*iface
, LPCOLESTR pwcsName
, const FILETIME
*pctime
, const FILETIME
*patime
, const FILETIME
*pmtime
)
3481 ok(0, "unexpected call to SetElementTimes\n");
3485 static HRESULT WINAPI
Storage_SetClass(IStorage
*iface
, REFCLSID clsid
)
3487 CHECK_EXPECT(Storage_SetClass
);
3488 ok(IsEqualIID(clsid
, Storage_SetClass_CLSID
), "expected %s, got %s\n",
3489 wine_dbgstr_guid(Storage_SetClass_CLSID
), wine_dbgstr_guid(clsid
));
3493 static HRESULT WINAPI
Storage_SetStateBits(IStorage
*iface
, DWORD grfStateBits
, DWORD grfMask
)
3495 ok(0, "unexpected call to SetStateBits\n");
3499 static HRESULT WINAPI
Storage_Stat(IStorage
*iface
, STATSTG
*pstatstg
, DWORD grfStatFlag
)
3501 CHECK_EXPECT2(Storage_Stat
);
3502 ok(pstatstg
!= NULL
, "pstatstg = NULL\n");
3503 ok(grfStatFlag
== STATFLAG_NONAME
, "grfStatFlag = %x\n", grfStatFlag
);
3505 memset(pstatstg
, 0, sizeof(STATSTG
));
3506 pstatstg
->type
= STGTY_STORAGE
;
3507 pstatstg
->clsid
= CLSID_WineTestOld
;
3511 static IStorageVtbl StorageVtbl
=
3513 Storage_QueryInterface
,
3516 Storage_CreateStream
,
3518 Storage_CreateStorage
,
3519 Storage_OpenStorage
,
3521 Storage_MoveElementTo
,
3524 Storage_EnumElements
,
3525 Storage_DestroyElement
,
3526 Storage_RenameElement
,
3527 Storage_SetElementTimes
,
3529 Storage_SetStateBits
,
3533 static IStorage Storage
= { &StorageVtbl
};
3535 static void test_OleDoAutoConvert(void)
3537 static const WCHAR clsidW
[] = {'C','L','S','I','D','\\',0};
3542 DWORD ansi_user_type_len
;
3543 DWORD ansi_clipboard_format_len
;
3545 DWORD unicode_marker
;
3546 DWORD unicode_user_type_len
;
3547 DWORD unicode_clipboard_format_len
;
3553 DWORD link_update_option
;
3555 DWORD reserved_moniker_stream_size
;
3556 DWORD relative_source_moniker_stream_size
;
3557 DWORD absolute_source_moniker_stream_size
;
3558 DWORD clsid_indicator
;
3560 DWORD reserved_display_name
;
3562 DWORD local_update_time
;
3563 DWORD local_check_update_time
;
3564 DWORD remote_update_time
;
3567 LARGE_INTEGER pos
= {{0}};
3574 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &comp_obj_stream
);
3575 ok(hr
== S_OK
, "CreateStreamOnHGlobal returned %x\n", hr
);
3576 hr
= IStream_Write(comp_obj_stream
, (char*)&comp_obj_data
, sizeof(comp_obj_data
), NULL
);
3577 ok(hr
== S_OK
, "IStream_Write returned %x\n", hr
);
3579 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &ole_stream
);
3580 ok(hr
== S_OK
, "CreateStreamOnHGlobal returned %x\n", hr
);
3581 hr
= IStream_Write(ole_stream
, (char*)&ole_data
, sizeof(ole_data
), NULL
);
3582 ok(hr
== S_OK
, "IStream_Write returned %x\n", hr
);
3584 clsid
= IID_WineTest
;
3585 hr
= OleDoAutoConvert(NULL
, &clsid
);
3586 ok(hr
== E_INVALIDARG
, "OleDoAutoConvert returned %x\n", hr
);
3587 ok(IsEqualIID(&clsid
, &IID_NULL
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3589 if(0) /* crashes on Win7 */
3590 OleDoAutoConvert(&Storage
, NULL
);
3592 clsid
= IID_WineTest
;
3593 SET_EXPECT(Storage_Stat
);
3594 hr
= OleDoAutoConvert(&Storage
, &clsid
);
3595 ok(hr
== REGDB_E_CLASSNOTREG
, "OleDoAutoConvert returned %x\n", hr
);
3596 CHECK_CALLED(Storage_Stat
);
3597 ok(IsEqualIID(&clsid
, &CLSID_WineTestOld
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3599 lstrcpyW(buf
, clsidW
);
3600 StringFromGUID2(&CLSID_WineTestOld
, buf
+6, 39);
3602 ret
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, buf
, 0, NULL
, 0,
3603 KEY_READ
| KEY_WRITE
| KEY_CREATE_SUB_KEY
, NULL
, &root
, NULL
);
3604 if(ret
!= ERROR_SUCCESS
) {
3605 win_skip("not enough permissions to create CLSID key (%u)\n", ret
);
3609 clsid
= IID_WineTest
;
3610 SET_EXPECT(Storage_Stat
);
3611 hr
= OleDoAutoConvert(&Storage
, &clsid
);
3612 ok(hr
== REGDB_E_KEYMISSING
, "OleDoAutoConvert returned %x\n", hr
);
3613 CHECK_CALLED(Storage_Stat
);
3614 ok(IsEqualIID(&clsid
, &CLSID_WineTestOld
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3616 hr
= OleSetAutoConvert(&CLSID_WineTestOld
, &CLSID_WineTest
);
3617 ok_ole_success(hr
, "OleSetAutoConvert");
3619 hr
= OleGetAutoConvert(&CLSID_WineTestOld
, &clsid
);
3620 ok_ole_success(hr
, "OleGetAutoConvert");
3621 ok(IsEqualIID(&clsid
, &CLSID_WineTest
), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid
));
3623 clsid
= IID_WineTest
;
3624 SET_EXPECT(Storage_Stat
);
3625 SET_EXPECT(Storage_OpenStream_CompObj
);
3626 SET_EXPECT(Storage_SetClass
);
3627 SET_EXPECT(Storage_CreateStream_CompObj
);
3628 SET_EXPECT(Storage_OpenStream_Ole
);
3629 hr
= OleDoAutoConvert(&Storage
, &clsid
);
3630 ok(hr
== S_OK
, "OleDoAutoConvert returned %x\n", hr
);
3631 CHECK_CALLED(Storage_Stat
);
3632 CHECK_CALLED(Storage_OpenStream_CompObj
);
3633 CHECK_CALLED(Storage_SetClass
);
3634 CHECK_CALLED(Storage_CreateStream_CompObj
);
3635 CHECK_CALLED(Storage_OpenStream_Ole
);
3636 ok(IsEqualIID(&clsid
, &CLSID_WineTest
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3638 hr
= IStream_Seek(comp_obj_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3639 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3640 hr
= IStream_Read(comp_obj_stream
, &comp_obj_data
, sizeof(comp_obj_data
), NULL
);
3641 ok(hr
== S_OK
, "IStream_Read returned %x\n", hr
);
3642 ok(comp_obj_data
.reserved1
== 0xfffe0001, "reserved1 = %x\n", comp_obj_data
.reserved1
);
3643 ok(comp_obj_data
.version
== 0xa03, "version = %x\n", comp_obj_data
.version
);
3644 ok(comp_obj_data
.reserved2
[0] == -1, "reserved2[0] = %x\n", comp_obj_data
.reserved2
[0]);
3645 ok(IsEqualIID(comp_obj_data
.reserved2
+1, &CLSID_WineTestOld
), "reserved2 = %s\n", wine_dbgstr_guid((CLSID
*)(comp_obj_data
.reserved2
+1)));
3646 ok(!comp_obj_data
.ansi_user_type_len
, "ansi_user_type_len = %d\n", comp_obj_data
.ansi_user_type_len
);
3647 ok(!comp_obj_data
.ansi_clipboard_format_len
, "ansi_clipboard_format_len = %d\n", comp_obj_data
.ansi_clipboard_format_len
);
3648 ok(!comp_obj_data
.reserved3
, "reserved3 = %x\n", comp_obj_data
.reserved3
);
3649 ok(comp_obj_data
.unicode_marker
== 0x71b239f4, "unicode_marker = %x\n", comp_obj_data
.unicode_marker
);
3650 ok(!comp_obj_data
.unicode_user_type_len
, "unicode_user_type_len = %d\n", comp_obj_data
.unicode_user_type_len
);
3651 ok(!comp_obj_data
.unicode_clipboard_format_len
, "unicode_clipboard_format_len = %d\n", comp_obj_data
.unicode_clipboard_format_len
);
3652 ok(!comp_obj_data
.reserved4
, "reserved4 %d\n", comp_obj_data
.reserved4
);
3654 hr
= IStream_Seek(ole_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3655 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3656 hr
= IStream_Read(ole_stream
, &ole_data
, sizeof(ole_data
), NULL
);
3657 ok(hr
== S_OK
, "IStream_Read returned %x\n", hr
);
3658 ok(ole_data
.version
== 0, "version = %x\n", ole_data
.version
);
3659 ok(ole_data
.flags
== 4, "flags = %x\n", ole_data
.flags
);
3660 for(i
=2; i
<sizeof(ole_data
)/sizeof(DWORD
); i
++)
3661 ok(((DWORD
*)&ole_data
)[i
] == 0, "ole_data[%d] = %x\n", i
, ((DWORD
*)&ole_data
)[i
]);
3663 SET_EXPECT(Storage_OpenStream_Ole
);
3664 hr
= SetConvertStg(&Storage
, TRUE
);
3665 ok(hr
== S_OK
, "SetConvertStg returned %x\n", hr
);
3666 CHECK_CALLED(Storage_OpenStream_Ole
);
3668 SET_EXPECT(Storage_OpenStream_CompObj
);
3669 SET_EXPECT(Storage_Stat
);
3670 SET_EXPECT(Storage_CreateStream_CompObj
);
3671 hr
= WriteFmtUserTypeStg(&Storage
, 0, NULL
);
3672 ok(hr
== S_OK
, "WriteFmtUserTypeStg returned %x\n", hr
);
3673 todo_wine
CHECK_CALLED(Storage_OpenStream_CompObj
);
3674 CHECK_CALLED(Storage_Stat
);
3675 CHECK_CALLED(Storage_CreateStream_CompObj
);
3676 hr
= IStream_Seek(comp_obj_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3677 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3678 hr
= IStream_Read(comp_obj_stream
, &comp_obj_data
, sizeof(comp_obj_data
), NULL
);
3679 ok(hr
== S_OK
, "IStream_Read returned %x\n", hr
);
3680 ok(comp_obj_data
.reserved1
== 0xfffe0001, "reserved1 = %x\n", comp_obj_data
.reserved1
);
3681 ok(comp_obj_data
.version
== 0xa03, "version = %x\n", comp_obj_data
.version
);
3682 ok(comp_obj_data
.reserved2
[0] == -1, "reserved2[0] = %x\n", comp_obj_data
.reserved2
[0]);
3683 ok(IsEqualIID(comp_obj_data
.reserved2
+1, &CLSID_WineTestOld
), "reserved2 = %s\n", wine_dbgstr_guid((CLSID
*)(comp_obj_data
.reserved2
+1)));
3684 ok(!comp_obj_data
.ansi_user_type_len
, "ansi_user_type_len = %d\n", comp_obj_data
.ansi_user_type_len
);
3685 ok(!comp_obj_data
.ansi_clipboard_format_len
, "ansi_clipboard_format_len = %d\n", comp_obj_data
.ansi_clipboard_format_len
);
3686 ok(!comp_obj_data
.reserved3
, "reserved3 = %x\n", comp_obj_data
.reserved3
);
3687 ok(comp_obj_data
.unicode_marker
== 0x71b239f4, "unicode_marker = %x\n", comp_obj_data
.unicode_marker
);
3688 ok(!comp_obj_data
.unicode_user_type_len
, "unicode_user_type_len = %d\n", comp_obj_data
.unicode_user_type_len
);
3689 ok(!comp_obj_data
.unicode_clipboard_format_len
, "unicode_clipboard_format_len = %d\n", comp_obj_data
.unicode_clipboard_format_len
);
3690 ok(!comp_obj_data
.reserved4
, "reserved4 %d\n", comp_obj_data
.reserved4
);
3692 ret
= IStream_Release(comp_obj_stream
);
3693 ok(!ret
, "comp_obj_stream was not freed\n");
3694 ret
= IStream_Release(ole_stream
);
3695 ok(!ret
, "ole_stream was not freed\n");
3697 ret
= RegDeleteKeyA(root
, "AutoConvertTo");
3698 ok(ret
== ERROR_SUCCESS
, "RegDeleteKey error %u\n", ret
);
3699 ret
= RegDeleteKeyA(root
, "");
3700 ok(ret
== ERROR_SUCCESS
, "RegDeleteKey error %u\n", ret
);
3705 static const unsigned char bmpimage
[] =
3707 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,
3708 0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
3709 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
3710 0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
3711 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,
3712 0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
3713 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,
3714 0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
3718 static const unsigned char mf_blank_bits
[] =
3720 0x01,0x00,0x09,0x00,0x00,0x03,0x0c,0x00,
3721 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
3722 0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00
3725 static void test_data_cache_save(void)
3727 static const WCHAR contentsW
[] = { 'C','o','n','t','e','n','t','s',0 };
3733 IPersistStorage
*stg
;
3734 DWORD clipformat
[2];
3735 PresentationDataHeader hdr
;
3737 hr
= CreateILockBytesOnHGlobal(0, TRUE
, &ilb
);
3738 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3739 hr
= StgCreateDocfileOnILockBytes(ilb
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &doc
);
3740 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3742 ILockBytes_Release(ilb
);
3744 hr
= IStorage_SetClass(doc
, &CLSID_WineTest
);
3745 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3747 hr
= IStorage_CreateStream(doc
, contentsW
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
3748 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3749 hr
= IStream_Write(stm
, bmpimage
, sizeof(bmpimage
), NULL
);
3750 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3751 IStream_Release(stm
);
3753 hr
= IStorage_CreateStream(doc
, olepres0W
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
3754 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3757 clipformat
[1] = CF_METAFILEPICT
;
3758 hr
= IStream_Write(stm
, clipformat
, sizeof(clipformat
), NULL
);
3759 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3761 hdr
.tdSize
= sizeof(hdr
.tdSize
);
3762 hdr
.dvAspect
= DVASPECT_CONTENT
;
3764 hdr
.advf
= ADVF_PRIMEFIRST
;
3766 hdr
.dwObjectExtentX
= 0;
3767 hdr
.dwObjectExtentY
= 0;
3768 hdr
.dwSize
= sizeof(mf_blank_bits
);
3769 hr
= IStream_Write(stm
, &hdr
, sizeof(hdr
), NULL
);
3770 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3771 hr
= IStream_Write(stm
, mf_blank_bits
, sizeof(mf_blank_bits
), NULL
);
3772 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3774 IStream_Release(stm
);
3776 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IUnknown
, (void **)&cache
);
3777 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3778 hr
= IOleCache2_QueryInterface(cache
, &IID_IPersistStorage
, (void **)&stg
);
3779 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3780 hr
= IPersistStorage_Load(stg
, doc
);
3781 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3783 IStorage_Release(doc
);
3785 hr
= IPersistStorage_IsDirty(stg
);
3786 ok(hr
== S_FALSE
, "unexpected %#x\n", hr
);
3789 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &olepres_stream
);
3790 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3792 /* FIXME: remove this stream once Wine is fixed */
3793 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &contents_stream
);
3794 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3796 SET_EXPECT(Storage_CreateStream_OlePres
);
3797 SET_EXPECT(Storage_OpenStream_OlePres
);
3798 SET_EXPECT(Storage_OpenStream_Ole
);
3799 SET_EXPECT(Storage_DestroyElement
);
3800 Storage_DestroyElement_limit
= 50;
3801 Storage_SetClass_CLSID
= &CLSID_NULL
;
3802 trace("IPersistStorage_Save:\n");
3803 hr
= IPersistStorage_Save(stg
, &Storage
, FALSE
);
3804 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3805 CHECK_CALLED(Storage_CreateStream_OlePres
);
3807 CHECK_CALLED(Storage_OpenStream_OlePres
);
3809 CHECK_CALLED(Storage_OpenStream_Ole
);
3811 CHECK_CALLED(Storage_DestroyElement
);
3813 IStream_Release(olepres_stream
);
3814 IStream_Release(contents_stream
);
3816 IPersistStorage_Release(stg
);
3817 IOleCache2_Release(cache
);
3820 #define MAX_STREAM 16
3836 struct stream_def stream
[MAX_STREAM
];
3839 static const struct storage_def stg_def_0
=
3842 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) }}
3844 static const struct storage_def stg_def_0_saved
=
3846 &CLSID_NULL
, 0, {{ 0 }}
3848 static const struct storage_def stg_def_1
=
3851 {{ "Contents", -1, 0, 0, NULL
, 0 },
3852 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3854 static const struct storage_def stg_def_1_saved
=
3857 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3859 static const struct storage_def stg_def_2
=
3861 &CLSID_ManualResetEvent
, 2,
3862 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3863 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3865 static const struct storage_def stg_def_2_saved
=
3868 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3870 static const struct storage_def stg_def_3
=
3873 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3874 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3875 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3876 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3877 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3879 static const struct storage_def stg_def_3_saved
=
3882 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3883 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3884 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) }}
3886 static const struct storage_def stg_def_4
=
3888 &CLSID_Picture_EnhMetafile
, 5,
3889 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3890 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3891 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3892 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3893 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3895 static const struct storage_def stg_def_4_saved
=
3898 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3900 static const struct storage_def stg_def_5
=
3902 &CLSID_Picture_Dib
, 5,
3903 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3904 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3905 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3906 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3907 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3909 static const struct storage_def stg_def_5_saved
=
3912 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3914 static const struct storage_def stg_def_6
=
3916 &CLSID_Picture_Metafile
, 5,
3917 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3918 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3919 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3920 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3921 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3923 static const struct storage_def stg_def_6_saved
=
3926 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3928 static const struct storage_def stg_def_7
=
3930 &CLSID_Picture_Dib
, 1,
3931 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) }}
3933 static const struct storage_def stg_def_7_saved
=
3935 &CLSID_NULL
, 0, {{ 0 }}
3937 static const struct storage_def stg_def_8
=
3939 &CLSID_Picture_Metafile
, 1,
3940 {{ "Contents", -1, 0, 0, mf_blank_bits
, sizeof(mf_blank_bits
) }}
3942 static const struct storage_def stg_def_8_saved
=
3944 &CLSID_NULL
, 0, {{ 0 }}
3946 static const struct storage_def stg_def_9
=
3948 &CLSID_Picture_EnhMetafile
, 1,
3949 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) }}
3951 static const struct storage_def stg_def_9_saved
=
3953 &CLSID_NULL
, 0, {{ 0 }}
3956 static int read_clipformat(IStream
*stream
)
3960 int length
, clipformat
= -2;
3962 hr
= IStream_Read(stream
, &length
, sizeof(length
), &bytes
);
3963 if (hr
!= S_OK
|| bytes
!= sizeof(length
))
3969 hr
= IStream_Read(stream
, &clipformat
, sizeof(clipformat
), &bytes
);
3970 if (hr
!= S_OK
|| bytes
!= sizeof(clipformat
))
3974 ok(0, "unhandled clipformat length %d\n", length
);
3979 static void check_storage_contents(IStorage
*stg
, const struct storage_def
*stg_def
,
3980 int *enumerated_streams
, int *matched_streams
)
3983 IEnumSTATSTG
*enumstg
;
3986 int i
, seen_stream
[MAX_STREAM
] = { 0 };
3988 if (winetest_debug
> 1)
3989 trace("check_storage_contents:\n=============================================\n");
3991 *enumerated_streams
= 0;
3992 *matched_streams
= 0;
3994 hr
= IStorage_Stat(stg
, &stat
, STATFLAG_NONAME
);
3995 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3996 ok(IsEqualCLSID(stg_def
->clsid
, &stat
.clsid
), "expected %s, got %s\n",
3997 wine_dbgstr_guid(stg_def
->clsid
), wine_dbgstr_guid(&stat
.clsid
));
3999 hr
= IStorage_EnumElements(stg
, 0, NULL
, 0, &enumstg
);
4000 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4005 int clipformat
= -1;
4006 PresentationDataHeader header
;
4010 memset(&header
, 0, sizeof(header
));
4012 hr
= IEnumSTATSTG_Next(enumstg
, 1, &stat
, NULL
);
4013 if(hr
== S_FALSE
) break;
4014 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4016 if (winetest_debug
> 1)
4017 trace("name %s, type %u, size %d, clsid %s\n",
4018 wine_dbgstr_w(stat
.pwcsName
), stat
.type
, stat
.cbSize
.u
.LowPart
, wine_dbgstr_guid(&stat
.clsid
));
4020 ok(stat
.type
== STGTY_STREAM
, "unexpected %#x\n", stat
.type
);
4022 WideCharToMultiByte(CP_ACP
, 0, stat
.pwcsName
, -1, name
, sizeof(name
), NULL
, NULL
);
4024 hr
= IStorage_OpenStream(stg
, stat
.pwcsName
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, &stream
);
4025 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4027 if (!memcmp(name
, "\2OlePres", 8))
4029 ULONG header_size
= sizeof(header
);
4031 clipformat
= read_clipformat(stream
);
4033 if (clipformat
== 0) /* view cache */
4034 header_size
= FIELD_OFFSET(PresentationDataHeader
, unknown7
);
4036 hr
= IStream_Read(stream
, &header
, header_size
, &bytes
);
4037 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4038 ok(bytes
== header_size
, "read %u bytes, expected %u\n", bytes
, header_size
);
4040 if (winetest_debug
> 1)
4041 trace("header: tdSize %#x, dvAspect %#x, lindex %#x, advf %#x, unknown7 %#x, dwObjectExtentX %#x, dwObjectExtentY %#x, dwSize %#x\n",
4042 header
.tdSize
, header
.dvAspect
, header
.lindex
, header
.advf
, header
.unknown7
,
4043 header
.dwObjectExtentX
, header
.dwObjectExtentY
, header
.dwSize
);
4046 memset(data
, 0, sizeof(data
));
4047 hr
= IStream_Read(stream
, data
, sizeof(data
), &bytes
);
4048 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4049 if (winetest_debug
> 1)
4050 trace("stream data (%u bytes): %02x %02x %02x %02x\n", bytes
, data
[0], data
[1], data
[2], data
[3]);
4052 for (i
= 0; i
< stg_def
->stream_count
; i
++)
4054 if (seen_stream
[i
]) continue;
4056 if (winetest_debug
> 1)
4057 trace("%s/%s, %d/%d, %d/%d, %d/%d\n",
4058 stg_def
->stream
[i
].name
, name
,
4059 stg_def
->stream
[i
].cf
, clipformat
,
4060 stg_def
->stream
[i
].dvAspect
, header
.dvAspect
,
4061 stg_def
->stream
[i
].advf
, header
.advf
);
4063 if (!strcmp(stg_def
->stream
[i
].name
, name
) &&
4064 stg_def
->stream
[i
].cf
== clipformat
&&
4065 stg_def
->stream
[i
].dvAspect
== header
.dvAspect
&&
4066 stg_def
->stream
[i
].advf
== header
.advf
&&
4067 stg_def
->stream
[i
].data_size
<= bytes
&&
4068 (!stg_def
->stream
[i
].data_size
||
4069 (!memcmp(stg_def
->stream
[i
].data
, data
, min(stg_def
->stream
[i
].data_size
, bytes
)))))
4071 if (winetest_debug
> 1)
4072 trace("stream %d matches def stream %d\n", *enumerated_streams
, i
);
4074 *matched_streams
+= 1;
4078 CoTaskMemFree(stat
.pwcsName
);
4079 IStream_Release(stream
);
4081 *enumerated_streams
+= 1;
4085 static HRESULT
stgmedium_cmp(const STGMEDIUM
*med1
, STGMEDIUM
*med2
)
4087 BYTE
*data1
, *data2
;
4088 ULONG datasize1
, datasize2
;
4090 if (med1
->tymed
!= med2
->tymed
)
4093 if (med1
->tymed
== TYMED_MFPICT
)
4095 METAFILEPICT
*mfpict1
= GlobalLock(U(med1
)->hMetaFilePict
);
4096 METAFILEPICT
*mfpict2
= GlobalLock(U(med2
)->hMetaFilePict
);
4098 datasize1
= GetMetaFileBitsEx(mfpict1
->hMF
, 0, NULL
);
4099 datasize2
= GetMetaFileBitsEx(mfpict2
->hMF
, 0, NULL
);
4100 if (datasize1
== datasize2
)
4102 data1
= HeapAlloc(GetProcessHeap(), 0, datasize1
);
4103 data2
= HeapAlloc(GetProcessHeap(), 0, datasize2
);
4104 GetMetaFileBitsEx(mfpict1
->hMF
, datasize1
, data1
);
4105 GetMetaFileBitsEx(mfpict2
->hMF
, datasize2
, data2
);
4109 else if (med1
->tymed
== TYMED_ENHMF
)
4111 datasize1
= GetEnhMetaFileBits(med1
->hEnhMetaFile
, 0, NULL
);
4112 datasize2
= GetEnhMetaFileBits(med2
->hEnhMetaFile
, 0, NULL
);
4113 if (datasize1
== datasize2
)
4115 data1
= HeapAlloc(GetProcessHeap(), 0, datasize1
);
4116 data2
= HeapAlloc(GetProcessHeap(), 0, datasize2
);
4117 GetEnhMetaFileBits(med1
->hEnhMetaFile
, datasize1
, data1
);
4118 GetEnhMetaFileBits(med2
->hEnhMetaFile
, datasize2
, data2
);
4122 else if (med1
->tymed
== TYMED_HGLOBAL
)
4124 datasize1
= GlobalSize(med1
->hGlobal
);
4125 datasize2
= GlobalSize(med2
->hGlobal
);
4127 if (datasize1
== datasize2
)
4129 data1
= GlobalLock(med1
->hGlobal
);
4130 data2
= GlobalLock(med2
->hGlobal
);
4138 if (memcmp(data1
, data2
, datasize1
) != 0)
4141 if (med1
->tymed
== TYMED_HGLOBAL
)
4143 GlobalUnlock(U(med1
)->hGlobal
);
4144 GlobalUnlock(U(med2
)->hGlobal
);
4146 else if (med1
->tymed
== TYMED_MFPICT
)
4148 HeapFree(GetProcessHeap(), 0, data1
);
4149 HeapFree(GetProcessHeap(), 0, data2
);
4150 GlobalUnlock(U(med1
)->hMetaFilePict
);
4151 GlobalUnlock(U(med2
)->hMetaFilePict
);
4155 HeapFree(GetProcessHeap(), 0, data1
);
4156 HeapFree(GetProcessHeap(), 0, data2
);
4162 static IStorage
*create_storage_from_def(const struct storage_def
*stg_def
)
4169 hr
= StgCreateDocfile(NULL
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &stg
);
4170 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4172 hr
= IStorage_SetClass(stg
, stg_def
->clsid
);
4173 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4175 for (i
= 0; i
< stg_def
->stream_count
; i
++)
4179 MultiByteToWideChar(CP_ACP
, 0, stg_def
->stream
[i
].name
, -1, name
, 32);
4180 hr
= IStorage_CreateStream(stg
, name
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
4181 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4183 if (stg_def
->stream
[i
].cf
!= -1)
4186 PresentationDataHeader hdr
;
4188 if (stg_def
->stream
[i
].cf
)
4191 clipformat
[1] = stg_def
->stream
[i
].cf
;
4192 hr
= IStream_Write(stm
, clipformat
, sizeof(clipformat
), NULL
);
4197 hr
= IStream_Write(stm
, &clipformat
[0], sizeof(clipformat
[0]), NULL
);
4199 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4201 hdr
.tdSize
= sizeof(hdr
.tdSize
);
4202 hdr
.dvAspect
= stg_def
->stream
[i
].dvAspect
;
4204 hdr
.advf
= stg_def
->stream
[i
].advf
;
4206 hdr
.dwObjectExtentX
= 0;
4207 hdr
.dwObjectExtentY
= 0;
4208 hdr
.dwSize
= stg_def
->stream
[i
].data_size
;
4209 hr
= IStream_Write(stm
, &hdr
, sizeof(hdr
), NULL
);
4210 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4213 if (stg_def
->stream
[i
].data_size
)
4215 hr
= IStream_Write(stm
, stg_def
->stream
[i
].data
, stg_def
->stream
[i
].data_size
, NULL
);
4216 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4219 IStream_Release(stm
);
4225 static const BYTE dib_inf
[] =
4227 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
4228 0x00, 0x00, 0x36, 0x00, 0x00, 0x00
4231 static const BYTE mf_rec
[] =
4233 0xd7, 0xcd, 0xc6, 0x9a, 0x00, 0x00, 0x00, 0x00,
4234 0x00, 0x00, 0x16, 0x00, 0x2d, 0x00, 0x40, 0x02,
4235 0x00, 0x00, 0x00, 0x00, 0x6a, 0x55
4238 static void get_stgdef(struct storage_def
*stg_def
, CLIPFORMAT cf
, STGMEDIUM
*stg_med
, int stm_idx
)
4242 METAFILEPICT
*mfpict
;
4248 data_size
= sizeof(dib
);
4249 if (!strcmp(stg_def
->stream
[stm_idx
].name
, "CONTENTS"))
4251 data_size
+= sizeof(dib_inf
);
4252 data
= HeapAlloc(GetProcessHeap(), 0, data_size
);
4253 memcpy(data
, dib_inf
, sizeof(dib_inf
));
4254 memcpy(data
+ sizeof(dib_inf
), dib
, sizeof(dib
));
4258 data
= HeapAlloc(GetProcessHeap(), 0, data_size
);
4259 memcpy(data
, dib
, sizeof(dib
));
4261 stg_def
->stream
[stm_idx
].data
= data
;
4262 stg_def
->stream
[stm_idx
].data_size
= data_size
;
4264 case CF_METAFILEPICT
:
4265 mfpict
= GlobalLock(U(stg_med
)->hMetaFilePict
);
4266 data_size
= GetMetaFileBitsEx(mfpict
->hMF
, 0, NULL
);
4267 if (!strcmp(stg_def
->stream
[stm_idx
].name
, "CONTENTS"))
4269 data
= HeapAlloc(GetProcessHeap(), 0, data_size
+ sizeof(mf_rec
));
4270 memcpy(data
, mf_rec
, sizeof(mf_rec
));
4271 GetMetaFileBitsEx(mfpict
->hMF
, data_size
, data
+ sizeof(mf_rec
));
4272 data_size
+= sizeof(mf_rec
);
4276 data
= HeapAlloc(GetProcessHeap(), 0, data_size
);
4277 GetMetaFileBitsEx(mfpict
->hMF
, data_size
, data
);
4279 GlobalUnlock(U(stg_med
)->hMetaFilePict
);
4280 stg_def
->stream
[stm_idx
].data_size
= data_size
;
4281 stg_def
->stream
[stm_idx
].data
= data
;
4283 case CF_ENHMETAFILE
:
4284 if (!strcmp(stg_def
->stream
[stm_idx
].name
, "CONTENTS"))
4286 data_size
= GetEnhMetaFileBits(U(stg_med
)->hEnhMetaFile
, 0, NULL
);
4287 data
= HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD
) + sizeof(ENHMETAHEADER
) + data_size
);
4288 *((DWORD
*)data
) = sizeof(ENHMETAHEADER
);
4289 GetEnhMetaFileBits(U(stg_med
)->hEnhMetaFile
, data_size
, data
+ sizeof(DWORD
) + sizeof(ENHMETAHEADER
));
4290 memcpy(data
+ sizeof(DWORD
), data
+ sizeof(DWORD
) + sizeof(ENHMETAHEADER
), sizeof(ENHMETAHEADER
));
4291 data_size
+= sizeof(DWORD
) + sizeof(ENHMETAHEADER
);
4296 data_size
= GetWinMetaFileBits(U(stg_med
)->hEnhMetaFile
, 0, NULL
, MM_ANISOTROPIC
, hdc
);
4297 data
= HeapAlloc(GetProcessHeap(), 0, data_size
);
4298 GetWinMetaFileBits(U(stg_med
)->hEnhMetaFile
, data_size
, data
, MM_ANISOTROPIC
, hdc
);
4299 ReleaseDC(NULL
, hdc
);
4301 stg_def
->stream
[stm_idx
].data_size
= data_size
;
4302 stg_def
->stream
[stm_idx
].data
= data
;
4307 static void get_stgmedium(CLIPFORMAT cfFormat
, STGMEDIUM
*stgmedium
)
4312 create_dib(stgmedium
);
4314 case CF_METAFILEPICT
:
4315 create_mfpict(stgmedium
);
4317 case CF_ENHMETAFILE
:
4318 create_emf(stgmedium
);
4321 ok(0, "cf %x not implemented\n", cfFormat
);
4326 static void test_data_cache_save_data(void)
4333 IPersistStorage
*persist
;
4335 int enumerated_streams
, matched_streams
, i
;
4337 STGMEDIUM stgmeds
[MAX_FMTS
];
4338 struct tests_data_cache
4340 FORMATETC fmts
[MAX_FMTS
];
4341 int num_fmts
, num_set
;
4343 struct storage_def stg_def
;
4346 static struct tests_data_cache
*pdata
, data
[] =
4350 { CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
},
4351 { CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
},
4352 { CF_ENHMETAFILE
, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
},
4353 { 0, 0, DVASPECT_DOCPRINT
, -1, TYMED_HGLOBAL
},
4355 4, 3, &CLSID_WineTest
,
4357 &CLSID_WineTestOld
, 4, { { "\2OlePres000", CF_DIB
, DVASPECT_CONTENT
, 0, NULL
, 0 },
4358 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, 0, NULL
, 0 },
4359 { "\2OlePres002", CF_ENHMETAFILE
, DVASPECT_CONTENT
, 0, NULL
, 0 },
4360 { "\2OlePres003", 0, DVASPECT_DOCPRINT
, 0, NULL
, 0 } }
4363 /* without setting data */
4366 { CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
},
4367 { CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
},
4368 { CF_ENHMETAFILE
, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
},
4370 3, 0, &CLSID_WineTest
,
4372 &CLSID_WineTestOld
, 3, { { "\2OlePres000", CF_DIB
, DVASPECT_CONTENT
, 0, NULL
, 0 },
4373 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, 0, NULL
, 0 },
4374 { "\2OlePres002", CF_ENHMETAFILE
, DVASPECT_CONTENT
, 0, NULL
, 0 } }
4377 /* static picture clsids */
4380 { CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
},
4382 1, 1, &CLSID_Picture_Dib
,
4384 &CLSID_WineTestOld
, 1, { { "CONTENTS", -1, 0, 0, NULL
, 0 } }
4389 { CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
},
4391 1, 1, &CLSID_Picture_Metafile
,
4393 &CLSID_WineTestOld
, 1, { { "CONTENTS", -1, 0, 0, NULL
, 0 } }
4398 { CF_ENHMETAFILE
, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
},
4400 1, 1, &CLSID_Picture_EnhMetafile
,
4402 &CLSID_WineTestOld
, 1, { { "CONTENTS", -1, 0, 0, NULL
, 0 } }
4405 /* static picture clsids without setting any data */
4408 { CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
},
4410 1, 0, &CLSID_Picture_Dib
,
4412 &CLSID_WineTestOld
, 1, { { "CONTENTS", -1, 0, 0, NULL
, 0 } }
4417 { CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
},
4419 1, 0, &CLSID_Picture_Metafile
,
4421 &CLSID_WineTestOld
, 1, { { "CONTENTS", -1, 0, 0, NULL
, 0 } }
4426 { CF_ENHMETAFILE
, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
},
4428 1, 0, &CLSID_Picture_EnhMetafile
,
4430 &CLSID_WineTestOld
, 1, { { "CONTENTS", -1, 0, 0, NULL
, 0 } }
4440 /* test _Save after caching directly through _Cache + _SetData */
4441 for (pdata
= data
; pdata
->clsid
!= NULL
; pdata
++)
4443 hr
= CreateDataCache(NULL
, pdata
->clsid
, &IID_IOleCache2
, (void **)&cache
);
4444 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4446 for (i
= 0; i
< pdata
->num_fmts
; i
++)
4448 hr
= IOleCache2_Cache(cache
, &pdata
->fmts
[i
], 0, &dummy
);
4449 ok(SUCCEEDED(hr
), "unexpected %#x\n", hr
);
4450 if (i
< pdata
->num_set
)
4452 get_stgmedium(pdata
->fmts
[i
].cfFormat
, &stgmeds
[i
]);
4453 get_stgdef(&pdata
->stg_def
, pdata
->fmts
[i
].cfFormat
, &stgmeds
[i
], i
);
4454 hr
= IOleCache2_SetData(cache
, &pdata
->fmts
[i
], &stgmeds
[i
], FALSE
);
4455 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4459 /* create Storage in memory where we'll save cache */
4460 hr
= CreateILockBytesOnHGlobal(0, TRUE
, &ilb
);
4461 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4462 hr
= StgCreateDocfileOnILockBytes(ilb
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &doc
);
4463 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4464 ILockBytes_Release(ilb
);
4465 hr
= IStorage_SetClass(doc
, &CLSID_WineTestOld
);
4466 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4468 hr
= IOleCache2_QueryInterface(cache
, &IID_IPersistStorage
, (void **)&persist
);
4469 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4471 /* cache entries are dirty. test saving them to stg */
4472 trace("IPersistStorage_Save:\n");
4473 hr
= IPersistStorage_Save(persist
, doc
, FALSE
);
4474 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4476 hr
= IPersistStorage_IsDirty(persist
);
4477 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4479 check_storage_contents(doc
, &pdata
->stg_def
, &enumerated_streams
, &matched_streams
);
4480 ok(enumerated_streams
== matched_streams
, "enumerated %d != matched %d\n",
4481 enumerated_streams
, matched_streams
);
4482 ok(enumerated_streams
== pdata
->stg_def
.stream_count
, "created %d != def streams %d\n",
4483 enumerated_streams
, pdata
->stg_def
.stream_count
);
4485 IPersistStorage_Release(persist
);
4486 IOleCache2_Release(cache
);
4488 /* now test _Load/_GetData using the storage we used for _Save */
4489 hr
= CreateDataCache(NULL
, pdata
->clsid
, &IID_IOleCache2
, (void **)&cache
);
4490 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4491 hr
= IOleCache2_QueryInterface(cache
, &IID_IPersistStorage
, (void **)&persist
);
4492 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4494 hr
= IStorage_SetClass(doc
, pdata
->clsid
);
4495 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4496 trace("IPersistStorage_Load\n");
4497 hr
= IPersistStorage_Load(persist
, doc
);
4498 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4500 hr
= IOleCache2_QueryInterface(cache
, &IID_IDataObject
, (void **)&odata
);
4501 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4502 for (i
= 0; i
< pdata
->num_set
; i
++)
4504 hr
= IDataObject_GetData(odata
, &pdata
->fmts
[i
], &stgmed
);
4505 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4507 hr
= stgmedium_cmp(&stgmeds
[i
], &stgmed
);
4508 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4509 ReleaseStgMedium(&stgmed
);
4510 ReleaseStgMedium(&stgmeds
[i
]);
4513 IDataObject_Release(odata
);
4514 IPersistStorage_Release(persist
);
4515 IStorage_Release(doc
);
4516 IOleCache2_Release(cache
);
4517 for (i
= 0; i
< pdata
->num_set
; i
++)
4518 HeapFree(GetProcessHeap(), 0, (void *)pdata
->stg_def
.stream
[i
].data
);
4523 static void test_data_cache_contents(void)
4526 IStorage
*doc1
, *doc2
;
4528 IPersistStorage
*stg
;
4529 int i
, enumerated_streams
, matched_streams
;
4532 const struct storage_def
*in
;
4533 const struct storage_def
*out
;
4536 { &stg_def_0
, &stg_def_0_saved
},
4537 { &stg_def_1
, &stg_def_1_saved
},
4538 { &stg_def_2
, &stg_def_2_saved
},
4539 { &stg_def_3
, &stg_def_3_saved
},
4540 { &stg_def_4
, &stg_def_4_saved
},
4541 { &stg_def_5
, &stg_def_5_saved
},
4542 { &stg_def_6
, &stg_def_6_saved
},
4543 { &stg_def_7
, &stg_def_7_saved
},
4544 { &stg_def_8
, &stg_def_8_saved
},
4545 { &stg_def_9
, &stg_def_9_saved
},
4548 for (i
= 0; i
< sizeof(test_data
)/sizeof(test_data
[0]); i
++)
4550 if (winetest_debug
> 1)
4551 trace("start testing storage def %d\n", i
);
4553 doc1
= create_storage_from_def(test_data
[i
].in
);
4554 if (!doc1
) continue;
4556 enumerated_streams
= matched_streams
= -1;
4557 check_storage_contents(doc1
, test_data
[i
].in
, &enumerated_streams
, &matched_streams
);
4558 ok(enumerated_streams
== matched_streams
, "%d in: enumerated %d != matched %d\n", i
,
4559 enumerated_streams
, matched_streams
);
4560 ok(enumerated_streams
== test_data
[i
].in
->stream_count
, "%d: created %d != def streams %d\n", i
,
4561 enumerated_streams
, test_data
[i
].in
->stream_count
);
4563 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IUnknown
, (void **)&cache
);
4564 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4565 hr
= IOleCache2_QueryInterface(cache
, &IID_IPersistStorage
, (void **)&stg
);
4566 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4567 hr
= IPersistStorage_Load(stg
, doc1
);
4568 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4570 IStorage_Release(doc1
);
4572 hr
= StgCreateDocfile(NULL
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &doc2
);
4573 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4575 hr
= IPersistStorage_IsDirty(stg
);
4576 ok(hr
== S_FALSE
, "%d: unexpected %#x\n", i
, hr
);
4578 hr
= IPersistStorage_Save(stg
, doc2
, FALSE
);
4579 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
4581 IPersistStorage_Release(stg
);
4583 enumerated_streams
= matched_streams
= -1;
4584 check_storage_contents(doc2
, test_data
[i
].out
, &enumerated_streams
, &matched_streams
);
4585 todo_wine_if(!(test_data
[i
].in
== &stg_def_0
|| test_data
[i
].in
== &stg_def_1
|| test_data
[i
].in
== &stg_def_2
))
4586 ok(enumerated_streams
== matched_streams
, "%d out: enumerated %d != matched %d\n", i
,
4587 enumerated_streams
, matched_streams
);
4588 todo_wine_if(!(test_data
[i
].in
== &stg_def_0
|| test_data
[i
].in
== &stg_def_4
|| test_data
[i
].in
== &stg_def_5
4589 || test_data
[i
].in
== &stg_def_6
))
4590 ok(enumerated_streams
== test_data
[i
].out
->stream_count
, "%d: saved streams %d != def streams %d\n", i
,
4591 enumerated_streams
, test_data
[i
].out
->stream_count
);
4593 IStorage_Release(doc2
);
4595 if (winetest_debug
> 1)
4596 trace("done testing storage def %d\n", i
);
4607 cf_test_1
= RegisterClipboardFormatA("cf_winetest_1");
4608 cf_test_2
= RegisterClipboardFormatA("cf_winetest_2");
4609 cf_test_3
= RegisterClipboardFormatA("cf_winetest_3");
4613 hr
= CoRegisterClassObject(&CLSID_Equation3
, (IUnknown
*)&OleObjectCF
, CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, &dwRegister
);
4614 ok_ole_success(hr
, "CoRegisterClassObject");
4616 hr
= StgCreateDocfile(NULL
, STGM_READWRITE
| STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &pStorage
);
4617 ok_ole_success(hr
, "StgCreateDocfile");
4619 test_OleCreate(pStorage
);
4621 hr
= IStorage_Stat(pStorage
, &statstg
, STATFLAG_NONAME
);
4622 ok_ole_success(hr
, "IStorage_Stat");
4623 ok(IsEqualCLSID(&CLSID_Equation3
, &statstg
.clsid
), "Wrong CLSID in storage\n");
4625 test_OleLoad(pStorage
);
4627 IStorage_Release(pStorage
);
4629 hr
= CoRevokeClassObject(dwRegister
);
4630 ok_ole_success(hr
, "CoRevokeClassObject");
4632 Storage_SetClass_CLSID
= &CLSID_WineTest
;
4635 test_data_cache_dib_contents_stream( 0 );
4636 test_data_cache_dib_contents_stream( 1 );
4637 test_data_cache_cache();
4638 test_data_cache_init();
4639 test_data_cache_initnew();
4640 test_data_cache_updatecache();
4641 test_default_handler();
4644 test_OleLockRunning();
4646 test_OleDoAutoConvert();
4647 test_data_cache_save();
4648 test_data_cache_save_data();
4649 test_data_cache_contents();