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
117 static const struct expected_method
*expected_method_list
;
118 static FORMATETC
*g_expected_fetc
= NULL
;
120 static BOOL g_showRunnable
= TRUE
;
121 static BOOL g_isRunning
= TRUE
;
122 static HRESULT g_GetMiscStatusFailsWith
= S_OK
;
123 static HRESULT g_QIFailsWith
;
125 static UINT cf_test_1
, cf_test_2
, cf_test_3
;
127 /****************************************************************************
128 * PresentationDataHeader
130 * This structure represents the header of the \002OlePresXXX stream in
131 * the OLE object storage.
133 typedef struct PresentationDataHeader
136 * - standard clipformat:
137 * DWORD length = 0xffffffff;
139 * - or custom clipformat:
141 * CHAR format_name[length]; (null-terminated)
143 DWORD unknown3
; /* 4, possibly TYMED_ISTREAM */
147 DWORD unknown7
; /* 0 */
148 DWORD dwObjectExtentX
;
149 DWORD dwObjectExtentY
;
151 } PresentationDataHeader
;
153 #define CHECK_EXPECTED_METHOD(method_name) \
155 trace("%s\n", method_name); \
156 ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \
157 if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \
159 todo_wine ok(0, "Too many method calls.\n"); \
162 if (expected_method_list->method) \
164 while (expected_method_list->flags & TEST_OPTIONAL && \
165 strcmp(expected_method_list->method, method_name) != 0) \
166 expected_method_list++; \
167 todo_wine_if (expected_method_list->flags & TEST_TODO) \
168 ok(!strcmp(expected_method_list->method, method_name), \
169 "Expected %s to be called instead of %s\n", \
170 expected_method_list->method, method_name); \
171 expected_method_list++; \
175 #define CHECK_NO_EXTRA_METHODS() \
177 while (expected_method_list->flags & TEST_OPTIONAL) \
178 expected_method_list++; \
179 ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \
182 static HRESULT WINAPI
OleObject_QueryInterface(IOleObject
*iface
, REFIID riid
, void **ppv
)
184 CHECK_EXPECTED_METHOD("OleObject_QueryInterface");
188 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IOleObject
))
190 else if (IsEqualIID(riid
, &IID_IPersistStorage
))
191 *ppv
= &OleObjectPersistStg
;
192 else if (IsEqualIID(riid
, &IID_IOleCache
))
194 else if (IsEqualIID(riid
, &IID_IRunnableObject
) && g_showRunnable
)
196 else if (IsEqualIID(riid
, &IID_WineTest
))
197 return g_QIFailsWith
;
200 IUnknown_AddRef((IUnknown
*)*ppv
);
204 trace("OleObject_QueryInterface: returning E_NOINTERFACE\n");
205 return E_NOINTERFACE
;
208 static ULONG WINAPI
OleObject_AddRef(IOleObject
*iface
)
210 CHECK_EXPECTED_METHOD("OleObject_AddRef");
214 static ULONG WINAPI
OleObject_Release(IOleObject
*iface
)
216 CHECK_EXPECTED_METHOD("OleObject_Release");
220 static HRESULT WINAPI OleObject_SetClientSite
223 IOleClientSite
*pClientSite
226 CHECK_EXPECTED_METHOD("OleObject_SetClientSite");
230 static HRESULT WINAPI OleObject_GetClientSite
233 IOleClientSite
**ppClientSite
236 CHECK_EXPECTED_METHOD("OleObject_GetClientSite");
240 static HRESULT WINAPI OleObject_SetHostNames
243 LPCOLESTR szContainerApp
,
244 LPCOLESTR szContainerObj
247 CHECK_EXPECTED_METHOD("OleObject_SetHostNames");
251 static HRESULT WINAPI OleObject_Close
257 CHECK_EXPECTED_METHOD("OleObject_Close");
261 static HRESULT WINAPI OleObject_SetMoniker
264 DWORD dwWhichMoniker
,
268 CHECK_EXPECTED_METHOD("OleObject_SetMoniker");
272 static HRESULT WINAPI OleObject_GetMoniker
276 DWORD dwWhichMoniker
,
280 CHECK_EXPECTED_METHOD("OleObject_GetMoniker");
284 static HRESULT WINAPI OleObject_InitFromData
287 IDataObject
*pDataObject
,
292 CHECK_EXPECTED_METHOD("OleObject_InitFromData");
296 static HRESULT WINAPI OleObject_GetClipboardData
300 IDataObject
**ppDataObject
303 CHECK_EXPECTED_METHOD("OleObject_GetClipboardData");
307 static HRESULT WINAPI OleObject_DoVerb
312 IOleClientSite
*pActiveSite
,
318 CHECK_EXPECTED_METHOD("OleObject_DoVerb");
322 static HRESULT WINAPI OleObject_EnumVerbs
325 IEnumOLEVERB
**ppEnumOleVerb
328 CHECK_EXPECTED_METHOD("OleObject_EnumVerbs");
332 static HRESULT WINAPI OleObject_Update
337 CHECK_EXPECTED_METHOD("OleObject_Update");
341 static HRESULT WINAPI OleObject_IsUpToDate
346 CHECK_EXPECTED_METHOD("OleObject_IsUpToDate");
350 static HRESULT WINAPI OleObject_GetUserClassID
356 CHECK_EXPECTED_METHOD("OleObject_GetUserClassID");
360 static HRESULT WINAPI OleObject_GetUserType
364 LPOLESTR
*pszUserType
367 CHECK_EXPECTED_METHOD("OleObject_GetUserType");
371 static HRESULT WINAPI OleObject_SetExtent
378 CHECK_EXPECTED_METHOD("OleObject_SetExtent");
382 static HRESULT WINAPI OleObject_GetExtent
389 CHECK_EXPECTED_METHOD("OleObject_GetExtent");
393 static HRESULT WINAPI OleObject_Advise
396 IAdviseSink
*pAdvSink
,
400 CHECK_EXPECTED_METHOD("OleObject_Advise");
404 static HRESULT WINAPI OleObject_Unadvise
410 CHECK_EXPECTED_METHOD("OleObject_Unadvise");
414 static HRESULT WINAPI OleObject_EnumAdvise
417 IEnumSTATDATA
**ppenumAdvise
420 CHECK_EXPECTED_METHOD("OleObject_EnumAdvise");
424 static HRESULT WINAPI OleObject_GetMiscStatus
431 CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus");
433 ok(aspect
== DVASPECT_CONTENT
, "got aspect %d\n", aspect
);
435 if (g_GetMiscStatusFailsWith
== S_OK
)
437 *pdwStatus
= OLEMISC_RECOMPOSEONRESIZE
;
443 return g_GetMiscStatusFailsWith
;
447 static HRESULT WINAPI OleObject_SetColorScheme
453 CHECK_EXPECTED_METHOD("OleObject_SetColorScheme");
457 static const IOleObjectVtbl OleObjectVtbl
=
459 OleObject_QueryInterface
,
462 OleObject_SetClientSite
,
463 OleObject_GetClientSite
,
464 OleObject_SetHostNames
,
466 OleObject_SetMoniker
,
467 OleObject_GetMoniker
,
468 OleObject_InitFromData
,
469 OleObject_GetClipboardData
,
473 OleObject_IsUpToDate
,
474 OleObject_GetUserClassID
,
475 OleObject_GetUserType
,
480 OleObject_EnumAdvise
,
481 OleObject_GetMiscStatus
,
482 OleObject_SetColorScheme
485 static IOleObject OleObject
= { &OleObjectVtbl
};
487 static HRESULT WINAPI
OleObjectPersistStg_QueryInterface(IPersistStorage
*iface
, REFIID riid
, void **ppv
)
489 trace("OleObjectPersistStg_QueryInterface\n");
490 return IOleObject_QueryInterface(&OleObject
, riid
, ppv
);
493 static ULONG WINAPI
OleObjectPersistStg_AddRef(IPersistStorage
*iface
)
495 CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef");
499 static ULONG WINAPI
OleObjectPersistStg_Release(IPersistStorage
*iface
)
501 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release");
505 static HRESULT WINAPI
OleObjectPersistStg_GetClassId(IPersistStorage
*iface
, CLSID
*clsid
)
507 CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId");
511 static HRESULT WINAPI OleObjectPersistStg_IsDirty
513 IPersistStorage
*iface
516 CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty");
520 static HRESULT WINAPI OleObjectPersistStg_InitNew
522 IPersistStorage
*iface
,
526 CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew");
530 static HRESULT WINAPI OleObjectPersistStg_Load
532 IPersistStorage
*iface
,
536 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load");
540 static HRESULT WINAPI OleObjectPersistStg_Save
542 IPersistStorage
*iface
,
547 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save");
551 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted
553 IPersistStorage
*iface
,
557 CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted");
561 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage
563 IPersistStorage
*iface
566 CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage");
570 static const IPersistStorageVtbl OleObjectPersistStgVtbl
=
572 OleObjectPersistStg_QueryInterface
,
573 OleObjectPersistStg_AddRef
,
574 OleObjectPersistStg_Release
,
575 OleObjectPersistStg_GetClassId
,
576 OleObjectPersistStg_IsDirty
,
577 OleObjectPersistStg_InitNew
,
578 OleObjectPersistStg_Load
,
579 OleObjectPersistStg_Save
,
580 OleObjectPersistStg_SaveCompleted
,
581 OleObjectPersistStg_HandsOffStorage
584 static IPersistStorage OleObjectPersistStg
= { &OleObjectPersistStgVtbl
};
586 static HRESULT WINAPI
OleObjectCache_QueryInterface(IOleCache
*iface
, REFIID riid
, void **ppv
)
588 return IOleObject_QueryInterface(&OleObject
, riid
, ppv
);
591 static ULONG WINAPI
OleObjectCache_AddRef(IOleCache
*iface
)
593 CHECK_EXPECTED_METHOD("OleObjectCache_AddRef");
597 static ULONG WINAPI
OleObjectCache_Release(IOleCache
*iface
)
599 CHECK_EXPECTED_METHOD("OleObjectCache_Release");
603 static HRESULT WINAPI OleObjectCache_Cache
606 FORMATETC
*pformatetc
,
611 CHECK_EXPECTED_METHOD("OleObjectCache_Cache");
612 if (g_expected_fetc
) {
613 ok(pformatetc
!= NULL
, "pformatetc should not be NULL\n");
615 ok(pformatetc
->cfFormat
== g_expected_fetc
->cfFormat
,
616 "cfFormat: %x\n", pformatetc
->cfFormat
);
617 ok((pformatetc
->ptd
!= NULL
) == (g_expected_fetc
->ptd
!= NULL
),
618 "ptd: %p\n", pformatetc
->ptd
);
619 ok(pformatetc
->dwAspect
== g_expected_fetc
->dwAspect
,
620 "dwAspect: %x\n", pformatetc
->dwAspect
);
621 ok(pformatetc
->lindex
== g_expected_fetc
->lindex
,
622 "lindex: %x\n", pformatetc
->lindex
);
623 ok(pformatetc
->tymed
== g_expected_fetc
->tymed
,
624 "tymed: %x\n", pformatetc
->tymed
);
627 ok(pformatetc
== NULL
, "pformatetc should be NULL\n");
631 static HRESULT WINAPI OleObjectCache_Uncache
637 CHECK_EXPECTED_METHOD("OleObjectCache_Uncache");
641 static HRESULT WINAPI OleObjectCache_EnumCache
644 IEnumSTATDATA
**ppenumSTATDATA
647 CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache");
652 static HRESULT WINAPI OleObjectCache_InitCache
655 IDataObject
*pDataObject
658 CHECK_EXPECTED_METHOD("OleObjectCache_InitCache");
663 static HRESULT WINAPI OleObjectCache_SetData
666 FORMATETC
*pformatetc
,
671 CHECK_EXPECTED_METHOD("OleObjectCache_SetData");
676 static const IOleCacheVtbl OleObjectCacheVtbl
=
678 OleObjectCache_QueryInterface
,
679 OleObjectCache_AddRef
,
680 OleObjectCache_Release
,
681 OleObjectCache_Cache
,
682 OleObjectCache_Uncache
,
683 OleObjectCache_EnumCache
,
684 OleObjectCache_InitCache
,
685 OleObjectCache_SetData
688 static IOleCache OleObjectCache
= { &OleObjectCacheVtbl
};
690 static HRESULT WINAPI
OleObjectCF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
692 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IClassFactory
))
695 IClassFactory_AddRef(iface
);
699 return E_NOINTERFACE
;
702 static ULONG WINAPI
OleObjectCF_AddRef(IClassFactory
*iface
)
707 static ULONG WINAPI
OleObjectCF_Release(IClassFactory
*iface
)
712 static HRESULT WINAPI
OleObjectCF_CreateInstance(IClassFactory
*iface
, IUnknown
*punkOuter
, REFIID riid
, void **ppv
)
714 return IOleObject_QueryInterface(&OleObject
, riid
, ppv
);
717 static HRESULT WINAPI
OleObjectCF_LockServer(IClassFactory
*iface
, BOOL lock
)
722 static const IClassFactoryVtbl OleObjectCFVtbl
=
724 OleObjectCF_QueryInterface
,
727 OleObjectCF_CreateInstance
,
728 OleObjectCF_LockServer
731 static IClassFactory OleObjectCF
= { &OleObjectCFVtbl
};
733 static HRESULT WINAPI
OleObjectRunnable_QueryInterface(IRunnableObject
*iface
, REFIID riid
, void **ppv
)
735 return IOleObject_QueryInterface(&OleObject
, riid
, ppv
);
738 static ULONG WINAPI
OleObjectRunnable_AddRef(IRunnableObject
*iface
)
740 CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef");
744 static ULONG WINAPI
OleObjectRunnable_Release(IRunnableObject
*iface
)
746 CHECK_EXPECTED_METHOD("OleObjectRunnable_Release");
750 static HRESULT WINAPI
OleObjectRunnable_GetRunningClass(
751 IRunnableObject
*iface
,
754 CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass");
758 static HRESULT WINAPI
OleObjectRunnable_Run(
759 IRunnableObject
*iface
,
762 CHECK_EXPECTED_METHOD("OleObjectRunnable_Run");
766 static BOOL WINAPI
OleObjectRunnable_IsRunning(IRunnableObject
*iface
)
768 CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning");
772 static HRESULT WINAPI
OleObjectRunnable_LockRunning(
773 IRunnableObject
*iface
,
775 BOOL fLastUnlockCloses
)
777 CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning");
781 static HRESULT WINAPI
OleObjectRunnable_SetContainedObject(
782 IRunnableObject
*iface
,
785 CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject");
789 static const IRunnableObjectVtbl OleObjectRunnableVtbl
=
791 OleObjectRunnable_QueryInterface
,
792 OleObjectRunnable_AddRef
,
793 OleObjectRunnable_Release
,
794 OleObjectRunnable_GetRunningClass
,
795 OleObjectRunnable_Run
,
796 OleObjectRunnable_IsRunning
,
797 OleObjectRunnable_LockRunning
,
798 OleObjectRunnable_SetContainedObject
801 static IRunnableObject OleObjectRunnable
= { &OleObjectRunnableVtbl
};
803 static const CLSID CLSID_Equation3
= {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
805 static HRESULT WINAPI
viewobject_QueryInterface(IViewObject
*iface
, REFIID riid
, void **obj
)
807 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IViewObject
))
814 return E_NOINTERFACE
;
817 static ULONG WINAPI
viewobject_AddRef(IViewObject
*iface
)
822 static ULONG WINAPI
viewobject_Release(IViewObject
*iface
)
827 static HRESULT WINAPI
viewobject_Draw(IViewObject
*iface
, DWORD aspect
, LONG index
,
828 void *paspect
, DVTARGETDEVICE
*ptd
, HDC hdcTargetDev
, HDC hdcDraw
,
829 LPCRECTL bounds
, LPCRECTL wbounds
, BOOL (STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
),
830 ULONG_PTR dwContinue
)
832 ok(index
== -1, "index=%d\n", index
);
836 static HRESULT WINAPI
viewobject_GetColorSet(IViewObject
*iface
, DWORD draw_aspect
, LONG index
,
837 void *aspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**colorset
)
839 ok(0, "unexpected call GetColorSet\n");
843 static HRESULT WINAPI
viewobject_Freeze(IViewObject
*iface
, DWORD draw_aspect
, LONG index
,
844 void *aspect
, DWORD
*freeze
)
846 ok(0, "unexpected call Freeze\n");
850 static HRESULT WINAPI
viewobject_Unfreeze(IViewObject
*iface
, DWORD freeze
)
852 ok(0, "unexpected call Unfreeze\n");
856 static HRESULT WINAPI
viewobject_SetAdvise(IViewObject
*iface
, DWORD aspects
, DWORD advf
, IAdviseSink
*sink
)
858 ok(0, "unexpected call SetAdvise\n");
862 static HRESULT WINAPI
viewobject_GetAdvise(IViewObject
*iface
, DWORD
*aspects
, DWORD
*advf
,
865 ok(0, "unexpected call GetAdvise\n");
869 static const struct IViewObjectVtbl viewobjectvtbl
= {
870 viewobject_QueryInterface
,
874 viewobject_GetColorSet
,
877 viewobject_SetAdvise
,
881 static IViewObject viewobject
= { &viewobjectvtbl
};
883 static void test_OleCreate(IStorage
*pStorage
)
888 static const struct expected_method methods_olerender_none
[] =
890 { "OleObject_QueryInterface", 0 },
891 { "OleObject_AddRef", 0 },
892 { "OleObject_QueryInterface", 0 },
893 { "OleObject_AddRef", TEST_OPTIONAL
},
894 { "OleObject_Release", TEST_OPTIONAL
},
895 { "OleObject_QueryInterface", TEST_OPTIONAL
},
896 { "OleObjectPersistStg_AddRef", 0 },
897 { "OleObjectPersistStg_InitNew", 0 },
898 { "OleObjectPersistStg_Release", 0 },
899 { "OleObject_Release", 0 },
900 { "OleObject_Release", TEST_OPTIONAL
},
903 static const struct expected_method methods_olerender_draw
[] =
905 { "OleObject_QueryInterface", 0 },
906 { "OleObject_AddRef", 0 },
907 { "OleObject_QueryInterface", 0 },
908 { "OleObject_AddRef", TEST_OPTIONAL
/* NT4 only */ },
909 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
910 { "OleObject_QueryInterface", TEST_OPTIONAL
/* NT4 only */ },
911 { "OleObjectPersistStg_AddRef", 0 },
912 { "OleObjectPersistStg_InitNew", 0 },
913 { "OleObjectPersistStg_Release", 0 },
914 { "OleObject_QueryInterface", 0 },
915 { "OleObjectRunnable_AddRef", 0 },
916 { "OleObjectRunnable_Run", 0 },
917 { "OleObjectRunnable_Release", 0 },
918 { "OleObject_QueryInterface", 0 },
919 { "OleObjectCache_AddRef", 0 },
920 { "OleObjectCache_Cache", 0 },
921 { "OleObjectCache_Release", 0 },
922 { "OleObject_Release", 0 },
923 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
926 static const struct expected_method methods_olerender_draw_with_site
[] =
928 { "OleObject_QueryInterface", 0 },
929 { "OleObject_AddRef", 0 },
930 { "OleObject_QueryInterface", 0 },
931 { "OleObject_AddRef", 0 },
932 { "OleObject_GetMiscStatus", 0 },
933 { "OleObject_QueryInterface", 0 },
934 { "OleObjectPersistStg_AddRef", 0 },
935 { "OleObjectPersistStg_InitNew", 0 },
936 { "OleObjectPersistStg_Release", 0 },
937 { "OleObject_SetClientSite", 0 },
938 { "OleObject_Release", 0 },
939 { "OleObject_QueryInterface", 0 },
940 { "OleObjectRunnable_AddRef", 0 },
941 { "OleObjectRunnable_Run", 0 },
942 { "OleObjectRunnable_Release", 0 },
943 { "OleObject_QueryInterface", 0 },
944 { "OleObjectCache_AddRef", 0 },
945 { "OleObjectCache_Cache", 0 },
946 { "OleObjectCache_Release", 0 },
947 { "OleObject_Release", 0 },
950 static const struct expected_method methods_olerender_format
[] =
952 { "OleObject_QueryInterface", 0 },
953 { "OleObject_AddRef", 0 },
954 { "OleObject_QueryInterface", 0 },
955 { "OleObject_AddRef", 0 },
956 { "OleObject_GetMiscStatus", 0 },
957 { "OleObject_QueryInterface", 0 },
958 { "OleObjectPersistStg_AddRef", 0 },
959 { "OleObjectPersistStg_InitNew", 0 },
960 { "OleObjectPersistStg_Release", 0 },
961 { "OleObject_SetClientSite", 0 },
962 { "OleObject_Release", 0 },
963 { "OleObject_QueryInterface", 0 },
964 { "OleObjectRunnable_AddRef", 0 },
965 { "OleObjectRunnable_Run", 0 },
966 { "OleObjectRunnable_Release", 0 },
967 { "OleObject_QueryInterface", 0 },
968 { "OleObjectCache_AddRef", 0 },
969 { "OleObjectCache_Cache", 0 },
970 { "OleObjectCache_Release", 0 },
971 { "OleObject_Release", 0 },
974 static const struct expected_method methods_olerender_asis
[] =
976 { "OleObject_QueryInterface", 0 },
977 { "OleObject_AddRef", 0 },
978 { "OleObject_QueryInterface", 0 },
979 { "OleObject_AddRef", TEST_OPTIONAL
/* NT4 only */ },
980 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
981 { "OleObject_QueryInterface", TEST_OPTIONAL
/* NT4 only */ },
982 { "OleObjectPersistStg_AddRef", 0 },
983 { "OleObjectPersistStg_InitNew", 0 },
984 { "OleObjectPersistStg_Release", 0 },
985 { "OleObject_Release", 0 },
986 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
989 static const struct expected_method methods_olerender_draw_no_runnable
[] =
991 { "OleObject_QueryInterface", 0 },
992 { "OleObject_AddRef", 0 },
993 { "OleObject_QueryInterface", 0 },
994 { "OleObject_AddRef", TEST_OPTIONAL
/* NT4 only */ },
995 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
996 { "OleObject_QueryInterface", TEST_OPTIONAL
/* NT4 only */ },
997 { "OleObjectPersistStg_AddRef", 0 },
998 { "OleObjectPersistStg_InitNew", 0 },
999 { "OleObjectPersistStg_Release", 0 },
1000 { "OleObject_QueryInterface", 0 },
1001 { "OleObject_QueryInterface", 0 },
1002 { "OleObjectCache_AddRef", 0 },
1003 { "OleObjectCache_Cache", 0 },
1004 { "OleObjectCache_Release", 0 },
1005 { "OleObject_Release", 0 },
1006 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1009 static const struct expected_method methods_olerender_draw_no_cache
[] =
1011 { "OleObject_QueryInterface", 0 },
1012 { "OleObject_AddRef", 0 },
1013 { "OleObject_QueryInterface", 0 },
1014 { "OleObject_AddRef", TEST_OPTIONAL
/* NT4 only */ },
1015 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1016 { "OleObject_QueryInterface", TEST_OPTIONAL
/* NT4 only */ },
1017 { "OleObjectPersistStg_AddRef", 0 },
1018 { "OleObjectPersistStg_InitNew", 0 },
1019 { "OleObjectPersistStg_Release", 0 },
1020 { "OleObject_QueryInterface", 0 },
1021 { "OleObjectRunnable_AddRef", 0 },
1022 { "OleObjectRunnable_Run", 0 },
1023 { "OleObjectRunnable_Release", 0 },
1024 { "OleObject_QueryInterface", 0 },
1025 { "OleObject_Release", 0 },
1026 { "OleObject_Release", TEST_OPTIONAL
/* NT4 only */ },
1030 g_expected_fetc
= &formatetc
;
1031 formatetc
.cfFormat
= 0;
1032 formatetc
.ptd
= NULL
;
1033 formatetc
.dwAspect
= DVASPECT_CONTENT
;
1034 formatetc
.lindex
= -1;
1035 formatetc
.tymed
= TYMED_NULL
;
1036 runnable
= &OleObjectRunnable
;
1037 cache
= &OleObjectCache
;
1038 expected_method_list
= methods_olerender_none
;
1039 trace("OleCreate with OLERENDER_NONE:\n");
1040 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_NONE
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1041 ok_ole_success(hr
, "OleCreate");
1042 IOleObject_Release(pObject
);
1043 CHECK_NO_EXTRA_METHODS();
1045 expected_method_list
= methods_olerender_draw
;
1046 trace("OleCreate with OLERENDER_DRAW:\n");
1047 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1048 ok_ole_success(hr
, "OleCreate");
1049 IOleObject_Release(pObject
);
1050 CHECK_NO_EXTRA_METHODS();
1052 expected_method_list
= methods_olerender_draw_with_site
;
1053 trace("OleCreate with OLERENDER_DRAW, with site:\n");
1054 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, (IOleClientSite
*)0xdeadbeef, pStorage
, (void **)&pObject
);
1055 ok_ole_success(hr
, "OleCreate");
1056 IOleObject_Release(pObject
);
1057 CHECK_NO_EXTRA_METHODS();
1059 /* GetMiscStatus fails */
1060 g_GetMiscStatusFailsWith
= 0x8fafefaf;
1061 expected_method_list
= methods_olerender_draw_with_site
;
1062 trace("OleCreate with OLERENDER_DRAW, with site:\n");
1063 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, (IOleClientSite
*)0xdeadbeef, pStorage
, (void **)&pObject
);
1064 ok_ole_success(hr
, "OleCreate");
1065 IOleObject_Release(pObject
);
1066 CHECK_NO_EXTRA_METHODS();
1067 g_GetMiscStatusFailsWith
= S_OK
;
1069 formatetc
.cfFormat
= CF_TEXT
;
1070 formatetc
.ptd
= NULL
;
1071 formatetc
.dwAspect
= DVASPECT_CONTENT
;
1072 formatetc
.lindex
= -1;
1073 formatetc
.tymed
= TYMED_HGLOBAL
;
1074 expected_method_list
= methods_olerender_format
;
1075 trace("OleCreate with OLERENDER_FORMAT:\n");
1076 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_FORMAT
, &formatetc
, (IOleClientSite
*)0xdeadbeef, pStorage
, (void **)&pObject
);
1078 broken(hr
== E_INVALIDARG
), /* win2k */
1079 "OleCreate failed with error 0x%08x\n", hr
);
1082 IOleObject_Release(pObject
);
1083 CHECK_NO_EXTRA_METHODS();
1086 expected_method_list
= methods_olerender_asis
;
1087 trace("OleCreate with OLERENDER_ASIS:\n");
1088 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_ASIS
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1089 ok_ole_success(hr
, "OleCreate");
1090 IOleObject_Release(pObject
);
1091 CHECK_NO_EXTRA_METHODS();
1093 formatetc
.cfFormat
= 0;
1094 formatetc
.tymed
= TYMED_NULL
;
1096 expected_method_list
= methods_olerender_draw_no_runnable
;
1097 trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n");
1098 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1099 ok_ole_success(hr
, "OleCreate");
1100 IOleObject_Release(pObject
);
1101 CHECK_NO_EXTRA_METHODS();
1103 runnable
= &OleObjectRunnable
;
1105 expected_method_list
= methods_olerender_draw_no_cache
;
1106 trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n");
1107 hr
= OleCreate(&CLSID_Equation3
, &IID_IOleObject
, OLERENDER_DRAW
, NULL
, NULL
, pStorage
, (void **)&pObject
);
1108 ok_ole_success(hr
, "OleCreate");
1109 IOleObject_Release(pObject
);
1110 CHECK_NO_EXTRA_METHODS();
1112 g_expected_fetc
= NULL
;
1115 static void test_OleLoad(IStorage
*pStorage
)
1118 IOleObject
*pObject
;
1121 static const struct expected_method methods_oleload
[] =
1123 { "OleObject_QueryInterface", 0 },
1124 { "OleObject_AddRef", 0 },
1125 { "OleObject_QueryInterface", 0 },
1126 { "OleObject_AddRef", 0 },
1127 { "OleObject_GetMiscStatus", 0 },
1128 { "OleObject_QueryInterface", 0 },
1129 { "OleObjectPersistStg_AddRef", 0 },
1130 { "OleObjectPersistStg_Load", 0 },
1131 { "OleObjectPersistStg_Release", 0 },
1132 { "OleObject_SetClientSite", 0 },
1133 { "OleObject_Release", 0 },
1134 { "OleObject_QueryInterface", 0 },
1135 { "OleObject_GetMiscStatus", 0 },
1136 { "OleObject_Release", 0 },
1140 /* Test once with IOleObject_GetMiscStatus failing */
1141 expected_method_list
= methods_oleload
;
1142 g_GetMiscStatusFailsWith
= E_FAIL
;
1143 trace("OleLoad:\n");
1144 hr
= OleLoad(pStorage
, &IID_IOleObject
, (IOleClientSite
*)0xdeadbeef, (void **)&pObject
);
1146 broken(hr
== E_INVALIDARG
), /* win98 and win2k */
1147 "OleLoad failed with error 0x%08x\n", hr
);
1150 DWORD dwStatus
= 0xdeadbeef;
1151 hr
= IOleObject_GetMiscStatus(pObject
, DVASPECT_CONTENT
, &dwStatus
);
1152 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
1153 ok(dwStatus
== 0x1234, "Got 0x%08x\n", dwStatus
);
1155 IOleObject_Release(pObject
);
1156 CHECK_NO_EXTRA_METHODS();
1158 g_GetMiscStatusFailsWith
= S_OK
;
1160 /* Test again, let IOleObject_GetMiscStatus succeed. */
1161 expected_method_list
= methods_oleload
;
1162 trace("OleLoad:\n");
1163 hr
= OleLoad(pStorage
, &IID_IOleObject
, (IOleClientSite
*)0xdeadbeef, (void **)&pObject
);
1165 broken(hr
== E_INVALIDARG
), /* win98 and win2k */
1166 "OleLoad failed with error 0x%08x\n", hr
);
1169 DWORD dwStatus
= 0xdeadbeef;
1170 hr
= IOleObject_GetMiscStatus(pObject
, DVASPECT_CONTENT
, &dwStatus
);
1171 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
1172 ok(dwStatus
== 1, "Got 0x%08x\n", dwStatus
);
1174 IOleObject_Release(pObject
);
1175 CHECK_NO_EXTRA_METHODS();
1178 for (fmt
= CF_TEXT
; fmt
< CF_MAX
; fmt
++)
1180 static const WCHAR olrepres
[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 };
1184 DWORD data
, i
, data_size
;
1185 PresentationDataHeader header
;
1191 for (i
= 0; i
< 7; i
++)
1193 hr
= StgCreateDocfile(NULL
, STGM_READWRITE
| STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &stg
);
1194 ok(hr
== S_OK
, "StgCreateDocfile error %#x\n", hr
);
1196 hr
= IStorage_SetClass(stg
, &CLSID_WineTest
);
1197 ok(hr
== S_OK
, "SetClass error %#x\n", hr
);
1199 hr
= IStorage_CreateStream(stg
, olrepres
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
, 0, 0, &stream
);
1200 ok(hr
== S_OK
, "CreateStream error %#x\n", hr
);
1203 hr
= IStream_Write(stream
, &data
, sizeof(data
), NULL
);
1204 ok(hr
== S_OK
, "Write error %#x\n", hr
);
1207 hr
= IStream_Write(stream
, &data
, sizeof(data
), NULL
);
1208 ok(hr
== S_OK
, "Write error %#x\n", hr
);
1213 /* FIXME: figure out stream format */
1214 hobj
= CreateBitmap(1, 1, 1, 1, NULL
);
1215 data_size
= GetBitmapBits(hobj
, sizeof(buf
), buf
);
1219 case CF_METAFILEPICT
:
1220 case CF_ENHMETAFILE
:
1221 hdc
= CreateMetaFileA(NULL
);
1222 hobj
= CloseMetaFile(hdc
);
1223 data_size
= GetMetaFileBitsEx(hobj
, sizeof(buf
), buf
);
1224 DeleteMetaFile(hobj
);
1228 data_size
= sizeof(buf
);
1229 memset(buf
, 'A', sizeof(buf
));
1233 header
.unknown3
= 4;
1234 header
.dvAspect
= DVASPECT_CONTENT
;
1236 header
.advf
= 1 << i
;
1237 header
.unknown7
= 0;
1238 header
.dwObjectExtentX
= 1;
1239 header
.dwObjectExtentY
= 1;
1240 header
.dwSize
= data_size
;
1241 hr
= IStream_Write(stream
, &header
, sizeof(header
), NULL
);
1242 ok(hr
== S_OK
, "Write error %#x\n", hr
);
1244 hr
= IStream_Write(stream
, buf
, data_size
, NULL
);
1245 ok(hr
== S_OK
, "Write error %#x\n", hr
);
1247 IStream_Release(stream
);
1249 hr
= OleLoad(stg
, &IID_IUnknown
, NULL
, (void **)&obj
);
1250 /* FIXME: figure out stream format */
1251 if (fmt
== CF_BITMAP
&& hr
!= S_OK
)
1253 IStorage_Release(stg
);
1256 ok(hr
== S_OK
, "OleLoad error %#x: cfFormat = %u, advf = %#x\n", hr
, fmt
, header
.advf
);
1258 hdc
= CreateCompatibleDC(0);
1259 SetRect(&rc
, 0, 0, 100, 100);
1260 hr
= OleDraw(obj
, DVASPECT_CONTENT
, hdc
, &rc
);
1262 if (fmt
== CF_METAFILEPICT
)
1263 ok(hr
== S_OK
, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr
, fmt
, header
.advf
);
1264 else if (fmt
== CF_ENHMETAFILE
)
1266 ok(hr
== S_OK
, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr
, fmt
, header
.advf
);
1268 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
);
1270 IUnknown_Release(obj
);
1271 IStorage_Release(stg
);
1276 static BOOL STDMETHODCALLTYPE
draw_continue(ULONG_PTR param
)
1278 CHECK_EXPECTED_METHOD("draw_continue");
1282 static BOOL STDMETHODCALLTYPE
draw_continue_false(ULONG_PTR param
)
1284 CHECK_EXPECTED_METHOD("draw_continue_false");
1288 static HRESULT WINAPI
AdviseSink_QueryInterface(IAdviseSink
*iface
, REFIID riid
, void **ppv
)
1290 if (IsEqualIID(riid
, &IID_IAdviseSink
) || IsEqualIID(riid
, &IID_IUnknown
))
1293 IAdviseSink_AddRef(iface
);
1297 return E_NOINTERFACE
;
1300 static ULONG WINAPI
AdviseSink_AddRef(IAdviseSink
*iface
)
1305 static ULONG WINAPI
AdviseSink_Release(IAdviseSink
*iface
)
1311 static void WINAPI
AdviseSink_OnDataChange(
1313 FORMATETC
*pFormatetc
,
1316 CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange");
1319 static void WINAPI
AdviseSink_OnViewChange(
1324 CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange");
1327 static void WINAPI
AdviseSink_OnRename(
1331 CHECK_EXPECTED_METHOD("AdviseSink_OnRename");
1334 static void WINAPI
AdviseSink_OnSave(IAdviseSink
*iface
)
1336 CHECK_EXPECTED_METHOD("AdviseSink_OnSave");
1339 static void WINAPI
AdviseSink_OnClose(IAdviseSink
*iface
)
1341 CHECK_EXPECTED_METHOD("AdviseSink_OnClose");
1344 static const IAdviseSinkVtbl AdviseSinkVtbl
=
1346 AdviseSink_QueryInterface
,
1349 AdviseSink_OnDataChange
,
1350 AdviseSink_OnViewChange
,
1351 AdviseSink_OnRename
,
1356 static IAdviseSink AdviseSink
= { &AdviseSinkVtbl
};
1358 static HRESULT WINAPI
DataObject_QueryInterface(
1363 CHECK_EXPECTED_METHOD("DataObject_QueryInterface");
1365 if (IsEqualIID(riid
, &IID_IDataObject
) || IsEqualIID(riid
, &IID_IUnknown
))
1374 static ULONG WINAPI
DataObject_AddRef(
1377 CHECK_EXPECTED_METHOD("DataObject_AddRef");
1381 static ULONG WINAPI
DataObject_Release(
1384 CHECK_EXPECTED_METHOD("DataObject_Release");
1388 static HRESULT WINAPI
DataObject_GetData(
1390 LPFORMATETC pformatetcIn
,
1393 CHECK_EXPECTED_METHOD("DataObject_GetData");
1397 static HRESULT WINAPI
DataObject_GetDataHere(
1399 LPFORMATETC pformatetc
,
1402 CHECK_EXPECTED_METHOD("DataObject_GetDataHere");
1406 static HRESULT WINAPI
DataObject_QueryGetData(
1408 LPFORMATETC pformatetc
)
1410 CHECK_EXPECTED_METHOD("DataObject_QueryGetData");
1414 static HRESULT WINAPI
DataObject_GetCanonicalFormatEtc(
1416 LPFORMATETC pformatectIn
,
1417 LPFORMATETC pformatetcOut
)
1419 CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc");
1423 static HRESULT WINAPI
DataObject_SetData(
1425 LPFORMATETC pformatetc
,
1429 CHECK_EXPECTED_METHOD("DataObject_SetData");
1433 static HRESULT WINAPI
DataObject_EnumFormatEtc(
1436 IEnumFORMATETC
** ppenumFormatEtc
)
1438 CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc");
1442 static HRESULT WINAPI
DataObject_DAdvise(
1444 FORMATETC
* pformatetc
,
1446 IAdviseSink
* pAdvSink
,
1447 DWORD
* pdwConnection
)
1449 STGMEDIUM stgmedium
;
1451 CHECK_EXPECTED_METHOD("DataObject_DAdvise");
1454 if(advf
& ADVF_PRIMEFIRST
)
1456 ok(pformatetc
->cfFormat
== cf_test_2
, "got %04x\n", pformatetc
->cfFormat
);
1457 stgmedium
.tymed
= TYMED_HGLOBAL
;
1458 U(stgmedium
).hGlobal
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_ZEROINIT
, 4);
1459 stgmedium
.pUnkForRelease
= NULL
;
1460 IAdviseSink_OnDataChange(pAdvSink
, pformatetc
, &stgmedium
);
1466 static HRESULT WINAPI
DataObject_DUnadvise(
1470 CHECK_EXPECTED_METHOD("DataObject_DUnadvise");
1474 static HRESULT WINAPI
DataObject_EnumDAdvise(
1476 IEnumSTATDATA
** ppenumAdvise
)
1478 CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise");
1479 return OLE_E_ADVISENOTSUPPORTED
;
1482 static IDataObjectVtbl DataObjectVtbl
=
1484 DataObject_QueryInterface
,
1488 DataObject_GetDataHere
,
1489 DataObject_QueryGetData
,
1490 DataObject_GetCanonicalFormatEtc
,
1492 DataObject_EnumFormatEtc
,
1494 DataObject_DUnadvise
,
1495 DataObject_EnumDAdvise
1498 static IDataObject DataObject
= { &DataObjectVtbl
};
1500 static HRESULT WINAPI
Unknown_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
1503 if (IsEqualIID(riid
, &IID_IUnknown
)) *ppv
= iface
;
1506 IUnknown_AddRef((IUnknown
*)*ppv
);
1509 return E_NOINTERFACE
;
1512 static ULONG WINAPI
Unknown_AddRef(IUnknown
*iface
)
1517 static ULONG WINAPI
Unknown_Release(IUnknown
*iface
)
1522 static const IUnknownVtbl UnknownVtbl
=
1524 Unknown_QueryInterface
,
1529 static IUnknown unknown
= { &UnknownVtbl
};
1531 static void check_enum_cache(IOleCache2
*cache
, const STATDATA
*expect
, int num
)
1533 IEnumSTATDATA
*enum_stat
;
1537 hr
= IOleCache2_EnumCache( cache
, &enum_stat
);
1538 ok( hr
== S_OK
, "got %08x\n", hr
);
1540 while (IEnumSTATDATA_Next(enum_stat
, 1, &stat
, NULL
) == S_OK
)
1542 ok( stat
.formatetc
.cfFormat
== expect
->formatetc
.cfFormat
, "got %d expect %d\n",
1543 stat
.formatetc
.cfFormat
, expect
->formatetc
.cfFormat
);
1544 ok( !stat
.formatetc
.ptd
== !expect
->formatetc
.ptd
, "got %p expect %p\n",
1545 stat
.formatetc
.ptd
, expect
->formatetc
.ptd
);
1546 ok( stat
.formatetc
.dwAspect
== expect
->formatetc
.dwAspect
, "got %d expect %d\n",
1547 stat
.formatetc
.dwAspect
, expect
->formatetc
.dwAspect
);
1548 ok( stat
.formatetc
.lindex
== expect
->formatetc
.lindex
, "got %d expect %d\n",
1549 stat
.formatetc
.lindex
, expect
->formatetc
.lindex
);
1550 ok( stat
.formatetc
.tymed
== expect
->formatetc
.tymed
, "got %d expect %d\n",
1551 stat
.formatetc
.tymed
, expect
->formatetc
.tymed
);
1552 ok( stat
.advf
== expect
->advf
, "got %d expect %d\n", stat
.advf
, expect
->advf
);
1553 ok( stat
.pAdvSink
== 0, "got %p\n", stat
.pAdvSink
);
1554 ok( stat
.dwConnection
== expect
->dwConnection
, "got %d expect %d\n", stat
.dwConnection
, expect
->dwConnection
);
1559 ok( num
== 0, "incorrect number. num %d\n", num
);
1561 IEnumSTATDATA_Release( enum_stat
);
1564 static void test_data_cache(void)
1567 IOleCache2
*pOleCache
;
1568 IOleCache
*olecache
;
1570 IUnknown
*unk
, *unk2
;
1571 IPersistStorage
*pPS
;
1572 IViewObject
*pViewObject
;
1573 IOleCacheControl
*pOleCacheControl
;
1574 IDataObject
*pCacheDataObject
;
1576 STGMEDIUM stgmedium
;
1582 char szSystemDir
[MAX_PATH
];
1583 WCHAR wszPath
[MAX_PATH
];
1584 static const WCHAR wszShell32
[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0};
1586 static const struct expected_method methods_cacheinitnew
[] =
1588 { "AdviseSink_OnViewChange", 0 },
1589 { "AdviseSink_OnViewChange", 0 },
1590 { "draw_continue", 1 },
1591 { "draw_continue_false", 1 },
1592 { "DataObject_DAdvise", 0 },
1593 { "DataObject_DAdvise", 0 },
1594 { "DataObject_DUnadvise", 0 },
1595 { "DataObject_DUnadvise", 0 },
1598 static const struct expected_method methods_cacheload
[] =
1600 { "AdviseSink_OnViewChange", 0 },
1601 { "draw_continue", 1 },
1602 { "draw_continue", 1 },
1603 { "draw_continue", 1 },
1604 { "DataObject_GetData", 0 },
1605 { "DataObject_GetData", 0 },
1606 { "DataObject_GetData", 0 },
1609 static const struct expected_method methods_cachethenrun
[] =
1611 { "DataObject_DAdvise", 0 },
1612 { "DataObject_DAdvise", 0 },
1613 { "DataObject_DAdvise", 0 },
1614 { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */
1615 { "DataObject_DAdvise", 0 },
1616 { "DataObject_DUnadvise", 0 },
1617 { "DataObject_DUnadvise", 0 },
1618 { "DataObject_DUnadvise", 0 },
1619 { "DataObject_DUnadvise", 0 },
1623 GetSystemDirectoryA(szSystemDir
, sizeof(szSystemDir
)/sizeof(szSystemDir
[0]));
1625 expected_method_list
= methods_cacheinitnew
;
1627 fmtetc
.cfFormat
= CF_METAFILEPICT
;
1628 fmtetc
.dwAspect
= DVASPECT_ICON
;
1631 fmtetc
.tymed
= TYMED_MFPICT
;
1633 hr
= StgCreateDocfile(NULL
, STGM_READWRITE
| STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &pStorage
);
1634 ok_ole_success(hr
, "StgCreateDocfile");
1638 /* requested is not IUnknown */
1639 hr
= CreateDataCache(&unknown
, &CLSID_NULL
, &IID_IOleCache2
, (void**)&pOleCache
);
1640 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1642 hr
= CreateDataCache(&unknown
, &CLSID_NULL
, &IID_IUnknown
, (void**)&unk
);
1643 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1645 hr
= IUnknown_QueryInterface(unk
, &IID_IOleCache
, (void**)&olecache
);
1646 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1647 hr
= IUnknown_QueryInterface(unk
, &IID_IOleCache2
, (void**)&pOleCache
);
1648 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1649 ok(unk
!= (IUnknown
*)olecache
, "got %p, expected %p\n", olecache
, unk
);
1650 ok(unk
!= (IUnknown
*)pOleCache
, "got %p, expected %p\n", pOleCache
, unk
);
1651 IOleCache2_Release(pOleCache
);
1652 IOleCache_Release(olecache
);
1653 IUnknown_Release(unk
);
1655 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IUnknown
, (void**)&unk
);
1656 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1657 hr
= IUnknown_QueryInterface(unk
, &IID_IOleCache
, (void**)&olecache
);
1658 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1659 hr
= IUnknown_QueryInterface(unk
, &IID_IOleCache2
, (void**)&pOleCache
);
1660 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1661 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, (void**)&unk2
);
1662 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1663 ok(unk
== (IUnknown
*)olecache
, "got %p, expected %p\n", olecache
, unk
);
1664 ok(unk
== (IUnknown
*)pOleCache
, "got %p, expected %p\n", pOleCache
, unk
);
1665 ok(unk
== unk2
, "got %p, expected %p\n", unk2
, unk
);
1666 IUnknown_Release(unk2
);
1667 IOleCache2_Release(pOleCache
);
1668 IOleCache_Release(olecache
);
1669 IUnknown_Release(unk
);
1671 /* Test with new data */
1673 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IOleCache2
, (LPVOID
*)&pOleCache
);
1674 ok_ole_success(hr
, "CreateDataCache");
1676 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IPersistStorage
, (LPVOID
*)&pPS
);
1677 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IPersistStorage)");
1678 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IViewObject
, (LPVOID
*)&pViewObject
);
1679 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IViewObject)");
1680 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IOleCacheControl
, (LPVOID
*)&pOleCacheControl
);
1681 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1683 hr
= IViewObject_SetAdvise(pViewObject
, DVASPECT_ICON
, ADVF_PRIMEFIRST
, &AdviseSink
);
1684 ok_ole_success(hr
, "IViewObject_SetAdvise");
1686 hr
= IPersistStorage_InitNew(pPS
, pStorage
);
1687 ok_ole_success(hr
, "IPersistStorage_InitNew");
1689 hr
= IPersistStorage_IsDirty(pPS
);
1690 ok_ole_success(hr
, "IPersistStorage_IsDirty");
1692 hr
= IPersistStorage_GetClassID(pPS
, &clsid
);
1693 ok_ole_success(hr
, "IPersistStorage_GetClassID");
1694 ok(IsEqualCLSID(&clsid
, &IID_NULL
), "clsid should be blank\n");
1696 hr
= IOleCache2_Uncache(pOleCache
, 0xdeadbeef);
1697 ok(hr
== OLE_E_NOCONNECTION
, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr
);
1699 /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */
1700 if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg"))
1702 hr
= IOleCache2_Cache(pOleCache
, NULL
, 0, &dwConnection
);
1703 ok(hr
== E_INVALIDARG
, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1705 hr
= IOleCache2_Cache(pOleCache
, NULL
, 0, NULL
);
1706 ok(hr
== E_INVALIDARG
, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr
);
1710 skip("tests with NULL parameters will crash on NT4 and below\n");
1713 for (fmtetc
.cfFormat
= CF_TEXT
; fmtetc
.cfFormat
< CF_MAX
; fmtetc
.cfFormat
++)
1716 fmtetc
.dwAspect
= DVASPECT_THUMBNAIL
;
1717 for (i
= 0; i
< 7; i
++)
1719 fmtetc
.tymed
= 1 << i
;
1720 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1721 if ((fmtetc
.cfFormat
== CF_METAFILEPICT
&& fmtetc
.tymed
== TYMED_MFPICT
) ||
1722 (fmtetc
.cfFormat
== CF_BITMAP
&& fmtetc
.tymed
== TYMED_GDI
) ||
1723 (fmtetc
.cfFormat
== CF_DIB
&& fmtetc
.tymed
== TYMED_HGLOBAL
) ||
1724 (fmtetc
.cfFormat
== CF_ENHMETAFILE
&& fmtetc
.tymed
== TYMED_ENHMF
))
1725 ok(hr
== S_OK
, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n",
1726 fmtetc
.cfFormat
, fmtetc
.tymed
, hr
);
1727 else if (fmtetc
.tymed
== TYMED_HGLOBAL
)
1728 ok(hr
== CACHE_S_FORMATETC_NOTSUPPORTED
||
1729 broken(hr
== S_OK
&& fmtetc
.cfFormat
== CF_BITMAP
) /* Win9x & NT4 */,
1730 "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n",
1731 fmtetc
.cfFormat
, fmtetc
.tymed
, hr
);
1733 ok(hr
== DV_E_TYMED
, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n",
1734 fmtetc
.cfFormat
, fmtetc
.tymed
, hr
);
1737 hr
= IOleCache2_Uncache(pOleCache
, dwConnection
);
1738 ok_ole_success(hr
, "IOleCache_Uncache");
1743 fmtetc
.cfFormat
= CF_BITMAP
;
1744 fmtetc
.dwAspect
= DVASPECT_THUMBNAIL
;
1745 fmtetc
.tymed
= TYMED_GDI
;
1746 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1747 ok_ole_success(hr
, "IOleCache_Cache");
1749 fmtetc
.cfFormat
= 0;
1750 fmtetc
.dwAspect
= DVASPECT_ICON
;
1751 fmtetc
.tymed
= TYMED_MFPICT
;
1752 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1753 ok_ole_success(hr
, "IOleCache_Cache");
1755 MultiByteToWideChar(CP_ACP
, 0, szSystemDir
, -1, wszPath
, sizeof(wszPath
)/sizeof(wszPath
[0]));
1756 memcpy(wszPath
+lstrlenW(wszPath
), wszShell32
, sizeof(wszShell32
));
1758 fmtetc
.cfFormat
= CF_METAFILEPICT
;
1759 stgmedium
.tymed
= TYMED_MFPICT
;
1760 U(stgmedium
).hMetaFilePict
= OleMetafilePictFromIconAndLabel(
1761 LoadIconA(NULL
, (LPSTR
)IDI_APPLICATION
), wszPath
, wszPath
, 0);
1762 stgmedium
.pUnkForRelease
= NULL
;
1764 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
1765 hr
= IOleCache2_SetData(pOleCache
, &fmtetc
, &stgmedium
, FALSE
);
1766 ok(hr
== OLE_E_BLANK
, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr
);
1768 fmtetc
.dwAspect
= DVASPECT_ICON
;
1769 hr
= IOleCache2_SetData(pOleCache
, &fmtetc
, &stgmedium
, FALSE
);
1770 ok_ole_success(hr
, "IOleCache_SetData");
1771 ReleaseStgMedium(&stgmedium
);
1773 hr
= IViewObject_Freeze(pViewObject
, DVASPECT_ICON
, -1, NULL
, &dwFreeze
);
1775 ok_ole_success(hr
, "IViewObject_Freeze");
1776 hr
= IViewObject_Freeze(pViewObject
, DVASPECT_CONTENT
, -1, NULL
, &dwFreeze
);
1777 ok(hr
== OLE_E_BLANK
, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr
);
1782 rcBounds
.right
= 100;
1783 rcBounds
.bottom
= 100;
1784 hdcMem
= CreateCompatibleDC(NULL
);
1786 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1787 ok_ole_success(hr
, "IViewObject_Draw");
1789 hr
= IViewObject_Draw(pViewObject
, DVASPECT_CONTENT
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1790 ok(hr
== OLE_E_BLANK
, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr
);
1792 /* a NULL draw_continue fn ptr */
1793 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, NULL
, 0xdeadbeef);
1794 ok_ole_success(hr
, "IViewObject_Draw");
1796 /* draw_continue that returns FALSE to abort drawing */
1797 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue_false
, 0xdeadbeef);
1799 broken(hr
== S_OK
), /* win9x may skip the callbacks */
1800 "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr
);
1804 hr
= IOleCacheControl_OnRun(pOleCacheControl
, &DataObject
);
1805 ok_ole_success(hr
, "IOleCacheControl_OnRun");
1807 hr
= IPersistStorage_Save(pPS
, pStorage
, TRUE
);
1808 ok_ole_success(hr
, "IPersistStorage_Save");
1810 hr
= IPersistStorage_SaveCompleted(pPS
, NULL
);
1811 ok_ole_success(hr
, "IPersistStorage_SaveCompleted");
1813 hr
= IPersistStorage_IsDirty(pPS
);
1814 ok(hr
== S_FALSE
, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr
);
1816 IPersistStorage_Release(pPS
);
1817 IViewObject_Release(pViewObject
);
1818 IOleCache2_Release(pOleCache
);
1819 IOleCacheControl_Release(pOleCacheControl
);
1821 CHECK_NO_EXTRA_METHODS();
1823 /* Test with loaded data */
1824 trace("Testing loaded data with CreateDataCache:\n");
1825 expected_method_list
= methods_cacheload
;
1827 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IOleCache2
, (LPVOID
*)&pOleCache
);
1828 ok_ole_success(hr
, "CreateDataCache");
1830 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IPersistStorage
, (LPVOID
*)&pPS
);
1831 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IPersistStorage)");
1832 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IViewObject
, (LPVOID
*)&pViewObject
);
1833 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IViewObject)");
1835 hr
= IViewObject_SetAdvise(pViewObject
, DVASPECT_ICON
, ADVF_PRIMEFIRST
, &AdviseSink
);
1836 ok_ole_success(hr
, "IViewObject_SetAdvise");
1838 hr
= IPersistStorage_Load(pPS
, pStorage
);
1839 ok_ole_success(hr
, "IPersistStorage_Load");
1841 hr
= IPersistStorage_IsDirty(pPS
);
1842 ok(hr
== S_FALSE
, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr
);
1844 fmtetc
.cfFormat
= 0;
1845 fmtetc
.dwAspect
= DVASPECT_ICON
;
1848 fmtetc
.tymed
= TYMED_MFPICT
;
1849 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1850 ok(hr
== CACHE_S_SAMECACHE
, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr
);
1854 rcBounds
.right
= 100;
1855 rcBounds
.bottom
= 100;
1856 hdcMem
= CreateCompatibleDC(NULL
);
1858 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1859 ok_ole_success(hr
, "IViewObject_Draw");
1861 hr
= IViewObject_Draw(pViewObject
, DVASPECT_CONTENT
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1862 ok(hr
== OLE_E_BLANK
, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr
);
1864 /* unload the cached storage object, causing it to be reloaded */
1865 hr
= IOleCache2_DiscardCache(pOleCache
, DISCARDCACHE_NOSAVE
);
1866 ok_ole_success(hr
, "IOleCache2_DiscardCache");
1867 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1868 ok_ole_success(hr
, "IViewObject_Draw");
1870 /* unload the cached storage object, but don't allow it to be reloaded */
1871 hr
= IPersistStorage_HandsOffStorage(pPS
);
1872 ok_ole_success(hr
, "IPersistStorage_HandsOffStorage");
1873 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1874 ok_ole_success(hr
, "IViewObject_Draw");
1875 hr
= IOleCache2_DiscardCache(pOleCache
, DISCARDCACHE_NOSAVE
);
1876 ok_ole_success(hr
, "IOleCache2_DiscardCache");
1877 hr
= IViewObject_Draw(pViewObject
, DVASPECT_ICON
, -1, NULL
, NULL
, NULL
, hdcMem
, &rcBounds
, NULL
, draw_continue
, 0xdeadbeef);
1878 ok(hr
== OLE_E_BLANK
, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr
);
1883 hr
= IOleCache2_InitCache(pOleCache
, &DataObject
);
1884 ok(hr
== CACHE_E_NOCACHE_UPDATED
, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr
);
1887 IPersistStorage_Release(pPS
);
1888 IViewObject_Release(pViewObject
);
1889 IOleCache2_Release(pOleCache
);
1892 CHECK_NO_EXTRA_METHODS();
1895 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IOleCache2
, (LPVOID
*)&pOleCache
);
1896 ok_ole_success(hr
, "CreateDataCache");
1898 expected_method_list
= methods_cachethenrun
;
1900 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IDataObject
, (LPVOID
*)&pCacheDataObject
);
1901 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IDataObject)");
1902 hr
= IOleCache2_QueryInterface(pOleCache
, &IID_IOleCacheControl
, (LPVOID
*)&pOleCacheControl
);
1903 ok_ole_success(hr
, "IOleCache_QueryInterface(IID_IOleCacheControl)");
1905 fmtetc
.cfFormat
= CF_METAFILEPICT
;
1906 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
1907 fmtetc
.tymed
= TYMED_MFPICT
;
1909 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1910 ok_ole_success(hr
, "IOleCache_Cache");
1912 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
1913 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
1915 fmtetc
.cfFormat
= cf_test_1
;
1916 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
1917 fmtetc
.tymed
= TYMED_HGLOBAL
;
1919 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1920 ok(hr
== CACHE_S_FORMATETC_NOTSUPPORTED
, "got %08x\n", hr
);
1922 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
1923 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
1925 fmtetc
.cfFormat
= cf_test_2
;
1926 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, ADVF_PRIMEFIRST
, &dwConnection
);
1927 ok(hr
== CACHE_S_FORMATETC_NOTSUPPORTED
, "got %08x\n", hr
);
1929 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
1930 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
1932 hr
= IOleCacheControl_OnRun(pOleCacheControl
, &DataObject
);
1933 ok_ole_success(hr
, "IOleCacheControl_OnRun");
1935 fmtetc
.cfFormat
= cf_test_3
;
1936 hr
= IOleCache2_Cache(pOleCache
, &fmtetc
, 0, &dwConnection
);
1937 ok(hr
== CACHE_S_FORMATETC_NOTSUPPORTED
, "got %08x\n", hr
);
1939 fmtetc
.cfFormat
= cf_test_1
;
1940 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
1941 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
1943 fmtetc
.cfFormat
= cf_test_2
;
1944 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
1945 ok(hr
== S_OK
, "got %08x\n", hr
);
1946 ReleaseStgMedium(&stgmedium
);
1948 fmtetc
.cfFormat
= cf_test_3
;
1949 hr
= IDataObject_GetData(pCacheDataObject
, &fmtetc
, &stgmedium
);
1950 ok(hr
== OLE_E_BLANK
, "got %08x\n", hr
);
1952 IOleCacheControl_Release(pOleCacheControl
);
1953 IDataObject_Release(pCacheDataObject
);
1954 IOleCache2_Release(pOleCache
);
1956 CHECK_NO_EXTRA_METHODS();
1958 IStorage_Release(pStorage
);
1962 static const WCHAR CONTENTS
[] = {'C','O','N','T','E','N','T','S',0};
1964 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */
1967 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
1968 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
1970 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00,
1971 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
1973 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00,
1974 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
1976 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1977 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1980 static IStorage
*create_storage( int num
)
1987 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg
);
1988 ok( hr
== S_OK
, "got %08x\n", hr
);
1989 hr
= IStorage_SetClass( stg
, &CLSID_Picture_Dib
);
1990 ok( hr
== S_OK
, "got %08x\n", hr
);
1991 hr
= IStorage_CreateStream( stg
, CONTENTS
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
, 0, 0, &stm
);
1992 ok( hr
== S_OK
, "got %08x\n", hr
);
1993 if (num
== 1) /* Set biXPelsPerMeter = 0 */
1998 hr
= IStream_Write( stm
, dib
, sizeof(dib
), &written
);
1999 ok( hr
== S_OK
, "got %08x\n", hr
);
2000 IStream_Release( stm
);
2004 static HGLOBAL
create_dib( void )
2009 h
= GlobalAlloc( GMEM_MOVEABLE
, sizeof(dib
) - sizeof(BITMAPFILEHEADER
) );
2010 ptr
= GlobalLock( h
);
2011 memcpy( ptr
, dib
+ sizeof(BITMAPFILEHEADER
), sizeof(dib
) - sizeof(BITMAPFILEHEADER
) );
2016 static void test_data_cache_dib_contents_stream(int num
)
2020 IPersistStorage
*persist
;
2025 FORMATETC fmt
= {CF_DIB
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
};
2030 BITMAPINFOHEADER expect_info
;
2031 STATDATA enum_expect
[] =
2033 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2034 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2037 hr
= CreateDataCache( NULL
, &CLSID_Picture_Metafile
, &IID_IUnknown
, (void **)&unk
);
2038 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2039 hr
= IUnknown_QueryInterface( unk
, &IID_IPersistStorage
, (void **)&persist
);
2040 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2041 hr
= IUnknown_QueryInterface( unk
, &IID_IDataObject
, (void **)&data
);
2042 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2043 hr
= IUnknown_QueryInterface( unk
, &IID_IViewObject2
, (void **)&view
);
2044 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2045 hr
= IUnknown_QueryInterface( unk
, &IID_IOleCache2
, (void **)&cache
);
2046 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2048 stg
= create_storage( num
);
2050 hr
= IPersistStorage_Load( persist
, stg
);
2051 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2052 IStorage_Release( stg
);
2054 hr
= IPersistStorage_GetClassID( persist
, &cls
);
2055 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2056 ok( IsEqualCLSID( &cls
, &CLSID_Picture_Dib
), "class id mismatch\n" );
2058 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2059 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2060 ok( med
.tymed
== TYMED_HGLOBAL
, "got %x\n", med
.tymed
);
2061 ok( GlobalSize( U(med
).hGlobal
) >= sizeof(dib
) - sizeof(BITMAPFILEHEADER
),
2062 "got %lu\n", GlobalSize( U(med
).hGlobal
) );
2063 ptr
= GlobalLock( U(med
).hGlobal
);
2065 expect_info
= *(BITMAPINFOHEADER
*)(dib
+ sizeof(BITMAPFILEHEADER
));
2066 if (expect_info
.biXPelsPerMeter
== 0 || expect_info
.biYPelsPerMeter
== 0)
2068 HDC hdc
= GetDC( 0 );
2069 expect_info
.biXPelsPerMeter
= MulDiv( GetDeviceCaps( hdc
, LOGPIXELSX
), 10000, 254 );
2070 expect_info
.biYPelsPerMeter
= MulDiv( GetDeviceCaps( hdc
, LOGPIXELSY
), 10000, 254 );
2071 ReleaseDC( 0, hdc
);
2073 ok( !memcmp( ptr
, &expect_info
, sizeof(expect_info
) ), "mismatch\n" );
2074 ok( !memcmp( ptr
+ sizeof(expect_info
), dib
+ sizeof(BITMAPFILEHEADER
) + sizeof(expect_info
),
2075 sizeof(dib
) - sizeof(BITMAPFILEHEADER
) - sizeof(expect_info
) ), "mismatch\n" );
2076 GlobalUnlock( U(med
).hGlobal
);
2077 ReleaseStgMedium( &med
);
2079 check_enum_cache( cache
, enum_expect
, 2 );
2081 hr
= IViewObject2_GetExtent( view
, DVASPECT_CONTENT
, -1, NULL
, &sz
);
2082 ok( SUCCEEDED(hr
), "got %08x\n", hr
);
2085 ok( sz
.cx
== 1000, "got %d\n", sz
.cx
);
2086 ok( sz
.cy
== 250, "got %d\n", sz
.cy
);
2090 HDC hdc
= GetDC( 0 );
2091 LONG x
= 2 * 2540 / GetDeviceCaps( hdc
, LOGPIXELSX
);
2092 LONG y
= 1 * 2540 / GetDeviceCaps( hdc
, LOGPIXELSY
);
2093 ok( sz
.cx
== x
, "got %d %d\n", sz
.cx
, x
);
2094 ok( sz
.cy
== y
, "got %d %d\n", sz
.cy
, y
);
2096 ReleaseDC( 0, hdc
);
2099 IOleCache2_Release( cache
);
2100 IViewObject2_Release( view
);
2101 IDataObject_Release( data
);
2102 IPersistStorage_Release( persist
);
2103 IUnknown_Release( unk
);
2106 static void check_bitmap_size( HBITMAP h
, int cx
, int cy
)
2110 GetObjectW( h
, sizeof(bm
), &bm
);
2111 ok( bm
.bmWidth
== cx
, "got %d expect %d\n", bm
.bmWidth
, cx
);
2112 ok( bm
.bmHeight
== cy
, "got %d expect %d\n", bm
.bmHeight
, cy
);
2115 static void check_dib_size( HGLOBAL h
, int cx
, int cy
)
2119 info
= GlobalLock( h
);
2120 ok( info
->bmiHeader
.biWidth
== cx
, "got %d expect %d\n", info
->bmiHeader
.biWidth
, cx
);
2121 ok( info
->bmiHeader
.biHeight
== cy
, "got %d expect %d\n", info
->bmiHeader
.biHeight
, cy
);
2125 static void test_data_cache_cache(void)
2135 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 0 },
2136 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 0 },
2137 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 0 },
2138 {{ CF_ENHMETAFILE
, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
}, 0, NULL
, 0 }
2140 STATDATA view_caching
[] =
2142 {{ 0, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
}, 0, NULL
, 0 },
2143 {{ 0, 0, DVASPECT_THUMBNAIL
, -1, TYMED_HGLOBAL
}, 0, NULL
, 0 },
2144 {{ 0, 0, DVASPECT_DOCPRINT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 0 },
2145 {{ CF_METAFILEPICT
, 0, DVASPECT_ICON
, -1, TYMED_MFPICT
}, 0, NULL
, 0 }
2148 hr
= CreateDataCache( NULL
, &CLSID_NULL
, &IID_IOleCache2
, (void **)&cache
);
2149 ok( hr
== S_OK
, "got %08x\n", hr
);
2151 /* create a dib entry which will also create a bitmap entry too */
2152 fmt
.cfFormat
= CF_DIB
;
2154 fmt
.dwAspect
= DVASPECT_CONTENT
;
2156 fmt
.tymed
= TYMED_HGLOBAL
;
2158 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2159 ok( hr
== S_OK
, "got %08x\n", hr
);
2160 ok( conn
== 2, "got %d\n", conn
);
2161 expect
[0].dwConnection
= conn
;
2162 expect
[1].dwConnection
= conn
;
2164 check_enum_cache( cache
, expect
, 2 );
2166 /* now try to add a bitmap */
2167 fmt
.cfFormat
= CF_BITMAP
;
2168 fmt
.tymed
= TYMED_GDI
;
2170 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2171 ok( hr
== CACHE_S_SAMECACHE
, "got %08x\n", hr
);
2174 fmt
.cfFormat
= CF_METAFILEPICT
;
2175 fmt
.tymed
= TYMED_MFPICT
;
2177 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2178 ok( hr
== S_OK
, "got %08x\n", hr
);
2179 ok( conn
== 3, "got %d\n", conn
);
2180 expect
[2].dwConnection
= conn
;
2182 check_enum_cache( cache
, expect
, 3);
2185 fmt
.cfFormat
= CF_ENHMETAFILE
;
2186 fmt
.tymed
= TYMED_ENHMF
;
2188 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2189 ok( hr
== S_OK
, "got %08x\n", hr
);
2190 ok( conn
== 4, "got %d\n", conn
);
2191 expect
[3].dwConnection
= conn
;
2193 check_enum_cache( cache
, expect
, 4 );
2195 /* uncache everything */
2196 hr
= IOleCache2_Uncache( cache
, expect
[3].dwConnection
);
2197 ok( hr
== S_OK
, "got %08x\n", hr
);
2198 hr
= IOleCache2_Uncache( cache
, expect
[2].dwConnection
);
2199 ok( hr
== S_OK
, "got %08x\n", hr
);
2200 hr
= IOleCache2_Uncache( cache
, expect
[0].dwConnection
);
2201 ok( hr
== S_OK
, "got %08x\n", hr
);
2202 hr
= IOleCache2_Uncache( cache
, expect
[0].dwConnection
);
2203 ok( hr
== OLE_E_NOCONNECTION
, "got %08x\n", hr
);
2205 check_enum_cache( cache
, expect
, 0 );
2207 /* just create a bitmap entry which again adds both dib and bitmap */
2208 fmt
.cfFormat
= CF_BITMAP
;
2209 fmt
.tymed
= TYMED_GDI
;
2211 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2212 ok( hr
== S_OK
, "got %08x\n", hr
);
2214 expect
[0].dwConnection
= conn
;
2215 expect
[1].dwConnection
= conn
;
2217 check_enum_cache( cache
, expect
, 2 );
2219 /* Try setting a 1x1 bitmap */
2220 hr
= IOleCache2_QueryInterface( cache
, &IID_IDataObject
, (void **) &data
);
2221 ok( hr
== S_OK
, "got %08x\n", hr
);
2223 med
.tymed
= TYMED_GDI
;
2224 U(med
).hBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
2225 med
.pUnkForRelease
= NULL
;
2227 hr
= IOleCache2_SetData( cache
, &fmt
, &med
, TRUE
);
2228 ok( hr
== S_OK
, "got %08x\n", hr
);
2230 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2231 ok( hr
== S_OK
, "got %08x\n", hr
);
2232 ok( med
.tymed
== TYMED_GDI
, "got %d\n", med
.tymed
);
2233 check_bitmap_size( U(med
).hBitmap
, 1, 1 );
2234 ReleaseStgMedium( &med
);
2236 fmt
.cfFormat
= CF_DIB
;
2237 fmt
.tymed
= TYMED_HGLOBAL
;
2238 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2239 ok( hr
== S_OK
, "got %08x\n", hr
);
2240 ok( med
.tymed
== TYMED_HGLOBAL
, "got %d\n", med
.tymed
);
2241 check_dib_size( U(med
).hGlobal
, 1, 1 );
2242 ReleaseStgMedium( &med
);
2244 /* Now set a 2x1 dib */
2245 fmt
.cfFormat
= CF_DIB
;
2246 fmt
.tymed
= TYMED_HGLOBAL
;
2247 med
.tymed
= TYMED_HGLOBAL
;
2248 U(med
).hGlobal
= create_dib();
2250 hr
= IOleCache2_SetData( cache
, &fmt
, &med
, TRUE
);
2251 ok( hr
== S_OK
, "got %08x\n", hr
);
2253 fmt
.cfFormat
= CF_BITMAP
;
2254 fmt
.tymed
= TYMED_GDI
;
2255 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2256 ok( hr
== S_OK
, "got %08x\n", hr
);
2257 ok( med
.tymed
== TYMED_GDI
, "got %d\n", med
.tymed
);
2258 check_bitmap_size( U(med
).hBitmap
, 2, 1 );
2259 ReleaseStgMedium( &med
);
2261 fmt
.cfFormat
= CF_DIB
;
2262 fmt
.tymed
= TYMED_HGLOBAL
;
2263 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2264 ok( hr
== S_OK
, "got %08x\n", hr
);
2265 ok( med
.tymed
== TYMED_HGLOBAL
, "got %d\n", med
.tymed
);
2266 check_dib_size( U(med
).hGlobal
, 2, 1 );
2267 ReleaseStgMedium( &med
);
2269 /* uncache everything */
2270 hr
= IOleCache2_Uncache( cache
, conn
);
2271 ok( hr
== S_OK
, "got %08x\n", hr
);
2275 fmt
.tymed
= TYMED_ENHMF
;
2276 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2277 ok( hr
== S_OK
, "got %08x\n", hr
);
2278 view_caching
[0].dwConnection
= conn
;
2280 fmt
.tymed
= TYMED_HGLOBAL
;
2281 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2282 ok( hr
== CACHE_S_SAMECACHE
, "got %08x\n", hr
);
2284 fmt
.dwAspect
= DVASPECT_THUMBNAIL
;
2285 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2286 ok( hr
== S_OK
, "got %08x\n", hr
);
2287 view_caching
[1].dwConnection
= conn
;
2289 fmt
.dwAspect
= DVASPECT_DOCPRINT
;
2290 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2291 ok( hr
== S_OK
, "got %08x\n", hr
);
2292 view_caching
[2].dwConnection
= conn
;
2294 /* DVASPECT_ICON view cache gets mapped to CF_METAFILEPICT */
2295 fmt
.dwAspect
= DVASPECT_ICON
;
2296 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2297 ok( hr
== S_OK
, "got %08x\n", hr
);
2298 view_caching
[3].dwConnection
= conn
;
2300 check_enum_cache( cache
, view_caching
, 4 );
2302 /* uncache everything */
2303 hr
= IOleCache2_Uncache( cache
, view_caching
[3].dwConnection
);
2304 ok( hr
== S_OK
, "got %08x\n", hr
);
2305 hr
= IOleCache2_Uncache( cache
, view_caching
[2].dwConnection
);
2306 ok( hr
== S_OK
, "got %08x\n", hr
);
2307 hr
= IOleCache2_Uncache( cache
, view_caching
[1].dwConnection
);
2308 ok( hr
== S_OK
, "got %08x\n", hr
);
2309 hr
= IOleCache2_Uncache( cache
, view_caching
[0].dwConnection
);
2310 ok( hr
== S_OK
, "got %08x\n", hr
);
2312 /* Only able to set cfFormat == CF_METAFILEPICT (or == 0, see above) for DVASPECT_ICON */
2313 fmt
.dwAspect
= DVASPECT_ICON
;
2314 fmt
.cfFormat
= CF_DIB
;
2315 fmt
.tymed
= TYMED_HGLOBAL
;
2316 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2317 ok( hr
== DV_E_FORMATETC
, "got %08x\n", hr
);
2318 fmt
.cfFormat
= CF_BITMAP
;
2319 fmt
.tymed
= TYMED_GDI
;
2320 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2321 ok( hr
== DV_E_FORMATETC
, "got %08x\n", hr
);
2322 fmt
.cfFormat
= CF_ENHMETAFILE
;
2323 fmt
.tymed
= TYMED_ENHMF
;
2324 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2325 ok( hr
== DV_E_FORMATETC
, "got %08x\n", hr
);
2326 fmt
.cfFormat
= CF_METAFILEPICT
;
2327 fmt
.tymed
= TYMED_MFPICT
;
2328 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2329 ok( hr
== S_OK
, "got %08x\n", hr
);
2331 /* uncache everything */
2332 hr
= IOleCache2_Uncache( cache
, conn
);
2333 ok( hr
== S_OK
, "got %08x\n", hr
);
2335 IDataObject_Release( data
);
2336 IOleCache2_Release( cache
);
2339 /* The CLSID_Picture_ classes automatically create appropriate cache entries */
2340 static void test_data_cache_init(void)
2344 IPersistStorage
*persist
;
2347 static const STATDATA enum_expect
[] =
2349 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2350 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2351 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 1 },
2352 {{ CF_ENHMETAFILE
, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
}, 0, NULL
, 1 }
2357 int enum_start
, enum_num
;
2360 { &CLSID_NULL
, 0, 0 },
2361 { &CLSID_WineTestOld
, 0, 0 },
2362 { &CLSID_Picture_Dib
, 0, 2 },
2363 { &CLSID_Picture_Metafile
, 2, 1 },
2364 { &CLSID_Picture_EnhMetafile
, 3, 1 }
2367 for (i
= 0; i
< sizeof(data
) / sizeof(data
[0]); i
++)
2369 hr
= CreateDataCache( NULL
, data
[i
].clsid
, &IID_IOleCache2
, (void **)&cache
);
2370 ok( hr
== S_OK
, "got %08x\n", hr
);
2372 check_enum_cache( cache
, enum_expect
+ data
[i
].enum_start
, data
[i
].enum_num
);
2374 IOleCache2_QueryInterface( cache
, &IID_IPersistStorage
, (void **) &persist
);
2375 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2376 ok( hr
== S_OK
, "got %08x\n", hr
);
2377 ok( IsEqualCLSID( &clsid
, data
[i
].clsid
), "class id mismatch %s %s\n", wine_dbgstr_guid( &clsid
),
2378 wine_dbgstr_guid( data
[i
].clsid
) );
2380 IPersistStorage_Release( persist
);
2381 IOleCache2_Release( cache
);
2385 static void test_data_cache_initnew(void)
2389 IPersistStorage
*persist
;
2390 IStorage
*stg_dib
, *stg_mf
, *stg_wine
;
2392 static const STATDATA initnew_expect
[] =
2394 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2395 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2397 static const STATDATA initnew2_expect
[] =
2399 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 1 },
2400 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 2 },
2401 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 2 },
2403 static const STATDATA initnew3_expect
[] =
2405 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2406 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2407 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 2 },
2408 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 2 },
2409 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 3 },
2411 static const STATDATA initnew4_expect
[] =
2413 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 2 },
2414 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 2 },
2415 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 3 },
2416 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 4 },
2417 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 4 },
2420 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg_dib
);
2421 ok( hr
== S_OK
, "got %08x\n", hr
);
2422 hr
= IStorage_SetClass( stg_dib
, &CLSID_Picture_Dib
);
2423 ok( hr
== S_OK
, "got %08x\n", hr
);
2425 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg_mf
);
2426 ok( hr
== S_OK
, "got %08x\n", hr
);
2427 hr
= IStorage_SetClass( stg_mf
, &CLSID_Picture_Metafile
);
2428 ok( hr
== S_OK
, "got %08x\n", hr
);
2430 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg_wine
);
2431 ok( hr
== S_OK
, "got %08x\n", hr
);
2432 hr
= IStorage_SetClass( stg_wine
, &CLSID_WineTestOld
);
2433 ok( hr
== S_OK
, "got %08x\n", hr
);
2435 hr
= CreateDataCache( NULL
, &CLSID_WineTestOld
, &IID_IOleCache2
, (void **)&cache
);
2436 ok( hr
== S_OK
, "got %08x\n", hr
);
2437 IOleCache2_QueryInterface( cache
, &IID_IPersistStorage
, (void **) &persist
);
2439 hr
= IPersistStorage_InitNew( persist
, stg_dib
);
2440 ok( hr
== S_OK
, "got %08x\n", hr
);
2442 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2443 ok( hr
== S_OK
, "got %08x\n", hr
);
2444 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Dib
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2446 check_enum_cache( cache
, initnew_expect
, 2 );
2448 hr
= IPersistStorage_InitNew( persist
, stg_mf
);
2449 ok( hr
== CO_E_ALREADYINITIALIZED
, "got %08x\n", hr
);
2451 hr
= IPersistStorage_HandsOffStorage( persist
);
2452 ok( hr
== S_OK
, "got %08x\n", hr
);
2454 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2455 ok( hr
== S_OK
, "got %08x\n", hr
);
2456 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Dib
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2458 hr
= IPersistStorage_InitNew( persist
, stg_mf
);
2459 ok( hr
== S_OK
, "got %08x\n", hr
);
2461 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2462 ok( hr
== S_OK
, "got %08x\n", hr
);
2463 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Metafile
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2465 check_enum_cache( cache
, initnew2_expect
, 3 );
2467 hr
= IPersistStorage_HandsOffStorage( persist
);
2468 ok( hr
== S_OK
, "got %08x\n", hr
);
2470 hr
= IPersistStorage_InitNew( persist
, stg_dib
);
2471 ok( hr
== S_OK
, "got %08x\n", hr
);
2473 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2474 ok( hr
== S_OK
, "got %08x\n", hr
);
2475 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Dib
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2477 check_enum_cache( cache
, initnew3_expect
, 5 );
2479 hr
= IPersistStorage_HandsOffStorage( persist
);
2480 ok( hr
== S_OK
, "got %08x\n", hr
);
2482 hr
= IPersistStorage_InitNew( persist
, stg_wine
);
2483 ok( hr
== S_OK
, "got %08x\n", hr
);
2485 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2486 ok( hr
== S_OK
, "got %08x\n", hr
);
2487 ok( IsEqualCLSID( &clsid
, &CLSID_WineTestOld
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2489 check_enum_cache( cache
, initnew4_expect
, 5 );
2491 IStorage_Release( stg_wine
);
2492 IStorage_Release( stg_mf
);
2493 IStorage_Release( stg_dib
);
2495 IPersistStorage_Release( persist
);
2496 IOleCache2_Release( cache
);
2499 static void test_default_handler(void)
2502 IOleObject
*pObject
;
2503 IRunnableObject
*pRunnableObject
;
2504 IOleClientSite
*pClientSite
;
2505 IDataObject
*pDataObject
;
2509 LPOLESTR pszUserType
;
2514 IOleInPlaceObject
*pInPlaceObj
;
2515 IEnumOLEVERB
*pEnumVerbs
;
2517 static const WCHAR wszUnknown
[] = {'U','n','k','n','o','w','n',0};
2518 static const WCHAR wszHostName
[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
2519 static const WCHAR wszDelim
[] = {'!',0};
2521 static const struct expected_method methods_embeddinghelper
[] =
2523 { "OleObject_QueryInterface", 0 },
2524 { "OleObject_AddRef", 0 },
2525 { "OleObject_QueryInterface", 0 },
2526 { "OleObject_QueryInterface", TEST_TODO
},
2527 { "OleObject_QueryInterface", 0 },
2528 { "OleObject_QueryInterface", 0 },
2529 { "OleObject_QueryInterface", TEST_OPTIONAL
}, /* Win95/98/NT4 */
2530 { "OleObject_Release", TEST_TODO
},
2531 { "WINE_EXTRA", TEST_OPTIONAL
},
2535 hr
= CoCreateInstance(&CLSID_WineTest
, NULL
, CLSCTX_INPROC_HANDLER
, &IID_IOleObject
, (void **)&pObject
);
2536 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2538 hr
= OleCreateDefaultHandler(&CLSID_WineTest
, NULL
, &IID_IOleObject
, (void **)&pObject
);
2539 ok_ole_success(hr
, "OleCreateDefaultHandler");
2541 hr
= IOleObject_QueryInterface(pObject
, &IID_IOleInPlaceObject
, (void **)&pInPlaceObj
);
2542 ok(hr
== E_NOINTERFACE
, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr
);
2544 hr
= IOleObject_Advise(pObject
, &AdviseSink
, &dwAdvConn
);
2545 ok_ole_success(hr
, "IOleObject_Advise");
2547 hr
= IOleObject_Close(pObject
, OLECLOSE_NOSAVE
);
2548 ok_ole_success(hr
, "IOleObject_Close");
2550 /* FIXME: test IOleObject_EnumAdvise */
2552 hr
= IOleObject_EnumVerbs(pObject
, &pEnumVerbs
);
2553 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2555 hr
= IOleObject_GetClientSite(pObject
, &pClientSite
);
2556 ok_ole_success(hr
, "IOleObject_GetClientSite");
2558 hr
= IOleObject_SetClientSite(pObject
, pClientSite
);
2559 ok_ole_success(hr
, "IOleObject_SetClientSite");
2561 hr
= IOleObject_GetClipboardData(pObject
, 0, &pDataObject
);
2562 ok(hr
== OLE_E_NOTRUNNING
,
2563 "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
2566 hr
= IOleObject_GetExtent(pObject
, DVASPECT_CONTENT
, &sizel
);
2567 ok(hr
== OLE_E_BLANK
, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
2570 hr
= IOleObject_GetMiscStatus(pObject
, DVASPECT_CONTENT
, &dwStatus
);
2571 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2573 hr
= IOleObject_GetUserClassID(pObject
, &clsid
);
2574 ok_ole_success(hr
, "IOleObject_GetUserClassID");
2575 ok(IsEqualCLSID(&clsid
, &CLSID_WineTest
), "clsid != CLSID_WineTest\n");
2577 hr
= IOleObject_GetUserType(pObject
, USERCLASSTYPE_FULL
, &pszUserType
);
2579 ok_ole_success(hr
, "IOleObject_GetUserType");
2580 ok(!lstrcmpW(pszUserType
, wszUnknown
), "Retrieved user type was wrong\n");
2583 hr
= IOleObject_InitFromData(pObject
, NULL
, TRUE
, 0);
2584 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2586 hr
= IOleObject_IsUpToDate(pObject
);
2587 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2589 palette
.palNumEntries
= 1;
2590 palette
.palVersion
= 2;
2591 memset(&palette
.palPalEntry
[0], 0, sizeof(palette
.palPalEntry
[0]));
2592 hr
= IOleObject_SetColorScheme(pObject
, &palette
);
2593 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2595 sizel
.cx
= sizel
.cy
= 0;
2596 hr
= IOleObject_SetExtent(pObject
, DVASPECT_CONTENT
, &sizel
);
2597 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2599 hr
= IOleObject_SetHostNames(pObject
, wszHostName
, NULL
);
2600 ok_ole_success(hr
, "IOleObject_SetHostNames");
2602 hr
= CreateItemMoniker(wszDelim
, wszHostName
, &pMoniker
);
2603 ok_ole_success(hr
, "CreateItemMoniker");
2604 hr
= IOleObject_SetMoniker(pObject
, OLEWHICHMK_CONTAINER
, pMoniker
);
2605 ok_ole_success(hr
, "IOleObject_SetMoniker");
2606 IMoniker_Release(pMoniker
);
2608 hr
= IOleObject_GetMoniker(pObject
, OLEGETMONIKER_ONLYIFTHERE
, OLEWHICHMK_CONTAINER
, &pMoniker
);
2609 ok(hr
== E_FAIL
, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr
);
2611 hr
= IOleObject_Update(pObject
);
2613 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2615 hr
= IOleObject_QueryInterface(pObject
, &IID_IDataObject
, (void **)&pDataObject
);
2616 ok_ole_success(hr
, "IOleObject_QueryInterface");
2618 fmtetc
.cfFormat
= CF_TEXT
;
2620 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2622 fmtetc
.tymed
= TYMED_NULL
;
2623 hr
= IDataObject_DAdvise(pDataObject
, &fmtetc
, 0, &AdviseSink
, &dwAdvConn
);
2624 ok_ole_success(hr
, "IDataObject_DAdvise");
2626 fmtetc
.cfFormat
= CF_ENHMETAFILE
;
2628 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2630 fmtetc
.tymed
= TYMED_ENHMF
;
2631 hr
= IDataObject_DAdvise(pDataObject
, &fmtetc
, 0, &AdviseSink
, &dwAdvConn
);
2632 ok_ole_success(hr
, "IDataObject_DAdvise");
2634 fmtetc
.cfFormat
= CF_ENHMETAFILE
;
2636 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2638 fmtetc
.tymed
= TYMED_ENHMF
;
2639 hr
= IDataObject_QueryGetData(pDataObject
, &fmtetc
);
2640 ok(hr
== OLE_E_NOTRUNNING
, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2642 fmtetc
.cfFormat
= CF_TEXT
;
2644 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2646 fmtetc
.tymed
= TYMED_NULL
;
2647 hr
= IDataObject_QueryGetData(pDataObject
, &fmtetc
);
2648 ok(hr
== OLE_E_NOTRUNNING
, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2650 hr
= IOleObject_QueryInterface(pObject
, &IID_IRunnableObject
, (void **)&pRunnableObject
);
2651 ok_ole_success(hr
, "IOleObject_QueryInterface");
2653 hr
= IRunnableObject_SetContainedObject(pRunnableObject
, TRUE
);
2654 ok_ole_success(hr
, "IRunnableObject_SetContainedObject");
2656 hr
= IRunnableObject_Run(pRunnableObject
, NULL
);
2657 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2659 hr
= IOleObject_Close(pObject
, OLECLOSE_NOSAVE
);
2660 ok_ole_success(hr
, "IOleObject_Close");
2662 IRunnableObject_Release(pRunnableObject
);
2663 IOleObject_Release(pObject
);
2665 /* Test failure propagation from delegate ::QueryInterface */
2666 hr
= CoRegisterClassObject(&CLSID_WineTest
, (IUnknown
*)&OleObjectCF
,
2667 CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, &dwRegister
);
2668 ok_ole_success(hr
, "CoRegisterClassObject");
2671 expected_method_list
= methods_embeddinghelper
;
2672 hr
= OleCreateEmbeddingHelper(&CLSID_WineTest
, NULL
, EMBDHLP_INPROC_SERVER
,
2673 &OleObjectCF
, &IID_IOleObject
, (void**)&pObject
);
2674 ok_ole_success(hr
, "OleCreateEmbeddingHelper");
2679 g_QIFailsWith
= E_FAIL
;
2680 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
2681 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
2683 g_QIFailsWith
= E_NOINTERFACE
;
2684 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
2685 ok(hr
== E_NOINTERFACE
, "Got 0x%08x\n", hr
);
2687 g_QIFailsWith
= CO_E_OBJNOTCONNECTED
;
2688 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
2689 ok(hr
== CO_E_OBJNOTCONNECTED
, "Got 0x%08x\n", hr
);
2691 g_QIFailsWith
= 0x87654321;
2692 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
2693 ok(hr
== 0x87654321, "Got 0x%08x\n", hr
);
2695 IOleObject_Release(pObject
);
2698 CHECK_NO_EXTRA_METHODS();
2700 hr
= CoRevokeClassObject(dwRegister
);
2701 ok_ole_success(hr
, "CoRevokeClassObject");
2705 static void test_runnable(void)
2707 static const struct expected_method methods_query_runnable
[] =
2709 { "OleObject_QueryInterface", 0 },
2710 { "OleObjectRunnable_AddRef", 0 },
2711 { "OleObjectRunnable_IsRunning", 0 },
2712 { "OleObjectRunnable_Release", 0 },
2716 static const struct expected_method methods_no_runnable
[] =
2718 { "OleObject_QueryInterface", 0 },
2723 IOleObject
*object
= &OleObject
;
2726 ret
= OleIsRunning(NULL
);
2727 ok(ret
== FALSE
, "got %d\n", ret
);
2729 expected_method_list
= methods_query_runnable
;
2730 ret
= OleIsRunning(object
);
2731 ok(ret
== TRUE
, "Object should be running\n");
2732 CHECK_NO_EXTRA_METHODS();
2734 g_isRunning
= FALSE
;
2735 expected_method_list
= methods_query_runnable
;
2736 ret
= OleIsRunning(object
);
2737 ok(ret
== FALSE
, "Object should not be running\n");
2738 CHECK_NO_EXTRA_METHODS();
2740 g_showRunnable
= FALSE
; /* QueryInterface(IID_IRunnableObject, ...) will fail */
2741 expected_method_list
= methods_no_runnable
;
2742 ret
= OleIsRunning(object
);
2743 ok(ret
== TRUE
, "Object without IRunnableObject should be running\n");
2744 CHECK_NO_EXTRA_METHODS();
2747 g_showRunnable
= TRUE
;
2751 static HRESULT WINAPI
OleRun_QueryInterface(IRunnableObject
*iface
, REFIID riid
, void **ppv
)
2755 if (IsEqualIID(riid
, &IID_IUnknown
) ||
2756 IsEqualIID(riid
, &IID_IRunnableObject
)) {
2762 IUnknown_AddRef((IUnknown
*)*ppv
);
2766 return E_NOINTERFACE
;
2769 static ULONG WINAPI
OleRun_AddRef(IRunnableObject
*iface
)
2774 static ULONG WINAPI
OleRun_Release(IRunnableObject
*iface
)
2779 static HRESULT WINAPI
OleRun_GetRunningClass(IRunnableObject
*iface
, CLSID
*clsid
)
2781 ok(0, "unexpected\n");
2785 static HRESULT WINAPI
OleRun_Run(IRunnableObject
*iface
, LPBINDCTX ctx
)
2787 ok(ctx
== NULL
, "got %p\n", ctx
);
2791 static BOOL WINAPI
OleRun_IsRunning(IRunnableObject
*iface
)
2793 ok(0, "unexpected\n");
2797 static HRESULT WINAPI
OleRun_LockRunning(IRunnableObject
*iface
, BOOL lock
,
2798 BOOL last_unlock_closes
)
2800 ok(0, "unexpected\n");
2804 static HRESULT WINAPI
OleRun_SetContainedObject(IRunnableObject
*iface
, BOOL contained
)
2806 ok(0, "unexpected\n");
2810 static const IRunnableObjectVtbl oleruntestvtbl
=
2812 OleRun_QueryInterface
,
2815 OleRun_GetRunningClass
,
2819 OleRun_SetContainedObject
2822 static IRunnableObject testrunnable
= { &oleruntestvtbl
};
2824 static void test_OleRun(void)
2828 /* doesn't support IRunnableObject */
2829 hr
= OleRun(&unknown
);
2830 ok(hr
== S_OK
, "OleRun failed 0x%08x\n", hr
);
2832 hr
= OleRun((IUnknown
*)&testrunnable
);
2833 ok(hr
== 0xdeadc0de, "got 0x%08x\n", hr
);
2836 static void test_OleLockRunning(void)
2840 hr
= OleLockRunning(&unknown
, TRUE
, FALSE
);
2841 ok(hr
== S_OK
, "OleLockRunning failed 0x%08x\n", hr
);
2844 static void test_OleDraw(void)
2849 hr
= OleDraw((IUnknown
*)&viewobject
, 0, (HDC
)0x1, NULL
);
2850 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2852 hr
= OleDraw(NULL
, 0, (HDC
)0x1, NULL
);
2853 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2855 hr
= OleDraw(NULL
, 0, (HDC
)0x1, &rect
);
2856 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2859 static const WCHAR olepres0W
[] = {2,'O','l','e','P','r','e','s','0','0','0',0};
2860 static const WCHAR comp_objW
[] = {1,'C','o','m','p','O','b','j',0};
2861 static IStream
*comp_obj_stream
;
2862 static IStream
*ole_stream
;
2863 static IStream
*olepres_stream
;
2864 static IStream
*contents_stream
;
2866 static HRESULT WINAPI
Storage_QueryInterface(IStorage
*iface
, REFIID riid
, void **ppvObject
)
2868 ok(0, "unexpected call to QueryInterface\n");
2872 static ULONG WINAPI
Storage_AddRef(IStorage
*iface
)
2874 ok(0, "unexpected call to AddRef\n");
2878 static ULONG WINAPI
Storage_Release(IStorage
*iface
)
2880 ok(0, "unexpected call to Release\n");
2884 static HRESULT WINAPI
Storage_CreateStream(IStorage
*iface
, LPCOLESTR pwcsName
, DWORD grfMode
, DWORD reserved1
, DWORD reserved2
, IStream
**ppstm
)
2886 ULARGE_INTEGER size
= {{0}};
2887 LARGE_INTEGER pos
= {{0}};
2890 if (!lstrcmpW(pwcsName
, comp_objW
))
2892 CHECK_EXPECT(Storage_CreateStream_CompObj
);
2893 *ppstm
= comp_obj_stream
;
2895 todo_wine
ok(grfMode
== (STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
2897 else if (!lstrcmpW(pwcsName
, olepres0W
))
2899 CHECK_EXPECT(Storage_CreateStream_OlePres
);
2900 *ppstm
= olepres_stream
;
2902 todo_wine
ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
2907 ok(0, "unexpected stream name %s\n", wine_dbgstr_w(pwcsName
));
2908 #if 0 /* FIXME: return NULL once Wine is fixed */
2912 *ppstm
= contents_stream
;
2916 ok(!reserved1
, "reserved1 = %x\n", reserved1
);
2917 ok(!reserved2
, "reserved2 = %x\n", reserved2
);
2918 ok(!!ppstm
, "ppstm = NULL\n");
2920 IStream_AddRef(*ppstm
);
2921 hr
= IStream_Seek(*ppstm
, pos
, STREAM_SEEK_SET
, NULL
);
2922 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
2923 hr
= IStream_SetSize(*ppstm
, size
);
2924 ok(hr
== S_OK
, "IStream_SetSize returned %x\n", hr
);
2928 static HRESULT WINAPI
Storage_OpenStream(IStorage
*iface
, LPCOLESTR pwcsName
, void *reserved1
, DWORD grfMode
, DWORD reserved2
, IStream
**ppstm
)
2930 static const WCHAR ole1W
[] = {1,'O','l','e',0};
2932 LARGE_INTEGER pos
= {{0}};
2935 ok(!reserved1
, "reserved1 = %p\n", reserved1
);
2936 ok(!reserved2
, "reserved2 = %x\n", reserved2
);
2937 ok(!!ppstm
, "ppstm = NULL\n");
2939 if(!lstrcmpW(pwcsName
, comp_objW
)) {
2940 CHECK_EXPECT2(Storage_OpenStream_CompObj
);
2941 ok(grfMode
== STGM_SHARE_EXCLUSIVE
, "grfMode = %x\n", grfMode
);
2943 *ppstm
= comp_obj_stream
;
2944 IStream_AddRef(comp_obj_stream
);
2945 hr
= IStream_Seek(comp_obj_stream
, pos
, STREAM_SEEK_SET
, NULL
);
2946 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
2948 }else if(!lstrcmpW(pwcsName
, ole1W
)) {
2949 CHECK_EXPECT(Storage_OpenStream_Ole
);
2953 ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READ
), "grfMode = %x\n", grfMode
);
2956 return STG_E_FILENOTFOUND
;
2959 ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
2961 *ppstm
= ole_stream
;
2962 IStream_AddRef(ole_stream
);
2963 hr
= IStream_Seek(ole_stream
, pos
, STREAM_SEEK_SET
, NULL
);
2964 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
2967 }else if(!lstrcmpW(pwcsName
, olepres0W
)) {
2968 CHECK_EXPECT(Storage_OpenStream_OlePres
);
2969 ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
2971 *ppstm
= olepres_stream
;
2972 IStream_AddRef(olepres_stream
);
2973 hr
= IStream_Seek(olepres_stream
, pos
, STREAM_SEEK_SET
, NULL
);
2974 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
2978 ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName
));
2982 static HRESULT WINAPI
Storage_CreateStorage(IStorage
*iface
, LPCOLESTR pwcsName
, DWORD grfMode
, DWORD dwStgFmt
, DWORD reserved2
, IStorage
**ppstg
)
2984 ok(0, "unexpected call to CreateStorage\n");
2988 static HRESULT WINAPI
Storage_OpenStorage(IStorage
*iface
, LPCOLESTR pwcsName
, IStorage
*pstgPriority
, DWORD grfMode
, SNB snbExclude
, DWORD reserved
, IStorage
**ppstg
)
2990 ok(0, "unexpected call to OpenStorage\n");
2994 static HRESULT WINAPI
Storage_CopyTo(IStorage
*iface
, DWORD ciidExclude
, const IID
*rgiidExclude
, SNB snbExclude
, IStorage
*pstgDest
)
2996 ok(0, "unexpected call to CopyTo\n");
3000 static HRESULT WINAPI
Storage_MoveElementTo(IStorage
*iface
, LPCOLESTR pwcsName
, IStorage
*pstgDest
, LPCOLESTR pwcsNewName
, DWORD grfFlags
)
3002 ok(0, "unexpected call to MoveElementTo\n");
3006 static HRESULT WINAPI
Storage_Commit(IStorage
*iface
, DWORD grfCommitFlags
)
3008 ok(0, "unexpected call to Commit\n");
3012 static HRESULT WINAPI
Storage_Revert(IStorage
*iface
)
3014 ok(0, "unexpected call to Revert\n");
3018 static HRESULT WINAPI
Storage_EnumElements(IStorage
*iface
, DWORD reserved1
, void *reserved2
, DWORD reserved3
, IEnumSTATSTG
**ppenum
)
3020 ok(0, "unexpected call to EnumElements\n");
3024 static HRESULT WINAPI
Storage_DestroyElement(IStorage
*iface
, LPCOLESTR pwcsName
)
3029 CHECK_EXPECT2(Storage_DestroyElement
);
3030 cmp
= CompareStringW(LOCALE_NEUTRAL
, 0, pwcsName
, 8, olepres0W
, 8);
3031 ok(cmp
== CSTR_EQUAL
,
3032 "unexpected call to DestroyElement(%s)\n", wine_dbgstr_w(pwcsName
));
3034 WideCharToMultiByte(CP_ACP
, 0, pwcsName
, -1, name
, sizeof(name
), NULL
, NULL
);
3035 stream_n
= atol(name
+ 8);
3036 if (stream_n
<= Storage_DestroyElement_limit
)
3039 return STG_E_FILENOTFOUND
;
3042 static HRESULT WINAPI
Storage_RenameElement(IStorage
*iface
, LPCOLESTR pwcsOldName
, LPCOLESTR pwcsNewName
)
3044 ok(0, "unexpected call to RenameElement\n");
3048 static HRESULT WINAPI
Storage_SetElementTimes(IStorage
*iface
, LPCOLESTR pwcsName
, const FILETIME
*pctime
, const FILETIME
*patime
, const FILETIME
*pmtime
)
3050 ok(0, "unexpected call to SetElementTimes\n");
3054 static HRESULT WINAPI
Storage_SetClass(IStorage
*iface
, REFCLSID clsid
)
3056 CHECK_EXPECT(Storage_SetClass
);
3057 ok(IsEqualIID(clsid
, Storage_SetClass_CLSID
), "expected %s, got %s\n",
3058 wine_dbgstr_guid(Storage_SetClass_CLSID
), wine_dbgstr_guid(clsid
));
3062 static HRESULT WINAPI
Storage_SetStateBits(IStorage
*iface
, DWORD grfStateBits
, DWORD grfMask
)
3064 ok(0, "unexpected call to SetStateBits\n");
3068 static HRESULT WINAPI
Storage_Stat(IStorage
*iface
, STATSTG
*pstatstg
, DWORD grfStatFlag
)
3070 CHECK_EXPECT2(Storage_Stat
);
3071 ok(pstatstg
!= NULL
, "pstatstg = NULL\n");
3072 ok(grfStatFlag
== STATFLAG_NONAME
, "grfStatFlag = %x\n", grfStatFlag
);
3074 memset(pstatstg
, 0, sizeof(STATSTG
));
3075 pstatstg
->type
= STGTY_STORAGE
;
3076 pstatstg
->clsid
= CLSID_WineTestOld
;
3080 static IStorageVtbl StorageVtbl
=
3082 Storage_QueryInterface
,
3085 Storage_CreateStream
,
3087 Storage_CreateStorage
,
3088 Storage_OpenStorage
,
3090 Storage_MoveElementTo
,
3093 Storage_EnumElements
,
3094 Storage_DestroyElement
,
3095 Storage_RenameElement
,
3096 Storage_SetElementTimes
,
3098 Storage_SetStateBits
,
3102 static IStorage Storage
= { &StorageVtbl
};
3104 static void test_OleDoAutoConvert(void)
3106 static const WCHAR clsidW
[] = {'C','L','S','I','D','\\',0};
3111 DWORD ansi_user_type_len
;
3112 DWORD ansi_clipboard_format_len
;
3114 DWORD unicode_marker
;
3115 DWORD unicode_user_type_len
;
3116 DWORD unicode_clipboard_format_len
;
3122 DWORD link_update_option
;
3124 DWORD reserved_moniker_stream_size
;
3125 DWORD relative_source_moniker_stream_size
;
3126 DWORD absolute_source_moniker_stream_size
;
3127 DWORD clsid_indicator
;
3129 DWORD reserved_display_name
;
3131 DWORD local_update_time
;
3132 DWORD local_check_update_time
;
3133 DWORD remote_update_time
;
3136 LARGE_INTEGER pos
= {{0}};
3143 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &comp_obj_stream
);
3144 ok(hr
== S_OK
, "CreateStreamOnHGlobal returned %x\n", hr
);
3145 hr
= IStream_Write(comp_obj_stream
, (char*)&comp_obj_data
, sizeof(comp_obj_data
), NULL
);
3146 ok(hr
== S_OK
, "IStream_Write returned %x\n", hr
);
3148 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &ole_stream
);
3149 ok(hr
== S_OK
, "CreateStreamOnHGlobal returned %x\n", hr
);
3150 hr
= IStream_Write(ole_stream
, (char*)&ole_data
, sizeof(ole_data
), NULL
);
3151 ok(hr
== S_OK
, "IStream_Write returned %x\n", hr
);
3153 clsid
= IID_WineTest
;
3154 hr
= OleDoAutoConvert(NULL
, &clsid
);
3155 ok(hr
== E_INVALIDARG
, "OleDoAutoConvert returned %x\n", hr
);
3156 ok(IsEqualIID(&clsid
, &IID_NULL
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3158 if(0) /* crashes on Win7 */
3159 OleDoAutoConvert(&Storage
, NULL
);
3161 clsid
= IID_WineTest
;
3162 SET_EXPECT(Storage_Stat
);
3163 hr
= OleDoAutoConvert(&Storage
, &clsid
);
3164 ok(hr
== REGDB_E_CLASSNOTREG
, "OleDoAutoConvert returned %x\n", hr
);
3165 CHECK_CALLED(Storage_Stat
);
3166 ok(IsEqualIID(&clsid
, &CLSID_WineTestOld
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3168 lstrcpyW(buf
, clsidW
);
3169 StringFromGUID2(&CLSID_WineTestOld
, buf
+6, 39);
3171 ret
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, buf
, 0, NULL
, 0,
3172 KEY_READ
| KEY_WRITE
| KEY_CREATE_SUB_KEY
, NULL
, &root
, NULL
);
3173 if(ret
!= ERROR_SUCCESS
) {
3174 win_skip("not enough permissions to create CLSID key (%u)\n", ret
);
3178 clsid
= IID_WineTest
;
3179 SET_EXPECT(Storage_Stat
);
3180 hr
= OleDoAutoConvert(&Storage
, &clsid
);
3181 ok(hr
== REGDB_E_KEYMISSING
, "OleDoAutoConvert returned %x\n", hr
);
3182 CHECK_CALLED(Storage_Stat
);
3183 ok(IsEqualIID(&clsid
, &CLSID_WineTestOld
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3185 hr
= OleSetAutoConvert(&CLSID_WineTestOld
, &CLSID_WineTest
);
3186 ok_ole_success(hr
, "OleSetAutoConvert");
3188 hr
= OleGetAutoConvert(&CLSID_WineTestOld
, &clsid
);
3189 ok_ole_success(hr
, "OleGetAutoConvert");
3190 ok(IsEqualIID(&clsid
, &CLSID_WineTest
), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid
));
3192 clsid
= IID_WineTest
;
3193 SET_EXPECT(Storage_Stat
);
3194 SET_EXPECT(Storage_OpenStream_CompObj
);
3195 SET_EXPECT(Storage_SetClass
);
3196 SET_EXPECT(Storage_CreateStream_CompObj
);
3197 SET_EXPECT(Storage_OpenStream_Ole
);
3198 hr
= OleDoAutoConvert(&Storage
, &clsid
);
3199 ok(hr
== S_OK
, "OleDoAutoConvert returned %x\n", hr
);
3200 CHECK_CALLED(Storage_Stat
);
3201 CHECK_CALLED(Storage_OpenStream_CompObj
);
3202 CHECK_CALLED(Storage_SetClass
);
3203 CHECK_CALLED(Storage_CreateStream_CompObj
);
3204 CHECK_CALLED(Storage_OpenStream_Ole
);
3205 ok(IsEqualIID(&clsid
, &CLSID_WineTest
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3207 hr
= IStream_Seek(comp_obj_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3208 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3209 hr
= IStream_Read(comp_obj_stream
, &comp_obj_data
, sizeof(comp_obj_data
), NULL
);
3210 ok(hr
== S_OK
, "IStream_Read returned %x\n", hr
);
3211 ok(comp_obj_data
.reserved1
== 0xfffe0001, "reserved1 = %x\n", comp_obj_data
.reserved1
);
3212 ok(comp_obj_data
.version
== 0xa03, "version = %x\n", comp_obj_data
.version
);
3213 ok(comp_obj_data
.reserved2
[0] == -1, "reserved2[0] = %x\n", comp_obj_data
.reserved2
[0]);
3214 ok(IsEqualIID(comp_obj_data
.reserved2
+1, &CLSID_WineTestOld
), "reserved2 = %s\n", wine_dbgstr_guid((CLSID
*)(comp_obj_data
.reserved2
+1)));
3215 ok(!comp_obj_data
.ansi_user_type_len
, "ansi_user_type_len = %d\n", comp_obj_data
.ansi_user_type_len
);
3216 ok(!comp_obj_data
.ansi_clipboard_format_len
, "ansi_clipboard_format_len = %d\n", comp_obj_data
.ansi_clipboard_format_len
);
3217 ok(!comp_obj_data
.reserved3
, "reserved3 = %x\n", comp_obj_data
.reserved3
);
3218 ok(comp_obj_data
.unicode_marker
== 0x71b239f4, "unicode_marker = %x\n", comp_obj_data
.unicode_marker
);
3219 ok(!comp_obj_data
.unicode_user_type_len
, "unicode_user_type_len = %d\n", comp_obj_data
.unicode_user_type_len
);
3220 ok(!comp_obj_data
.unicode_clipboard_format_len
, "unicode_clipboard_format_len = %d\n", comp_obj_data
.unicode_clipboard_format_len
);
3221 ok(!comp_obj_data
.reserved4
, "reserved4 %d\n", comp_obj_data
.reserved4
);
3223 hr
= IStream_Seek(ole_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3224 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3225 hr
= IStream_Read(ole_stream
, &ole_data
, sizeof(ole_data
), NULL
);
3226 ok(hr
== S_OK
, "IStream_Read returned %x\n", hr
);
3227 ok(ole_data
.version
== 0, "version = %x\n", ole_data
.version
);
3228 ok(ole_data
.flags
== 4, "flags = %x\n", ole_data
.flags
);
3229 for(i
=2; i
<sizeof(ole_data
)/sizeof(DWORD
); i
++)
3230 ok(((DWORD
*)&ole_data
)[i
] == 0, "ole_data[%d] = %x\n", i
, ((DWORD
*)&ole_data
)[i
]);
3232 SET_EXPECT(Storage_OpenStream_Ole
);
3233 hr
= SetConvertStg(&Storage
, TRUE
);
3234 ok(hr
== S_OK
, "SetConvertStg returned %x\n", hr
);
3235 CHECK_CALLED(Storage_OpenStream_Ole
);
3237 SET_EXPECT(Storage_OpenStream_CompObj
);
3238 SET_EXPECT(Storage_Stat
);
3239 SET_EXPECT(Storage_CreateStream_CompObj
);
3240 hr
= WriteFmtUserTypeStg(&Storage
, 0, NULL
);
3241 ok(hr
== S_OK
, "WriteFmtUserTypeStg returned %x\n", hr
);
3242 todo_wine
CHECK_CALLED(Storage_OpenStream_CompObj
);
3243 CHECK_CALLED(Storage_Stat
);
3244 CHECK_CALLED(Storage_CreateStream_CompObj
);
3245 hr
= IStream_Seek(comp_obj_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3246 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3247 hr
= IStream_Read(comp_obj_stream
, &comp_obj_data
, sizeof(comp_obj_data
), NULL
);
3248 ok(hr
== S_OK
, "IStream_Read returned %x\n", hr
);
3249 ok(comp_obj_data
.reserved1
== 0xfffe0001, "reserved1 = %x\n", comp_obj_data
.reserved1
);
3250 ok(comp_obj_data
.version
== 0xa03, "version = %x\n", comp_obj_data
.version
);
3251 ok(comp_obj_data
.reserved2
[0] == -1, "reserved2[0] = %x\n", comp_obj_data
.reserved2
[0]);
3252 ok(IsEqualIID(comp_obj_data
.reserved2
+1, &CLSID_WineTestOld
), "reserved2 = %s\n", wine_dbgstr_guid((CLSID
*)(comp_obj_data
.reserved2
+1)));
3253 ok(!comp_obj_data
.ansi_user_type_len
, "ansi_user_type_len = %d\n", comp_obj_data
.ansi_user_type_len
);
3254 ok(!comp_obj_data
.ansi_clipboard_format_len
, "ansi_clipboard_format_len = %d\n", comp_obj_data
.ansi_clipboard_format_len
);
3255 ok(!comp_obj_data
.reserved3
, "reserved3 = %x\n", comp_obj_data
.reserved3
);
3256 ok(comp_obj_data
.unicode_marker
== 0x71b239f4, "unicode_marker = %x\n", comp_obj_data
.unicode_marker
);
3257 ok(!comp_obj_data
.unicode_user_type_len
, "unicode_user_type_len = %d\n", comp_obj_data
.unicode_user_type_len
);
3258 ok(!comp_obj_data
.unicode_clipboard_format_len
, "unicode_clipboard_format_len = %d\n", comp_obj_data
.unicode_clipboard_format_len
);
3259 ok(!comp_obj_data
.reserved4
, "reserved4 %d\n", comp_obj_data
.reserved4
);
3261 ret
= IStream_Release(comp_obj_stream
);
3262 ok(!ret
, "comp_obj_stream was not freed\n");
3263 ret
= IStream_Release(ole_stream
);
3264 ok(!ret
, "ole_stream was not freed\n");
3266 ret
= RegDeleteKeyA(root
, "AutoConvertTo");
3267 ok(ret
== ERROR_SUCCESS
, "RegDeleteKey error %u\n", ret
);
3268 ret
= RegDeleteKeyA(root
, "");
3269 ok(ret
== ERROR_SUCCESS
, "RegDeleteKey error %u\n", ret
);
3274 static const unsigned char bmpimage
[] =
3276 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,
3277 0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
3278 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
3279 0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
3280 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,
3281 0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
3282 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,
3283 0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
3287 static const unsigned char mf_blank_bits
[] =
3289 0x01,0x00,0x09,0x00,0x00,0x03,0x0c,0x00,
3290 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
3291 0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00
3294 static void test_data_cache_save(void)
3296 static const WCHAR contentsW
[] = { 'C','o','n','t','e','n','t','s',0 };
3302 IPersistStorage
*stg
;
3303 DWORD clipformat
[2];
3304 PresentationDataHeader hdr
;
3306 hr
= CreateILockBytesOnHGlobal(0, TRUE
, &ilb
);
3307 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3308 hr
= StgCreateDocfileOnILockBytes(ilb
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &doc
);
3309 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3311 ILockBytes_Release(ilb
);
3313 hr
= IStorage_SetClass(doc
, &CLSID_WineTest
);
3314 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3316 hr
= IStorage_CreateStream(doc
, contentsW
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
3317 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3318 hr
= IStream_Write(stm
, bmpimage
, sizeof(bmpimage
), NULL
);
3319 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3320 IStream_Release(stm
);
3322 hr
= IStorage_CreateStream(doc
, olepres0W
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
3323 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3326 clipformat
[1] = CF_METAFILEPICT
;
3327 hr
= IStream_Write(stm
, clipformat
, sizeof(clipformat
), NULL
);
3328 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3331 hdr
.dvAspect
= DVASPECT_CONTENT
;
3333 hdr
.advf
= ADVF_PRIMEFIRST
;
3335 hdr
.dwObjectExtentX
= 0;
3336 hdr
.dwObjectExtentY
= 0;
3337 hdr
.dwSize
= sizeof(mf_blank_bits
);
3338 hr
= IStream_Write(stm
, &hdr
, sizeof(hdr
), NULL
);
3339 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3340 hr
= IStream_Write(stm
, mf_blank_bits
, sizeof(mf_blank_bits
), NULL
);
3341 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3343 IStream_Release(stm
);
3345 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IUnknown
, (void **)&cache
);
3346 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3347 hr
= IOleCache2_QueryInterface(cache
, &IID_IPersistStorage
, (void **)&stg
);
3348 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3349 hr
= IPersistStorage_Load(stg
, doc
);
3350 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3352 IStorage_Release(doc
);
3354 hr
= IPersistStorage_IsDirty(stg
);
3355 ok(hr
== S_FALSE
, "unexpected %#x\n", hr
);
3358 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &olepres_stream
);
3359 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3361 /* FIXME: remove this stream once Wine is fixed */
3362 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &contents_stream
);
3363 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3365 SET_EXPECT(Storage_CreateStream_OlePres
);
3366 SET_EXPECT(Storage_OpenStream_OlePres
);
3367 SET_EXPECT(Storage_OpenStream_Ole
);
3368 SET_EXPECT(Storage_DestroyElement
);
3369 Storage_DestroyElement_limit
= 50;
3370 Storage_SetClass_CLSID
= &CLSID_NULL
;
3371 trace("IPersistStorage_Save:\n");
3372 hr
= IPersistStorage_Save(stg
, &Storage
, FALSE
);
3373 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3374 CHECK_CALLED(Storage_CreateStream_OlePres
);
3376 CHECK_CALLED(Storage_OpenStream_OlePres
);
3378 CHECK_CALLED(Storage_OpenStream_Ole
);
3380 CHECK_CALLED(Storage_DestroyElement
);
3382 IStream_Release(olepres_stream
);
3383 IStream_Release(contents_stream
);
3385 IPersistStorage_Release(stg
);
3386 IOleCache2_Release(cache
);
3389 #define MAX_STREAM 16
3405 struct stream_def stream
[MAX_STREAM
];
3408 static const struct storage_def stg_def_0
=
3411 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) }}
3413 static const struct storage_def stg_def_0_saved
=
3415 &CLSID_NULL
, 0, {{ 0 }}
3417 static const struct storage_def stg_def_1
=
3420 {{ "Contents", -1, 0, 0, NULL
, 0 },
3421 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3423 static const struct storage_def stg_def_1_saved
=
3426 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3428 static const struct storage_def stg_def_2
=
3430 &CLSID_ManualResetEvent
, 2,
3431 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3432 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3434 static const struct storage_def stg_def_2_saved
=
3437 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3439 static const struct storage_def stg_def_3
=
3442 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3443 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3444 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3445 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3446 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3448 static const struct storage_def stg_def_3_saved
=
3451 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3452 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3453 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) }}
3455 static const struct storage_def stg_def_4
=
3457 &CLSID_Picture_EnhMetafile
, 5,
3458 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3459 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3460 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3461 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3462 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3464 static const struct storage_def stg_def_4_saved
=
3467 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3469 static const struct storage_def stg_def_5
=
3471 &CLSID_Picture_Dib
, 5,
3472 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3473 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3474 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3475 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3476 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3478 static const struct storage_def stg_def_5_saved
=
3481 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3483 static const struct storage_def stg_def_6
=
3485 &CLSID_Picture_Metafile
, 5,
3486 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3487 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3488 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3489 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3490 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3492 static const struct storage_def stg_def_6_saved
=
3495 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3497 static const struct storage_def stg_def_7
=
3499 &CLSID_Picture_Dib
, 1,
3500 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) }}
3502 static const struct storage_def stg_def_7_saved
=
3504 &CLSID_NULL
, 0, {{ 0 }}
3506 static const struct storage_def stg_def_8
=
3508 &CLSID_Picture_Metafile
, 1,
3509 {{ "Contents", -1, 0, 0, mf_blank_bits
, sizeof(mf_blank_bits
) }}
3511 static const struct storage_def stg_def_8_saved
=
3513 &CLSID_NULL
, 0, {{ 0 }}
3515 static const struct storage_def stg_def_9
=
3517 &CLSID_Picture_EnhMetafile
, 1,
3518 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) }}
3520 static const struct storage_def stg_def_9_saved
=
3522 &CLSID_NULL
, 0, {{ 0 }}
3525 static int read_clipformat(IStream
*stream
)
3529 int length
, clipformat
= -2;
3531 hr
= IStream_Read(stream
, &length
, sizeof(length
), &bytes
);
3532 if (hr
!= S_OK
|| bytes
!= sizeof(length
))
3538 hr
= IStream_Read(stream
, &clipformat
, sizeof(clipformat
), &bytes
);
3539 if (hr
!= S_OK
|| bytes
!= sizeof(clipformat
))
3543 ok(0, "unhandled clipformat length %d\n", length
);
3548 static void check_storage_contents(IStorage
*stg
, const struct storage_def
*stg_def
,
3549 int *enumerated_streams
, int *matched_streams
)
3552 IEnumSTATSTG
*enumstg
;
3555 int i
, seen_stream
[MAX_STREAM
] = { 0 };
3557 if (winetest_debug
> 1)
3558 trace("check_storage_contents:\n=============================================\n");
3560 *enumerated_streams
= 0;
3561 *matched_streams
= 0;
3563 hr
= IStorage_Stat(stg
, &stat
, STATFLAG_NONAME
);
3564 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3565 ok(IsEqualCLSID(stg_def
->clsid
, &stat
.clsid
), "expected %s, got %s\n",
3566 wine_dbgstr_guid(stg_def
->clsid
), wine_dbgstr_guid(&stat
.clsid
));
3568 hr
= IStorage_EnumElements(stg
, 0, NULL
, 0, &enumstg
);
3569 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3574 int clipformat
= -1;
3575 PresentationDataHeader header
;
3579 memset(&header
, 0, sizeof(header
));
3581 hr
= IEnumSTATSTG_Next(enumstg
, 1, &stat
, NULL
);
3582 if(hr
== S_FALSE
) break;
3583 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3585 if (winetest_debug
> 1)
3586 trace("name %s, type %u, size %d, clsid %s\n",
3587 wine_dbgstr_w(stat
.pwcsName
), stat
.type
, stat
.cbSize
.u
.LowPart
, wine_dbgstr_guid(&stat
.clsid
));
3589 ok(stat
.type
== STGTY_STREAM
, "unexpected %#x\n", stat
.type
);
3591 WideCharToMultiByte(CP_ACP
, 0, stat
.pwcsName
, -1, name
, sizeof(name
), NULL
, NULL
);
3593 hr
= IStorage_OpenStream(stg
, stat
.pwcsName
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, &stream
);
3594 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3596 if (!memcmp(name
, "\2OlePres", 7))
3598 clipformat
= read_clipformat(stream
);
3600 hr
= IStream_Read(stream
, &header
, sizeof(header
), &bytes
);
3601 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3602 ok(bytes
>= 24, "read %u bytes\n", bytes
);
3604 if (winetest_debug
> 1)
3605 trace("header: unknown3 %#x, dvAspect %#x, lindex %#x, advf %#x, unknown7 %#x, dwObjectExtentX %#x, dwObjectExtentY %#x, dwSize %#x\n",
3606 header
.unknown3
, header
.dvAspect
, header
.lindex
, header
.advf
, header
.unknown7
,
3607 header
.dwObjectExtentX
, header
.dwObjectExtentY
, header
.dwSize
);
3610 memset(data
, 0, sizeof(data
));
3611 hr
= IStream_Read(stream
, data
, sizeof(data
), &bytes
);
3612 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3613 if (winetest_debug
> 1)
3614 trace("stream data (%u bytes): %02x %02x %02x %02x\n", bytes
, data
[0], data
[1], data
[2], data
[3]);
3616 for (i
= 0; i
< stg_def
->stream_count
; i
++)
3618 if (seen_stream
[i
]) continue;
3620 if (winetest_debug
> 1)
3621 trace("%s/%s, %d/%d, %d/%d, %d/%d\n",
3622 stg_def
->stream
[i
].name
, name
,
3623 stg_def
->stream
[i
].cf
, clipformat
,
3624 stg_def
->stream
[i
].dvAspect
, header
.dvAspect
,
3625 stg_def
->stream
[i
].advf
, header
.advf
);
3627 if (!strcmp(stg_def
->stream
[i
].name
, name
) &&
3628 stg_def
->stream
[i
].cf
== clipformat
&&
3629 stg_def
->stream
[i
].dvAspect
== header
.dvAspect
&&
3630 stg_def
->stream
[i
].advf
== header
.advf
&&
3631 stg_def
->stream
[i
].data_size
<= bytes
&&
3632 (!stg_def
->stream
[i
].data_size
||
3633 (!memcmp(stg_def
->stream
[i
].data
, data
, min(stg_def
->stream
[i
].data_size
, bytes
)))))
3635 if (winetest_debug
> 1)
3636 trace("stream %d matches def stream %d\n", *enumerated_streams
, i
);
3638 *matched_streams
+= 1;
3642 CoTaskMemFree(stat
.pwcsName
);
3643 IStream_Release(stream
);
3645 *enumerated_streams
+= 1;
3649 static IStorage
*create_storage_from_def(const struct storage_def
*stg_def
)
3656 hr
= StgCreateDocfile(NULL
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &stg
);
3657 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3659 hr
= IStorage_SetClass(stg
, stg_def
->clsid
);
3660 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3662 for (i
= 0; i
< stg_def
->stream_count
; i
++)
3666 MultiByteToWideChar(CP_ACP
, 0, stg_def
->stream
[i
].name
, -1, name
, 32);
3667 hr
= IStorage_CreateStream(stg
, name
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
3668 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3670 if (stg_def
->stream
[i
].cf
!= -1)
3673 PresentationDataHeader hdr
;
3675 if (stg_def
->stream
[i
].cf
)
3678 clipformat
[1] = stg_def
->stream
[i
].cf
;
3679 hr
= IStream_Write(stm
, clipformat
, sizeof(clipformat
), NULL
);
3684 hr
= IStream_Write(stm
, &clipformat
[0], sizeof(clipformat
[0]), NULL
);
3686 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3689 hdr
.dvAspect
= stg_def
->stream
[i
].dvAspect
;
3691 hdr
.advf
= stg_def
->stream
[i
].advf
;
3693 hdr
.dwObjectExtentX
= 0;
3694 hdr
.dwObjectExtentY
= 0;
3695 hdr
.dwSize
= stg_def
->stream
[i
].data_size
;
3696 hr
= IStream_Write(stm
, &hdr
, sizeof(hdr
), NULL
);
3697 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3700 if (stg_def
->stream
[i
].data_size
)
3702 hr
= IStream_Write(stm
, stg_def
->stream
[i
].data
, stg_def
->stream
[i
].data_size
, NULL
);
3703 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3706 IStream_Release(stm
);
3712 static void test_data_cache_contents(void)
3715 IStorage
*doc1
, *doc2
;
3717 IPersistStorage
*stg
;
3718 int i
, enumerated_streams
, matched_streams
;
3721 const struct storage_def
*in
;
3722 const struct storage_def
*out
;
3725 { &stg_def_0
, &stg_def_0_saved
},
3726 { &stg_def_1
, &stg_def_1_saved
},
3727 { &stg_def_2
, &stg_def_2_saved
},
3728 { &stg_def_3
, &stg_def_3_saved
},
3729 { &stg_def_4
, &stg_def_4_saved
},
3730 { &stg_def_5
, &stg_def_5_saved
},
3731 { &stg_def_6
, &stg_def_6_saved
},
3732 { &stg_def_7
, &stg_def_7_saved
},
3733 { &stg_def_8
, &stg_def_8_saved
},
3734 { &stg_def_9
, &stg_def_9_saved
},
3737 for (i
= 0; i
< sizeof(test_data
)/sizeof(test_data
[0]); i
++)
3739 if (winetest_debug
> 1)
3740 trace("start testing storage def %d\n", i
);
3742 doc1
= create_storage_from_def(test_data
[i
].in
);
3743 if (!doc1
) continue;
3745 enumerated_streams
= matched_streams
= -1;
3746 check_storage_contents(doc1
, test_data
[i
].in
, &enumerated_streams
, &matched_streams
);
3747 ok(enumerated_streams
== matched_streams
, "%d in: enumerated %d != matched %d\n", i
,
3748 enumerated_streams
, matched_streams
);
3749 ok(enumerated_streams
== test_data
[i
].in
->stream_count
, "%d: created %d != def streams %d\n", i
,
3750 enumerated_streams
, test_data
[i
].in
->stream_count
);
3752 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IUnknown
, (void **)&cache
);
3753 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3754 hr
= IOleCache2_QueryInterface(cache
, &IID_IPersistStorage
, (void **)&stg
);
3755 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3756 hr
= IPersistStorage_Load(stg
, doc1
);
3757 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3759 IStorage_Release(doc1
);
3761 hr
= StgCreateDocfile(NULL
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &doc2
);
3762 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3764 hr
= IPersistStorage_IsDirty(stg
);
3765 todo_wine_if(test_data
[i
].in
== &stg_def_4
|| test_data
[i
].in
== &stg_def_8
|| test_data
[i
].in
== &stg_def_9
)
3766 ok(hr
== S_FALSE
, "%d: unexpected %#x\n", i
, hr
);
3768 hr
= IPersistStorage_Save(stg
, doc2
, FALSE
);
3769 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3771 IPersistStorage_Release(stg
);
3773 enumerated_streams
= matched_streams
= -1;
3774 check_storage_contents(doc2
, test_data
[i
].out
, &enumerated_streams
, &matched_streams
);
3775 todo_wine_if(!(test_data
[i
].in
== &stg_def_0
|| test_data
[i
].in
== &stg_def_1
|| test_data
[i
].in
== &stg_def_2
))
3776 ok(enumerated_streams
== matched_streams
, "%d out: enumerated %d != matched %d\n", i
,
3777 enumerated_streams
, matched_streams
);
3778 todo_wine_if(!(test_data
[i
].in
== &stg_def_0
|| test_data
[i
].in
== &stg_def_5
))
3779 ok(enumerated_streams
== test_data
[i
].out
->stream_count
, "%d: saved streams %d != def streams %d\n", i
,
3780 enumerated_streams
, test_data
[i
].out
->stream_count
);
3782 IStorage_Release(doc2
);
3784 if (winetest_debug
> 1)
3785 trace("done testing storage def %d\n", i
);
3796 cf_test_1
= RegisterClipboardFormatA("cf_winetest_1");
3797 cf_test_2
= RegisterClipboardFormatA("cf_winetest_2");
3798 cf_test_3
= RegisterClipboardFormatA("cf_winetest_3");
3802 hr
= CoRegisterClassObject(&CLSID_Equation3
, (IUnknown
*)&OleObjectCF
, CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, &dwRegister
);
3803 ok_ole_success(hr
, "CoRegisterClassObject");
3805 hr
= StgCreateDocfile(NULL
, STGM_READWRITE
| STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &pStorage
);
3806 ok_ole_success(hr
, "StgCreateDocfile");
3808 test_OleCreate(pStorage
);
3810 hr
= IStorage_Stat(pStorage
, &statstg
, STATFLAG_NONAME
);
3811 ok_ole_success(hr
, "IStorage_Stat");
3812 ok(IsEqualCLSID(&CLSID_Equation3
, &statstg
.clsid
), "Wrong CLSID in storage\n");
3814 test_OleLoad(pStorage
);
3816 IStorage_Release(pStorage
);
3818 hr
= CoRevokeClassObject(dwRegister
);
3819 ok_ole_success(hr
, "CoRevokeClassObject");
3821 Storage_SetClass_CLSID
= &CLSID_WineTest
;
3824 test_data_cache_dib_contents_stream( 0 );
3825 test_data_cache_dib_contents_stream( 1 );
3826 test_data_cache_cache();
3827 test_data_cache_init();
3828 test_data_cache_initnew();
3829 test_default_handler();
3832 test_OleLockRunning();
3834 test_OleDoAutoConvert();
3835 test_data_cache_save();
3836 test_data_cache_contents();