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_bitmap(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 }
2141 hr
= CreateDataCache( NULL
, &CLSID_NULL
, &IID_IOleCache2
, (void **)&cache
);
2142 ok( hr
== S_OK
, "got %08x\n", hr
);
2144 /* create a dib entry which will also create a bitmap entry too */
2145 fmt
.cfFormat
= CF_DIB
;
2147 fmt
.dwAspect
= DVASPECT_CONTENT
;
2149 fmt
.tymed
= TYMED_HGLOBAL
;
2151 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2152 ok( hr
== S_OK
, "got %08x\n", hr
);
2153 ok( conn
== 2, "got %d\n", conn
);
2154 expect
[0].dwConnection
= conn
;
2155 expect
[1].dwConnection
= conn
;
2157 check_enum_cache( cache
, expect
, 2 );
2159 /* now try to add a bitmap */
2160 fmt
.cfFormat
= CF_BITMAP
;
2161 fmt
.tymed
= TYMED_GDI
;
2163 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2164 ok( hr
== CACHE_S_SAMECACHE
, "got %08x\n", hr
);
2167 fmt
.cfFormat
= CF_METAFILEPICT
;
2168 fmt
.tymed
= TYMED_MFPICT
;
2170 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2171 ok( hr
== S_OK
, "got %08x\n", hr
);
2172 ok( conn
== 3, "got %d\n", conn
);
2173 expect
[2].dwConnection
= conn
;
2175 check_enum_cache( cache
, expect
, 3);
2178 fmt
.cfFormat
= CF_ENHMETAFILE
;
2179 fmt
.tymed
= TYMED_ENHMF
;
2181 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2182 ok( hr
== S_OK
, "got %08x\n", hr
);
2183 ok( conn
== 4, "got %d\n", conn
);
2184 expect
[3].dwConnection
= conn
;
2186 check_enum_cache( cache
, expect
, 4 );
2188 /* uncache everything */
2189 hr
= IOleCache2_Uncache( cache
, expect
[3].dwConnection
);
2190 ok( hr
== S_OK
, "got %08x\n", hr
);
2191 hr
= IOleCache2_Uncache( cache
, expect
[2].dwConnection
);
2192 ok( hr
== S_OK
, "got %08x\n", hr
);
2193 hr
= IOleCache2_Uncache( cache
, expect
[0].dwConnection
);
2194 ok( hr
== S_OK
, "got %08x\n", hr
);
2195 hr
= IOleCache2_Uncache( cache
, expect
[0].dwConnection
);
2196 ok( hr
== OLE_E_NOCONNECTION
, "got %08x\n", hr
);
2198 check_enum_cache( cache
, expect
, 0 );
2200 /* just create a bitmap entry which again adds both dib and bitmap */
2201 fmt
.cfFormat
= CF_BITMAP
;
2202 fmt
.tymed
= TYMED_GDI
;
2204 hr
= IOleCache2_Cache( cache
, &fmt
, 0, &conn
);
2205 ok( hr
== S_OK
, "got %08x\n", hr
);
2207 expect
[0].dwConnection
= conn
;
2208 expect
[1].dwConnection
= conn
;
2210 check_enum_cache( cache
, expect
, 2 );
2212 /* Try setting a 1x1 bitmap */
2213 hr
= IOleCache2_QueryInterface( cache
, &IID_IDataObject
, (void **) &data
);
2214 ok( hr
== S_OK
, "got %08x\n", hr
);
2216 med
.tymed
= TYMED_GDI
;
2217 U(med
).hBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
2218 med
.pUnkForRelease
= NULL
;
2220 hr
= IOleCache2_SetData( cache
, &fmt
, &med
, TRUE
);
2221 ok( hr
== S_OK
, "got %08x\n", hr
);
2223 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2224 ok( hr
== S_OK
, "got %08x\n", hr
);
2225 ok( med
.tymed
== TYMED_GDI
, "got %d\n", med
.tymed
);
2226 check_bitmap_size( U(med
).hBitmap
, 1, 1 );
2227 ReleaseStgMedium( &med
);
2229 fmt
.cfFormat
= CF_DIB
;
2230 fmt
.tymed
= TYMED_HGLOBAL
;
2231 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2232 ok( hr
== S_OK
, "got %08x\n", hr
);
2233 ok( med
.tymed
== TYMED_HGLOBAL
, "got %d\n", med
.tymed
);
2234 check_dib_size( U(med
).hGlobal
, 1, 1 );
2235 ReleaseStgMedium( &med
);
2237 /* Now set a 2x1 dib */
2238 fmt
.cfFormat
= CF_DIB
;
2239 fmt
.tymed
= TYMED_HGLOBAL
;
2240 med
.tymed
= TYMED_HGLOBAL
;
2241 U(med
).hGlobal
= create_dib();
2243 hr
= IOleCache2_SetData( cache
, &fmt
, &med
, TRUE
);
2244 ok( hr
== S_OK
, "got %08x\n", hr
);
2246 fmt
.cfFormat
= CF_BITMAP
;
2247 fmt
.tymed
= TYMED_GDI
;
2248 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2249 ok( hr
== S_OK
, "got %08x\n", hr
);
2250 ok( med
.tymed
== TYMED_GDI
, "got %d\n", med
.tymed
);
2251 check_bitmap_size( U(med
).hBitmap
, 2, 1 );
2252 ReleaseStgMedium( &med
);
2254 fmt
.cfFormat
= CF_DIB
;
2255 fmt
.tymed
= TYMED_HGLOBAL
;
2256 hr
= IDataObject_GetData( data
, &fmt
, &med
);
2257 ok( hr
== S_OK
, "got %08x\n", hr
);
2258 ok( med
.tymed
== TYMED_HGLOBAL
, "got %d\n", med
.tymed
);
2259 check_dib_size( U(med
).hGlobal
, 2, 1 );
2260 ReleaseStgMedium( &med
);
2262 IDataObject_Release( data
);
2263 IOleCache2_Release( cache
);
2266 /* The CLSID_Picture_ classes automatically create appropriate cache entries */
2267 static void test_data_cache_init(void)
2271 IPersistStorage
*persist
;
2274 static const STATDATA enum_expect
[] =
2276 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2277 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2278 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 1 },
2279 {{ CF_ENHMETAFILE
, 0, DVASPECT_CONTENT
, -1, TYMED_ENHMF
}, 0, NULL
, 1 }
2284 int enum_start
, enum_num
;
2287 { &CLSID_NULL
, 0, 0 },
2288 { &CLSID_WineTestOld
, 0, 0 },
2289 { &CLSID_Picture_Dib
, 0, 2 },
2290 { &CLSID_Picture_Metafile
, 2, 1 },
2291 { &CLSID_Picture_EnhMetafile
, 3, 1 }
2294 for (i
= 0; i
< sizeof(data
) / sizeof(data
[0]); i
++)
2296 hr
= CreateDataCache( NULL
, data
[i
].clsid
, &IID_IOleCache2
, (void **)&cache
);
2297 ok( hr
== S_OK
, "got %08x\n", hr
);
2299 check_enum_cache( cache
, enum_expect
+ data
[i
].enum_start
, data
[i
].enum_num
);
2301 IOleCache2_QueryInterface( cache
, &IID_IPersistStorage
, (void **) &persist
);
2302 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2303 ok( hr
== S_OK
, "got %08x\n", hr
);
2304 ok( IsEqualCLSID( &clsid
, data
[i
].clsid
), "class id mismatch %s %s\n", wine_dbgstr_guid( &clsid
),
2305 wine_dbgstr_guid( data
[i
].clsid
) );
2307 IPersistStorage_Release( persist
);
2308 IOleCache2_Release( cache
);
2312 static void test_data_cache_initnew(void)
2316 IPersistStorage
*persist
;
2317 IStorage
*stg_dib
, *stg_mf
, *stg_wine
;
2319 static const STATDATA initnew_expect
[] =
2321 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2322 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2324 static const STATDATA initnew2_expect
[] =
2326 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 1 },
2327 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 2 },
2328 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 2 },
2330 static const STATDATA initnew3_expect
[] =
2332 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 1 },
2333 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 1 },
2334 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 2 },
2335 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 2 },
2336 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 3 },
2338 static const STATDATA initnew4_expect
[] =
2340 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 2 },
2341 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 2 },
2342 {{ CF_METAFILEPICT
, 0, DVASPECT_CONTENT
, -1, TYMED_MFPICT
}, 0, NULL
, 3 },
2343 {{ CF_DIB
, 0, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
}, 0, NULL
, 4 },
2344 {{ CF_BITMAP
, 0, DVASPECT_CONTENT
, -1, TYMED_GDI
}, 0, NULL
, 4 },
2347 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg_dib
);
2348 ok( hr
== S_OK
, "got %08x\n", hr
);
2349 hr
= IStorage_SetClass( stg_dib
, &CLSID_Picture_Dib
);
2350 ok( hr
== S_OK
, "got %08x\n", hr
);
2352 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg_mf
);
2353 ok( hr
== S_OK
, "got %08x\n", hr
);
2354 hr
= IStorage_SetClass( stg_mf
, &CLSID_Picture_Metafile
);
2355 ok( hr
== S_OK
, "got %08x\n", hr
);
2357 hr
= StgCreateDocfile( NULL
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_CREATE
| STGM_DELETEONRELEASE
, 0, &stg_wine
);
2358 ok( hr
== S_OK
, "got %08x\n", hr
);
2359 hr
= IStorage_SetClass( stg_wine
, &CLSID_WineTestOld
);
2360 ok( hr
== S_OK
, "got %08x\n", hr
);
2362 hr
= CreateDataCache( NULL
, &CLSID_WineTestOld
, &IID_IOleCache2
, (void **)&cache
);
2363 ok( hr
== S_OK
, "got %08x\n", hr
);
2364 IOleCache2_QueryInterface( cache
, &IID_IPersistStorage
, (void **) &persist
);
2366 hr
= IPersistStorage_InitNew( persist
, stg_dib
);
2367 ok( hr
== S_OK
, "got %08x\n", hr
);
2369 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2370 ok( hr
== S_OK
, "got %08x\n", hr
);
2371 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Dib
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2373 check_enum_cache( cache
, initnew_expect
, 2 );
2375 hr
= IPersistStorage_InitNew( persist
, stg_mf
);
2376 ok( hr
== CO_E_ALREADYINITIALIZED
, "got %08x\n", hr
);
2378 hr
= IPersistStorage_HandsOffStorage( persist
);
2379 ok( hr
== S_OK
, "got %08x\n", hr
);
2381 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2382 ok( hr
== S_OK
, "got %08x\n", hr
);
2383 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Dib
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2385 hr
= IPersistStorage_InitNew( persist
, stg_mf
);
2386 ok( hr
== S_OK
, "got %08x\n", hr
);
2388 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2389 ok( hr
== S_OK
, "got %08x\n", hr
);
2390 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Metafile
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2392 check_enum_cache( cache
, initnew2_expect
, 3 );
2394 hr
= IPersistStorage_HandsOffStorage( persist
);
2395 ok( hr
== S_OK
, "got %08x\n", hr
);
2397 hr
= IPersistStorage_InitNew( persist
, stg_dib
);
2398 ok( hr
== S_OK
, "got %08x\n", hr
);
2400 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2401 ok( hr
== S_OK
, "got %08x\n", hr
);
2402 ok( IsEqualCLSID( &clsid
, &CLSID_Picture_Dib
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2404 check_enum_cache( cache
, initnew3_expect
, 5 );
2406 hr
= IPersistStorage_HandsOffStorage( persist
);
2407 ok( hr
== S_OK
, "got %08x\n", hr
);
2409 hr
= IPersistStorage_InitNew( persist
, stg_wine
);
2410 ok( hr
== S_OK
, "got %08x\n", hr
);
2412 hr
= IPersistStorage_GetClassID( persist
, &clsid
);
2413 ok( hr
== S_OK
, "got %08x\n", hr
);
2414 ok( IsEqualCLSID( &clsid
, &CLSID_WineTestOld
), "got %s\n", wine_dbgstr_guid( &clsid
) );
2416 check_enum_cache( cache
, initnew4_expect
, 5 );
2418 IStorage_Release( stg_wine
);
2419 IStorage_Release( stg_mf
);
2420 IStorage_Release( stg_dib
);
2422 IPersistStorage_Release( persist
);
2423 IOleCache2_Release( cache
);
2426 static void test_default_handler(void)
2429 IOleObject
*pObject
;
2430 IRunnableObject
*pRunnableObject
;
2431 IOleClientSite
*pClientSite
;
2432 IDataObject
*pDataObject
;
2436 LPOLESTR pszUserType
;
2441 IOleInPlaceObject
*pInPlaceObj
;
2442 IEnumOLEVERB
*pEnumVerbs
;
2444 static const WCHAR wszUnknown
[] = {'U','n','k','n','o','w','n',0};
2445 static const WCHAR wszHostName
[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0};
2446 static const WCHAR wszDelim
[] = {'!',0};
2448 static const struct expected_method methods_embeddinghelper
[] =
2450 { "OleObject_QueryInterface", 0 },
2451 { "OleObject_AddRef", 0 },
2452 { "OleObject_QueryInterface", 0 },
2453 { "OleObject_QueryInterface", TEST_TODO
},
2454 { "OleObject_QueryInterface", 0 },
2455 { "OleObject_QueryInterface", 0 },
2456 { "OleObject_QueryInterface", TEST_OPTIONAL
}, /* Win95/98/NT4 */
2457 { "OleObject_Release", TEST_TODO
},
2458 { "WINE_EXTRA", TEST_OPTIONAL
},
2462 hr
= CoCreateInstance(&CLSID_WineTest
, NULL
, CLSCTX_INPROC_HANDLER
, &IID_IOleObject
, (void **)&pObject
);
2463 ok(hr
== REGDB_E_CLASSNOTREG
, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2465 hr
= OleCreateDefaultHandler(&CLSID_WineTest
, NULL
, &IID_IOleObject
, (void **)&pObject
);
2466 ok_ole_success(hr
, "OleCreateDefaultHandler");
2468 hr
= IOleObject_QueryInterface(pObject
, &IID_IOleInPlaceObject
, (void **)&pInPlaceObj
);
2469 ok(hr
== E_NOINTERFACE
, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr
);
2471 hr
= IOleObject_Advise(pObject
, &AdviseSink
, &dwAdvConn
);
2472 ok_ole_success(hr
, "IOleObject_Advise");
2474 hr
= IOleObject_Close(pObject
, OLECLOSE_NOSAVE
);
2475 ok_ole_success(hr
, "IOleObject_Close");
2477 /* FIXME: test IOleObject_EnumAdvise */
2479 hr
= IOleObject_EnumVerbs(pObject
, &pEnumVerbs
);
2480 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2482 hr
= IOleObject_GetClientSite(pObject
, &pClientSite
);
2483 ok_ole_success(hr
, "IOleObject_GetClientSite");
2485 hr
= IOleObject_SetClientSite(pObject
, pClientSite
);
2486 ok_ole_success(hr
, "IOleObject_SetClientSite");
2488 hr
= IOleObject_GetClipboardData(pObject
, 0, &pDataObject
);
2489 ok(hr
== OLE_E_NOTRUNNING
,
2490 "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n",
2493 hr
= IOleObject_GetExtent(pObject
, DVASPECT_CONTENT
, &sizel
);
2494 ok(hr
== OLE_E_BLANK
, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n",
2497 hr
= IOleObject_GetMiscStatus(pObject
, DVASPECT_CONTENT
, &dwStatus
);
2498 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2500 hr
= IOleObject_GetUserClassID(pObject
, &clsid
);
2501 ok_ole_success(hr
, "IOleObject_GetUserClassID");
2502 ok(IsEqualCLSID(&clsid
, &CLSID_WineTest
), "clsid != CLSID_WineTest\n");
2504 hr
= IOleObject_GetUserType(pObject
, USERCLASSTYPE_FULL
, &pszUserType
);
2506 ok_ole_success(hr
, "IOleObject_GetUserType");
2507 ok(!lstrcmpW(pszUserType
, wszUnknown
), "Retrieved user type was wrong\n");
2510 hr
= IOleObject_InitFromData(pObject
, NULL
, TRUE
, 0);
2511 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2513 hr
= IOleObject_IsUpToDate(pObject
);
2514 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2516 palette
.palNumEntries
= 1;
2517 palette
.palVersion
= 2;
2518 memset(&palette
.palPalEntry
[0], 0, sizeof(palette
.palPalEntry
[0]));
2519 hr
= IOleObject_SetColorScheme(pObject
, &palette
);
2520 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2522 sizel
.cx
= sizel
.cy
= 0;
2523 hr
= IOleObject_SetExtent(pObject
, DVASPECT_CONTENT
, &sizel
);
2524 ok(hr
== OLE_E_NOTRUNNING
, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2526 hr
= IOleObject_SetHostNames(pObject
, wszHostName
, NULL
);
2527 ok_ole_success(hr
, "IOleObject_SetHostNames");
2529 hr
= CreateItemMoniker(wszDelim
, wszHostName
, &pMoniker
);
2530 ok_ole_success(hr
, "CreateItemMoniker");
2531 hr
= IOleObject_SetMoniker(pObject
, OLEWHICHMK_CONTAINER
, pMoniker
);
2532 ok_ole_success(hr
, "IOleObject_SetMoniker");
2533 IMoniker_Release(pMoniker
);
2535 hr
= IOleObject_GetMoniker(pObject
, OLEGETMONIKER_ONLYIFTHERE
, OLEWHICHMK_CONTAINER
, &pMoniker
);
2536 ok(hr
== E_FAIL
, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr
);
2538 hr
= IOleObject_Update(pObject
);
2540 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2542 hr
= IOleObject_QueryInterface(pObject
, &IID_IDataObject
, (void **)&pDataObject
);
2543 ok_ole_success(hr
, "IOleObject_QueryInterface");
2545 fmtetc
.cfFormat
= CF_TEXT
;
2547 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2549 fmtetc
.tymed
= TYMED_NULL
;
2550 hr
= IDataObject_DAdvise(pDataObject
, &fmtetc
, 0, &AdviseSink
, &dwAdvConn
);
2551 ok_ole_success(hr
, "IDataObject_DAdvise");
2553 fmtetc
.cfFormat
= CF_ENHMETAFILE
;
2555 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2557 fmtetc
.tymed
= TYMED_ENHMF
;
2558 hr
= IDataObject_DAdvise(pDataObject
, &fmtetc
, 0, &AdviseSink
, &dwAdvConn
);
2559 ok_ole_success(hr
, "IDataObject_DAdvise");
2561 fmtetc
.cfFormat
= CF_ENHMETAFILE
;
2563 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2565 fmtetc
.tymed
= TYMED_ENHMF
;
2566 hr
= IDataObject_QueryGetData(pDataObject
, &fmtetc
);
2567 ok(hr
== OLE_E_NOTRUNNING
, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2569 fmtetc
.cfFormat
= CF_TEXT
;
2571 fmtetc
.dwAspect
= DVASPECT_CONTENT
;
2573 fmtetc
.tymed
= TYMED_NULL
;
2574 hr
= IDataObject_QueryGetData(pDataObject
, &fmtetc
);
2575 ok(hr
== OLE_E_NOTRUNNING
, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr
);
2577 hr
= IOleObject_QueryInterface(pObject
, &IID_IRunnableObject
, (void **)&pRunnableObject
);
2578 ok_ole_success(hr
, "IOleObject_QueryInterface");
2580 hr
= IRunnableObject_SetContainedObject(pRunnableObject
, TRUE
);
2581 ok_ole_success(hr
, "IRunnableObject_SetContainedObject");
2583 hr
= IRunnableObject_Run(pRunnableObject
, NULL
);
2584 ok(hr
== REGDB_E_CLASSNOTREG
, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr
);
2586 hr
= IOleObject_Close(pObject
, OLECLOSE_NOSAVE
);
2587 ok_ole_success(hr
, "IOleObject_Close");
2589 IRunnableObject_Release(pRunnableObject
);
2590 IOleObject_Release(pObject
);
2592 /* Test failure propagation from delegate ::QueryInterface */
2593 hr
= CoRegisterClassObject(&CLSID_WineTest
, (IUnknown
*)&OleObjectCF
,
2594 CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, &dwRegister
);
2595 ok_ole_success(hr
, "CoRegisterClassObject");
2598 expected_method_list
= methods_embeddinghelper
;
2599 hr
= OleCreateEmbeddingHelper(&CLSID_WineTest
, NULL
, EMBDHLP_INPROC_SERVER
,
2600 &OleObjectCF
, &IID_IOleObject
, (void**)&pObject
);
2601 ok_ole_success(hr
, "OleCreateEmbeddingHelper");
2606 g_QIFailsWith
= E_FAIL
;
2607 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
2608 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
2610 g_QIFailsWith
= E_NOINTERFACE
;
2611 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
2612 ok(hr
== E_NOINTERFACE
, "Got 0x%08x\n", hr
);
2614 g_QIFailsWith
= CO_E_OBJNOTCONNECTED
;
2615 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
2616 ok(hr
== CO_E_OBJNOTCONNECTED
, "Got 0x%08x\n", hr
);
2618 g_QIFailsWith
= 0x87654321;
2619 hr
= IOleObject_QueryInterface(pObject
, &IID_WineTest
, (void**)&punk
);
2620 ok(hr
== 0x87654321, "Got 0x%08x\n", hr
);
2622 IOleObject_Release(pObject
);
2625 CHECK_NO_EXTRA_METHODS();
2627 hr
= CoRevokeClassObject(dwRegister
);
2628 ok_ole_success(hr
, "CoRevokeClassObject");
2632 static void test_runnable(void)
2634 static const struct expected_method methods_query_runnable
[] =
2636 { "OleObject_QueryInterface", 0 },
2637 { "OleObjectRunnable_AddRef", 0 },
2638 { "OleObjectRunnable_IsRunning", 0 },
2639 { "OleObjectRunnable_Release", 0 },
2643 static const struct expected_method methods_no_runnable
[] =
2645 { "OleObject_QueryInterface", 0 },
2650 IOleObject
*object
= &OleObject
;
2653 ret
= OleIsRunning(NULL
);
2654 ok(ret
== FALSE
, "got %d\n", ret
);
2656 expected_method_list
= methods_query_runnable
;
2657 ret
= OleIsRunning(object
);
2658 ok(ret
== TRUE
, "Object should be running\n");
2659 CHECK_NO_EXTRA_METHODS();
2661 g_isRunning
= FALSE
;
2662 expected_method_list
= methods_query_runnable
;
2663 ret
= OleIsRunning(object
);
2664 ok(ret
== FALSE
, "Object should not be running\n");
2665 CHECK_NO_EXTRA_METHODS();
2667 g_showRunnable
= FALSE
; /* QueryInterface(IID_IRunnableObject, ...) will fail */
2668 expected_method_list
= methods_no_runnable
;
2669 ret
= OleIsRunning(object
);
2670 ok(ret
== TRUE
, "Object without IRunnableObject should be running\n");
2671 CHECK_NO_EXTRA_METHODS();
2674 g_showRunnable
= TRUE
;
2678 static HRESULT WINAPI
OleRun_QueryInterface(IRunnableObject
*iface
, REFIID riid
, void **ppv
)
2682 if (IsEqualIID(riid
, &IID_IUnknown
) ||
2683 IsEqualIID(riid
, &IID_IRunnableObject
)) {
2689 IUnknown_AddRef((IUnknown
*)*ppv
);
2693 return E_NOINTERFACE
;
2696 static ULONG WINAPI
OleRun_AddRef(IRunnableObject
*iface
)
2701 static ULONG WINAPI
OleRun_Release(IRunnableObject
*iface
)
2706 static HRESULT WINAPI
OleRun_GetRunningClass(IRunnableObject
*iface
, CLSID
*clsid
)
2708 ok(0, "unexpected\n");
2712 static HRESULT WINAPI
OleRun_Run(IRunnableObject
*iface
, LPBINDCTX ctx
)
2714 ok(ctx
== NULL
, "got %p\n", ctx
);
2718 static BOOL WINAPI
OleRun_IsRunning(IRunnableObject
*iface
)
2720 ok(0, "unexpected\n");
2724 static HRESULT WINAPI
OleRun_LockRunning(IRunnableObject
*iface
, BOOL lock
,
2725 BOOL last_unlock_closes
)
2727 ok(0, "unexpected\n");
2731 static HRESULT WINAPI
OleRun_SetContainedObject(IRunnableObject
*iface
, BOOL contained
)
2733 ok(0, "unexpected\n");
2737 static const IRunnableObjectVtbl oleruntestvtbl
=
2739 OleRun_QueryInterface
,
2742 OleRun_GetRunningClass
,
2746 OleRun_SetContainedObject
2749 static IRunnableObject testrunnable
= { &oleruntestvtbl
};
2751 static void test_OleRun(void)
2755 /* doesn't support IRunnableObject */
2756 hr
= OleRun(&unknown
);
2757 ok(hr
== S_OK
, "OleRun failed 0x%08x\n", hr
);
2759 hr
= OleRun((IUnknown
*)&testrunnable
);
2760 ok(hr
== 0xdeadc0de, "got 0x%08x\n", hr
);
2763 static void test_OleLockRunning(void)
2767 hr
= OleLockRunning(&unknown
, TRUE
, FALSE
);
2768 ok(hr
== S_OK
, "OleLockRunning failed 0x%08x\n", hr
);
2771 static void test_OleDraw(void)
2776 hr
= OleDraw((IUnknown
*)&viewobject
, 0, (HDC
)0x1, NULL
);
2777 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
2779 hr
= OleDraw(NULL
, 0, (HDC
)0x1, NULL
);
2780 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2782 hr
= OleDraw(NULL
, 0, (HDC
)0x1, &rect
);
2783 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
2786 static const WCHAR olepres0W
[] = {2,'O','l','e','P','r','e','s','0','0','0',0};
2787 static const WCHAR comp_objW
[] = {1,'C','o','m','p','O','b','j',0};
2788 static IStream
*comp_obj_stream
;
2789 static IStream
*ole_stream
;
2790 static IStream
*olepres_stream
;
2791 static IStream
*contents_stream
;
2793 static HRESULT WINAPI
Storage_QueryInterface(IStorage
*iface
, REFIID riid
, void **ppvObject
)
2795 ok(0, "unexpected call to QueryInterface\n");
2799 static ULONG WINAPI
Storage_AddRef(IStorage
*iface
)
2801 ok(0, "unexpected call to AddRef\n");
2805 static ULONG WINAPI
Storage_Release(IStorage
*iface
)
2807 ok(0, "unexpected call to Release\n");
2811 static HRESULT WINAPI
Storage_CreateStream(IStorage
*iface
, LPCOLESTR pwcsName
, DWORD grfMode
, DWORD reserved1
, DWORD reserved2
, IStream
**ppstm
)
2813 ULARGE_INTEGER size
= {{0}};
2814 LARGE_INTEGER pos
= {{0}};
2817 if (!lstrcmpW(pwcsName
, comp_objW
))
2819 CHECK_EXPECT(Storage_CreateStream_CompObj
);
2820 *ppstm
= comp_obj_stream
;
2822 todo_wine
ok(grfMode
== (STGM_CREATE
|STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
2824 else if (!lstrcmpW(pwcsName
, olepres0W
))
2826 CHECK_EXPECT(Storage_CreateStream_OlePres
);
2827 *ppstm
= olepres_stream
;
2829 todo_wine
ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
2834 ok(0, "unexpected stream name %s\n", wine_dbgstr_w(pwcsName
));
2835 #if 0 /* FIXME: return NULL once Wine is fixed */
2839 *ppstm
= contents_stream
;
2843 ok(!reserved1
, "reserved1 = %x\n", reserved1
);
2844 ok(!reserved2
, "reserved2 = %x\n", reserved2
);
2845 ok(!!ppstm
, "ppstm = NULL\n");
2847 IStream_AddRef(*ppstm
);
2848 hr
= IStream_Seek(*ppstm
, pos
, STREAM_SEEK_SET
, NULL
);
2849 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
2850 hr
= IStream_SetSize(*ppstm
, size
);
2851 ok(hr
== S_OK
, "IStream_SetSize returned %x\n", hr
);
2855 static HRESULT WINAPI
Storage_OpenStream(IStorage
*iface
, LPCOLESTR pwcsName
, void *reserved1
, DWORD grfMode
, DWORD reserved2
, IStream
**ppstm
)
2857 static const WCHAR ole1W
[] = {1,'O','l','e',0};
2859 LARGE_INTEGER pos
= {{0}};
2862 ok(!reserved1
, "reserved1 = %p\n", reserved1
);
2863 ok(!reserved2
, "reserved2 = %x\n", reserved2
);
2864 ok(!!ppstm
, "ppstm = NULL\n");
2866 if(!lstrcmpW(pwcsName
, comp_objW
)) {
2867 CHECK_EXPECT2(Storage_OpenStream_CompObj
);
2868 ok(grfMode
== STGM_SHARE_EXCLUSIVE
, "grfMode = %x\n", grfMode
);
2870 *ppstm
= comp_obj_stream
;
2871 IStream_AddRef(comp_obj_stream
);
2872 hr
= IStream_Seek(comp_obj_stream
, pos
, STREAM_SEEK_SET
, NULL
);
2873 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
2875 }else if(!lstrcmpW(pwcsName
, ole1W
)) {
2876 CHECK_EXPECT(Storage_OpenStream_Ole
);
2880 ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READ
), "grfMode = %x\n", grfMode
);
2883 return STG_E_FILENOTFOUND
;
2886 ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
2888 *ppstm
= ole_stream
;
2889 IStream_AddRef(ole_stream
);
2890 hr
= IStream_Seek(ole_stream
, pos
, STREAM_SEEK_SET
, NULL
);
2891 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
2894 }else if(!lstrcmpW(pwcsName
, olepres0W
)) {
2895 CHECK_EXPECT(Storage_OpenStream_OlePres
);
2896 ok(grfMode
== (STGM_SHARE_EXCLUSIVE
|STGM_READWRITE
), "grfMode = %x\n", grfMode
);
2898 *ppstm
= olepres_stream
;
2899 IStream_AddRef(olepres_stream
);
2900 hr
= IStream_Seek(olepres_stream
, pos
, STREAM_SEEK_SET
, NULL
);
2901 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
2905 ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName
));
2909 static HRESULT WINAPI
Storage_CreateStorage(IStorage
*iface
, LPCOLESTR pwcsName
, DWORD grfMode
, DWORD dwStgFmt
, DWORD reserved2
, IStorage
**ppstg
)
2911 ok(0, "unexpected call to CreateStorage\n");
2915 static HRESULT WINAPI
Storage_OpenStorage(IStorage
*iface
, LPCOLESTR pwcsName
, IStorage
*pstgPriority
, DWORD grfMode
, SNB snbExclude
, DWORD reserved
, IStorage
**ppstg
)
2917 ok(0, "unexpected call to OpenStorage\n");
2921 static HRESULT WINAPI
Storage_CopyTo(IStorage
*iface
, DWORD ciidExclude
, const IID
*rgiidExclude
, SNB snbExclude
, IStorage
*pstgDest
)
2923 ok(0, "unexpected call to CopyTo\n");
2927 static HRESULT WINAPI
Storage_MoveElementTo(IStorage
*iface
, LPCOLESTR pwcsName
, IStorage
*pstgDest
, LPCOLESTR pwcsNewName
, DWORD grfFlags
)
2929 ok(0, "unexpected call to MoveElementTo\n");
2933 static HRESULT WINAPI
Storage_Commit(IStorage
*iface
, DWORD grfCommitFlags
)
2935 ok(0, "unexpected call to Commit\n");
2939 static HRESULT WINAPI
Storage_Revert(IStorage
*iface
)
2941 ok(0, "unexpected call to Revert\n");
2945 static HRESULT WINAPI
Storage_EnumElements(IStorage
*iface
, DWORD reserved1
, void *reserved2
, DWORD reserved3
, IEnumSTATSTG
**ppenum
)
2947 ok(0, "unexpected call to EnumElements\n");
2951 static HRESULT WINAPI
Storage_DestroyElement(IStorage
*iface
, LPCOLESTR pwcsName
)
2956 CHECK_EXPECT2(Storage_DestroyElement
);
2957 cmp
= CompareStringW(LOCALE_NEUTRAL
, 0, pwcsName
, 8, olepres0W
, 8);
2958 ok(cmp
== CSTR_EQUAL
,
2959 "unexpected call to DestroyElement(%s)\n", wine_dbgstr_w(pwcsName
));
2961 WideCharToMultiByte(CP_ACP
, 0, pwcsName
, -1, name
, sizeof(name
), NULL
, NULL
);
2962 stream_n
= atol(name
+ 8);
2963 if (stream_n
<= Storage_DestroyElement_limit
)
2966 return STG_E_FILENOTFOUND
;
2969 static HRESULT WINAPI
Storage_RenameElement(IStorage
*iface
, LPCOLESTR pwcsOldName
, LPCOLESTR pwcsNewName
)
2971 ok(0, "unexpected call to RenameElement\n");
2975 static HRESULT WINAPI
Storage_SetElementTimes(IStorage
*iface
, LPCOLESTR pwcsName
, const FILETIME
*pctime
, const FILETIME
*patime
, const FILETIME
*pmtime
)
2977 ok(0, "unexpected call to SetElementTimes\n");
2981 static HRESULT WINAPI
Storage_SetClass(IStorage
*iface
, REFCLSID clsid
)
2983 CHECK_EXPECT(Storage_SetClass
);
2984 ok(IsEqualIID(clsid
, Storage_SetClass_CLSID
), "expected %s, got %s\n",
2985 wine_dbgstr_guid(Storage_SetClass_CLSID
), wine_dbgstr_guid(clsid
));
2989 static HRESULT WINAPI
Storage_SetStateBits(IStorage
*iface
, DWORD grfStateBits
, DWORD grfMask
)
2991 ok(0, "unexpected call to SetStateBits\n");
2995 static HRESULT WINAPI
Storage_Stat(IStorage
*iface
, STATSTG
*pstatstg
, DWORD grfStatFlag
)
2997 CHECK_EXPECT2(Storage_Stat
);
2998 ok(pstatstg
!= NULL
, "pstatstg = NULL\n");
2999 ok(grfStatFlag
== STATFLAG_NONAME
, "grfStatFlag = %x\n", grfStatFlag
);
3001 memset(pstatstg
, 0, sizeof(STATSTG
));
3002 pstatstg
->type
= STGTY_STORAGE
;
3003 pstatstg
->clsid
= CLSID_WineTestOld
;
3007 static IStorageVtbl StorageVtbl
=
3009 Storage_QueryInterface
,
3012 Storage_CreateStream
,
3014 Storage_CreateStorage
,
3015 Storage_OpenStorage
,
3017 Storage_MoveElementTo
,
3020 Storage_EnumElements
,
3021 Storage_DestroyElement
,
3022 Storage_RenameElement
,
3023 Storage_SetElementTimes
,
3025 Storage_SetStateBits
,
3029 static IStorage Storage
= { &StorageVtbl
};
3031 static void test_OleDoAutoConvert(void)
3033 static const WCHAR clsidW
[] = {'C','L','S','I','D','\\',0};
3038 DWORD ansi_user_type_len
;
3039 DWORD ansi_clipboard_format_len
;
3041 DWORD unicode_marker
;
3042 DWORD unicode_user_type_len
;
3043 DWORD unicode_clipboard_format_len
;
3049 DWORD link_update_option
;
3051 DWORD reserved_moniker_stream_size
;
3052 DWORD relative_source_moniker_stream_size
;
3053 DWORD absolute_source_moniker_stream_size
;
3054 DWORD clsid_indicator
;
3056 DWORD reserved_display_name
;
3058 DWORD local_update_time
;
3059 DWORD local_check_update_time
;
3060 DWORD remote_update_time
;
3063 LARGE_INTEGER pos
= {{0}};
3070 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &comp_obj_stream
);
3071 ok(hr
== S_OK
, "CreateStreamOnHGlobal returned %x\n", hr
);
3072 hr
= IStream_Write(comp_obj_stream
, (char*)&comp_obj_data
, sizeof(comp_obj_data
), NULL
);
3073 ok(hr
== S_OK
, "IStream_Write returned %x\n", hr
);
3075 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &ole_stream
);
3076 ok(hr
== S_OK
, "CreateStreamOnHGlobal returned %x\n", hr
);
3077 hr
= IStream_Write(ole_stream
, (char*)&ole_data
, sizeof(ole_data
), NULL
);
3078 ok(hr
== S_OK
, "IStream_Write returned %x\n", hr
);
3080 clsid
= IID_WineTest
;
3081 hr
= OleDoAutoConvert(NULL
, &clsid
);
3082 ok(hr
== E_INVALIDARG
, "OleDoAutoConvert returned %x\n", hr
);
3083 ok(IsEqualIID(&clsid
, &IID_NULL
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3085 if(0) /* crashes on Win7 */
3086 OleDoAutoConvert(&Storage
, NULL
);
3088 clsid
= IID_WineTest
;
3089 SET_EXPECT(Storage_Stat
);
3090 hr
= OleDoAutoConvert(&Storage
, &clsid
);
3091 ok(hr
== REGDB_E_CLASSNOTREG
, "OleDoAutoConvert returned %x\n", hr
);
3092 CHECK_CALLED(Storage_Stat
);
3093 ok(IsEqualIID(&clsid
, &CLSID_WineTestOld
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3095 lstrcpyW(buf
, clsidW
);
3096 StringFromGUID2(&CLSID_WineTestOld
, buf
+6, 39);
3098 ret
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, buf
, 0, NULL
, 0,
3099 KEY_READ
| KEY_WRITE
| KEY_CREATE_SUB_KEY
, NULL
, &root
, NULL
);
3100 if(ret
!= ERROR_SUCCESS
) {
3101 win_skip("not enough permissions to create CLSID key (%u)\n", ret
);
3105 clsid
= IID_WineTest
;
3106 SET_EXPECT(Storage_Stat
);
3107 hr
= OleDoAutoConvert(&Storage
, &clsid
);
3108 ok(hr
== REGDB_E_KEYMISSING
, "OleDoAutoConvert returned %x\n", hr
);
3109 CHECK_CALLED(Storage_Stat
);
3110 ok(IsEqualIID(&clsid
, &CLSID_WineTestOld
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3112 hr
= OleSetAutoConvert(&CLSID_WineTestOld
, &CLSID_WineTest
);
3113 ok_ole_success(hr
, "OleSetAutoConvert");
3115 hr
= OleGetAutoConvert(&CLSID_WineTestOld
, &clsid
);
3116 ok_ole_success(hr
, "OleGetAutoConvert");
3117 ok(IsEqualIID(&clsid
, &CLSID_WineTest
), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid
));
3119 clsid
= IID_WineTest
;
3120 SET_EXPECT(Storage_Stat
);
3121 SET_EXPECT(Storage_OpenStream_CompObj
);
3122 SET_EXPECT(Storage_SetClass
);
3123 SET_EXPECT(Storage_CreateStream_CompObj
);
3124 SET_EXPECT(Storage_OpenStream_Ole
);
3125 hr
= OleDoAutoConvert(&Storage
, &clsid
);
3126 ok(hr
== S_OK
, "OleDoAutoConvert returned %x\n", hr
);
3127 CHECK_CALLED(Storage_Stat
);
3128 CHECK_CALLED(Storage_OpenStream_CompObj
);
3129 CHECK_CALLED(Storage_SetClass
);
3130 CHECK_CALLED(Storage_CreateStream_CompObj
);
3131 CHECK_CALLED(Storage_OpenStream_Ole
);
3132 ok(IsEqualIID(&clsid
, &CLSID_WineTest
), "clsid = %s\n", wine_dbgstr_guid(&clsid
));
3134 hr
= IStream_Seek(comp_obj_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3135 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3136 hr
= IStream_Read(comp_obj_stream
, &comp_obj_data
, sizeof(comp_obj_data
), NULL
);
3137 ok(hr
== S_OK
, "IStream_Read returned %x\n", hr
);
3138 ok(comp_obj_data
.reserved1
== 0xfffe0001, "reserved1 = %x\n", comp_obj_data
.reserved1
);
3139 ok(comp_obj_data
.version
== 0xa03, "version = %x\n", comp_obj_data
.version
);
3140 ok(comp_obj_data
.reserved2
[0] == -1, "reserved2[0] = %x\n", comp_obj_data
.reserved2
[0]);
3141 ok(IsEqualIID(comp_obj_data
.reserved2
+1, &CLSID_WineTestOld
), "reserved2 = %s\n", wine_dbgstr_guid((CLSID
*)(comp_obj_data
.reserved2
+1)));
3142 ok(!comp_obj_data
.ansi_user_type_len
, "ansi_user_type_len = %d\n", comp_obj_data
.ansi_user_type_len
);
3143 ok(!comp_obj_data
.ansi_clipboard_format_len
, "ansi_clipboard_format_len = %d\n", comp_obj_data
.ansi_clipboard_format_len
);
3144 ok(!comp_obj_data
.reserved3
, "reserved3 = %x\n", comp_obj_data
.reserved3
);
3145 ok(comp_obj_data
.unicode_marker
== 0x71b239f4, "unicode_marker = %x\n", comp_obj_data
.unicode_marker
);
3146 ok(!comp_obj_data
.unicode_user_type_len
, "unicode_user_type_len = %d\n", comp_obj_data
.unicode_user_type_len
);
3147 ok(!comp_obj_data
.unicode_clipboard_format_len
, "unicode_clipboard_format_len = %d\n", comp_obj_data
.unicode_clipboard_format_len
);
3148 ok(!comp_obj_data
.reserved4
, "reserved4 %d\n", comp_obj_data
.reserved4
);
3150 hr
= IStream_Seek(ole_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3151 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3152 hr
= IStream_Read(ole_stream
, &ole_data
, sizeof(ole_data
), NULL
);
3153 ok(hr
== S_OK
, "IStream_Read returned %x\n", hr
);
3154 ok(ole_data
.version
== 0, "version = %x\n", ole_data
.version
);
3155 ok(ole_data
.flags
== 4, "flags = %x\n", ole_data
.flags
);
3156 for(i
=2; i
<sizeof(ole_data
)/sizeof(DWORD
); i
++)
3157 ok(((DWORD
*)&ole_data
)[i
] == 0, "ole_data[%d] = %x\n", i
, ((DWORD
*)&ole_data
)[i
]);
3159 SET_EXPECT(Storage_OpenStream_Ole
);
3160 hr
= SetConvertStg(&Storage
, TRUE
);
3161 ok(hr
== S_OK
, "SetConvertStg returned %x\n", hr
);
3162 CHECK_CALLED(Storage_OpenStream_Ole
);
3164 SET_EXPECT(Storage_OpenStream_CompObj
);
3165 SET_EXPECT(Storage_Stat
);
3166 SET_EXPECT(Storage_CreateStream_CompObj
);
3167 hr
= WriteFmtUserTypeStg(&Storage
, 0, NULL
);
3168 ok(hr
== S_OK
, "WriteFmtUserTypeStg returned %x\n", hr
);
3169 todo_wine
CHECK_CALLED(Storage_OpenStream_CompObj
);
3170 CHECK_CALLED(Storage_Stat
);
3171 CHECK_CALLED(Storage_CreateStream_CompObj
);
3172 hr
= IStream_Seek(comp_obj_stream
, pos
, STREAM_SEEK_SET
, NULL
);
3173 ok(hr
== S_OK
, "IStream_Seek returned %x\n", hr
);
3174 hr
= IStream_Read(comp_obj_stream
, &comp_obj_data
, sizeof(comp_obj_data
), NULL
);
3175 ok(hr
== S_OK
, "IStream_Read returned %x\n", hr
);
3176 ok(comp_obj_data
.reserved1
== 0xfffe0001, "reserved1 = %x\n", comp_obj_data
.reserved1
);
3177 ok(comp_obj_data
.version
== 0xa03, "version = %x\n", comp_obj_data
.version
);
3178 ok(comp_obj_data
.reserved2
[0] == -1, "reserved2[0] = %x\n", comp_obj_data
.reserved2
[0]);
3179 ok(IsEqualIID(comp_obj_data
.reserved2
+1, &CLSID_WineTestOld
), "reserved2 = %s\n", wine_dbgstr_guid((CLSID
*)(comp_obj_data
.reserved2
+1)));
3180 ok(!comp_obj_data
.ansi_user_type_len
, "ansi_user_type_len = %d\n", comp_obj_data
.ansi_user_type_len
);
3181 ok(!comp_obj_data
.ansi_clipboard_format_len
, "ansi_clipboard_format_len = %d\n", comp_obj_data
.ansi_clipboard_format_len
);
3182 ok(!comp_obj_data
.reserved3
, "reserved3 = %x\n", comp_obj_data
.reserved3
);
3183 ok(comp_obj_data
.unicode_marker
== 0x71b239f4, "unicode_marker = %x\n", comp_obj_data
.unicode_marker
);
3184 ok(!comp_obj_data
.unicode_user_type_len
, "unicode_user_type_len = %d\n", comp_obj_data
.unicode_user_type_len
);
3185 ok(!comp_obj_data
.unicode_clipboard_format_len
, "unicode_clipboard_format_len = %d\n", comp_obj_data
.unicode_clipboard_format_len
);
3186 ok(!comp_obj_data
.reserved4
, "reserved4 %d\n", comp_obj_data
.reserved4
);
3188 ret
= IStream_Release(comp_obj_stream
);
3189 ok(!ret
, "comp_obj_stream was not freed\n");
3190 ret
= IStream_Release(ole_stream
);
3191 ok(!ret
, "ole_stream was not freed\n");
3193 ret
= RegDeleteKeyA(root
, "AutoConvertTo");
3194 ok(ret
== ERROR_SUCCESS
, "RegDeleteKey error %u\n", ret
);
3195 ret
= RegDeleteKeyA(root
, "");
3196 ok(ret
== ERROR_SUCCESS
, "RegDeleteKey error %u\n", ret
);
3201 static const unsigned char bmpimage
[] =
3203 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,
3204 0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
3205 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
3206 0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
3207 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,
3208 0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
3209 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,
3210 0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
3214 static const unsigned char mf_blank_bits
[] =
3216 0x01,0x00,0x09,0x00,0x00,0x03,0x0c,0x00,
3217 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
3218 0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00
3221 static void test_data_cache_save(void)
3223 static const WCHAR contentsW
[] = { 'C','o','n','t','e','n','t','s',0 };
3229 IPersistStorage
*stg
;
3230 DWORD clipformat
[2];
3231 PresentationDataHeader hdr
;
3233 hr
= CreateILockBytesOnHGlobal(0, TRUE
, &ilb
);
3234 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3235 hr
= StgCreateDocfileOnILockBytes(ilb
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, &doc
);
3236 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3238 ILockBytes_Release(ilb
);
3240 hr
= IStorage_SetClass(doc
, &CLSID_WineTest
);
3241 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3243 hr
= IStorage_CreateStream(doc
, contentsW
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
3244 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3245 hr
= IStream_Write(stm
, bmpimage
, sizeof(bmpimage
), NULL
);
3246 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3247 IStream_Release(stm
);
3249 hr
= IStorage_CreateStream(doc
, olepres0W
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
3250 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3253 clipformat
[1] = CF_METAFILEPICT
;
3254 hr
= IStream_Write(stm
, clipformat
, sizeof(clipformat
), NULL
);
3255 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3258 hdr
.dvAspect
= DVASPECT_CONTENT
;
3260 hdr
.advf
= ADVF_PRIMEFIRST
;
3262 hdr
.dwObjectExtentX
= 0;
3263 hdr
.dwObjectExtentY
= 0;
3264 hdr
.dwSize
= sizeof(mf_blank_bits
);
3265 hr
= IStream_Write(stm
, &hdr
, sizeof(hdr
), NULL
);
3266 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3267 hr
= IStream_Write(stm
, mf_blank_bits
, sizeof(mf_blank_bits
), NULL
);
3268 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3270 IStream_Release(stm
);
3272 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IUnknown
, (void **)&cache
);
3273 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3274 hr
= IOleCache2_QueryInterface(cache
, &IID_IPersistStorage
, (void **)&stg
);
3275 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3276 hr
= IPersistStorage_Load(stg
, doc
);
3277 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3279 IStorage_Release(doc
);
3281 hr
= IPersistStorage_IsDirty(stg
);
3282 ok(hr
== S_FALSE
, "unexpected %#x\n", hr
);
3285 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &olepres_stream
);
3286 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3288 /* FIXME: remove this stream once Wine is fixed */
3289 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &contents_stream
);
3290 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3292 SET_EXPECT(Storage_CreateStream_OlePres
);
3293 SET_EXPECT(Storage_OpenStream_OlePres
);
3294 SET_EXPECT(Storage_OpenStream_Ole
);
3295 SET_EXPECT(Storage_DestroyElement
);
3296 Storage_DestroyElement_limit
= 50;
3297 Storage_SetClass_CLSID
= &CLSID_NULL
;
3298 trace("IPersistStorage_Save:\n");
3299 hr
= IPersistStorage_Save(stg
, &Storage
, FALSE
);
3300 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3301 CHECK_CALLED(Storage_CreateStream_OlePres
);
3303 CHECK_CALLED(Storage_OpenStream_OlePres
);
3305 CHECK_CALLED(Storage_OpenStream_Ole
);
3307 CHECK_CALLED(Storage_DestroyElement
);
3309 IStream_Release(olepres_stream
);
3310 IStream_Release(contents_stream
);
3312 IPersistStorage_Release(stg
);
3313 IOleCache2_Release(cache
);
3316 #define MAX_STREAM 16
3332 struct stream_def stream
[MAX_STREAM
];
3335 static const struct storage_def stg_def_0
=
3338 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) }}
3340 static const struct storage_def stg_def_0_saved
=
3342 &CLSID_NULL
, 0, {{ 0 }}
3344 static const struct storage_def stg_def_1
=
3347 {{ "Contents", -1, 0, 0, NULL
, 0 },
3348 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3350 static const struct storage_def stg_def_1_saved
=
3353 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3355 static const struct storage_def stg_def_2
=
3357 &CLSID_ManualResetEvent
, 2,
3358 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3359 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3361 static const struct storage_def stg_def_2_saved
=
3364 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3366 static const struct storage_def stg_def_3
=
3369 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3370 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3371 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3372 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3373 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3375 static const struct storage_def stg_def_3_saved
=
3378 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3379 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3380 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) }}
3382 static const struct storage_def stg_def_4
=
3384 &CLSID_Picture_EnhMetafile
, 5,
3385 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3386 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3387 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3388 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3389 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3391 static const struct storage_def stg_def_4_saved
=
3394 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3396 static const struct storage_def stg_def_5
=
3398 &CLSID_Picture_Dib
, 5,
3399 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3400 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3401 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3402 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3403 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3405 static const struct storage_def stg_def_5_saved
=
3408 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3410 static const struct storage_def stg_def_6
=
3412 &CLSID_Picture_Metafile
, 5,
3413 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) },
3414 { "\2OlePres001", CF_METAFILEPICT
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, mf_blank_bits
, sizeof(mf_blank_bits
) },
3415 { "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 },
3416 { "\2OlePres002", CF_DIB
, DVASPECT_CONTENT
, ADVF_PRIMEFIRST
, bmpimage
, sizeof(bmpimage
) },
3417 { "MyStream", -1, 0, 0, "Hello World!", 13 }}
3419 static const struct storage_def stg_def_6_saved
=
3422 {{ "\2OlePres000", 0, DVASPECT_ICON
, ADVF_PRIMEFIRST
| ADVF_ONLYONCE
, NULL
, 0 }}
3424 static const struct storage_def stg_def_7
=
3426 &CLSID_Picture_Dib
, 1,
3427 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) }}
3429 static const struct storage_def stg_def_7_saved
=
3431 &CLSID_NULL
, 0, {{ 0 }}
3433 static const struct storage_def stg_def_8
=
3435 &CLSID_Picture_Metafile
, 1,
3436 {{ "Contents", -1, 0, 0, mf_blank_bits
, sizeof(mf_blank_bits
) }}
3438 static const struct storage_def stg_def_8_saved
=
3440 &CLSID_NULL
, 0, {{ 0 }}
3442 static const struct storage_def stg_def_9
=
3444 &CLSID_Picture_EnhMetafile
, 1,
3445 {{ "Contents", -1, 0, 0, bmpimage
, sizeof(bmpimage
) }}
3447 static const struct storage_def stg_def_9_saved
=
3449 &CLSID_NULL
, 0, {{ 0 }}
3452 static int read_clipformat(IStream
*stream
)
3456 int length
, clipformat
= -2;
3458 hr
= IStream_Read(stream
, &length
, sizeof(length
), &bytes
);
3459 if (hr
!= S_OK
|| bytes
!= sizeof(length
))
3465 hr
= IStream_Read(stream
, &clipformat
, sizeof(clipformat
), &bytes
);
3466 if (hr
!= S_OK
|| bytes
!= sizeof(clipformat
))
3470 ok(0, "unhandled clipformat length %d\n", length
);
3475 static void check_storage_contents(IStorage
*stg
, const struct storage_def
*stg_def
,
3476 int *enumerated_streams
, int *matched_streams
)
3479 IEnumSTATSTG
*enumstg
;
3482 int i
, seen_stream
[MAX_STREAM
] = { 0 };
3484 if (winetest_debug
> 1)
3485 trace("check_storage_contents:\n=============================================\n");
3487 *enumerated_streams
= 0;
3488 *matched_streams
= 0;
3490 hr
= IStorage_Stat(stg
, &stat
, STATFLAG_NONAME
);
3491 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3492 ok(IsEqualCLSID(stg_def
->clsid
, &stat
.clsid
), "expected %s, got %s\n",
3493 wine_dbgstr_guid(stg_def
->clsid
), wine_dbgstr_guid(&stat
.clsid
));
3495 hr
= IStorage_EnumElements(stg
, 0, NULL
, 0, &enumstg
);
3496 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3501 int clipformat
= -1;
3502 PresentationDataHeader header
;
3506 memset(&header
, 0, sizeof(header
));
3508 hr
= IEnumSTATSTG_Next(enumstg
, 1, &stat
, NULL
);
3509 if(hr
== S_FALSE
) break;
3510 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3512 if (winetest_debug
> 1)
3513 trace("name %s, type %u, size %d, clsid %s\n",
3514 wine_dbgstr_w(stat
.pwcsName
), stat
.type
, stat
.cbSize
.u
.LowPart
, wine_dbgstr_guid(&stat
.clsid
));
3516 ok(stat
.type
== STGTY_STREAM
, "unexpected %#x\n", stat
.type
);
3518 WideCharToMultiByte(CP_ACP
, 0, stat
.pwcsName
, -1, name
, sizeof(name
), NULL
, NULL
);
3520 hr
= IStorage_OpenStream(stg
, stat
.pwcsName
, NULL
, STGM_READ
| STGM_SHARE_EXCLUSIVE
, 0, &stream
);
3521 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3523 if (!memcmp(name
, "\2OlePres", 7))
3525 clipformat
= read_clipformat(stream
);
3527 hr
= IStream_Read(stream
, &header
, sizeof(header
), &bytes
);
3528 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3529 ok(bytes
>= 24, "read %u bytes\n", bytes
);
3531 if (winetest_debug
> 1)
3532 trace("header: unknown3 %#x, dvAspect %#x, lindex %#x, advf %#x, unknown7 %#x, dwObjectExtentX %#x, dwObjectExtentY %#x, dwSize %#x\n",
3533 header
.unknown3
, header
.dvAspect
, header
.lindex
, header
.advf
, header
.unknown7
,
3534 header
.dwObjectExtentX
, header
.dwObjectExtentY
, header
.dwSize
);
3537 memset(data
, 0, sizeof(data
));
3538 hr
= IStream_Read(stream
, data
, sizeof(data
), &bytes
);
3539 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3540 if (winetest_debug
> 1)
3541 trace("stream data (%u bytes): %02x %02x %02x %02x\n", bytes
, data
[0], data
[1], data
[2], data
[3]);
3543 for (i
= 0; i
< stg_def
->stream_count
; i
++)
3545 if (seen_stream
[i
]) continue;
3547 if (winetest_debug
> 1)
3548 trace("%s/%s, %d/%d, %d/%d, %d/%d\n",
3549 stg_def
->stream
[i
].name
, name
,
3550 stg_def
->stream
[i
].cf
, clipformat
,
3551 stg_def
->stream
[i
].dvAspect
, header
.dvAspect
,
3552 stg_def
->stream
[i
].advf
, header
.advf
);
3554 if (!strcmp(stg_def
->stream
[i
].name
, name
) &&
3555 stg_def
->stream
[i
].cf
== clipformat
&&
3556 stg_def
->stream
[i
].dvAspect
== header
.dvAspect
&&
3557 stg_def
->stream
[i
].advf
== header
.advf
&&
3558 stg_def
->stream
[i
].data_size
<= bytes
&&
3559 (!stg_def
->stream
[i
].data_size
||
3560 (!memcmp(stg_def
->stream
[i
].data
, data
, min(stg_def
->stream
[i
].data_size
, bytes
)))))
3562 if (winetest_debug
> 1)
3563 trace("stream %d matches def stream %d\n", *enumerated_streams
, i
);
3565 *matched_streams
+= 1;
3569 CoTaskMemFree(stat
.pwcsName
);
3570 IStream_Release(stream
);
3572 *enumerated_streams
+= 1;
3576 static IStorage
*create_storage_from_def(const struct storage_def
*stg_def
)
3583 hr
= StgCreateDocfile(NULL
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &stg
);
3584 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3586 hr
= IStorage_SetClass(stg
, stg_def
->clsid
);
3587 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3589 for (i
= 0; i
< stg_def
->stream_count
; i
++)
3593 MultiByteToWideChar(CP_ACP
, 0, stg_def
->stream
[i
].name
, -1, name
, 32);
3594 hr
= IStorage_CreateStream(stg
, name
, STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
, 0, 0, &stm
);
3595 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3597 if (stg_def
->stream
[i
].cf
!= -1)
3600 PresentationDataHeader hdr
;
3602 if (stg_def
->stream
[i
].cf
)
3605 clipformat
[1] = stg_def
->stream
[i
].cf
;
3606 hr
= IStream_Write(stm
, clipformat
, sizeof(clipformat
), NULL
);
3611 hr
= IStream_Write(stm
, &clipformat
[0], sizeof(clipformat
[0]), NULL
);
3613 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3616 hdr
.dvAspect
= stg_def
->stream
[i
].dvAspect
;
3618 hdr
.advf
= stg_def
->stream
[i
].advf
;
3620 hdr
.dwObjectExtentX
= 0;
3621 hdr
.dwObjectExtentY
= 0;
3622 hdr
.dwSize
= stg_def
->stream
[i
].data_size
;
3623 hr
= IStream_Write(stm
, &hdr
, sizeof(hdr
), NULL
);
3624 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3627 if (stg_def
->stream
[i
].data_size
)
3629 hr
= IStream_Write(stm
, stg_def
->stream
[i
].data
, stg_def
->stream
[i
].data_size
, NULL
);
3630 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3633 IStream_Release(stm
);
3639 static void test_data_cache_contents(void)
3642 IStorage
*doc1
, *doc2
;
3644 IPersistStorage
*stg
;
3645 int i
, enumerated_streams
, matched_streams
;
3648 const struct storage_def
*in
;
3649 const struct storage_def
*out
;
3652 { &stg_def_0
, &stg_def_0_saved
},
3653 { &stg_def_1
, &stg_def_1_saved
},
3654 { &stg_def_2
, &stg_def_2_saved
},
3655 { &stg_def_3
, &stg_def_3_saved
},
3656 { &stg_def_4
, &stg_def_4_saved
},
3657 { &stg_def_5
, &stg_def_5_saved
},
3658 { &stg_def_6
, &stg_def_6_saved
},
3659 { &stg_def_7
, &stg_def_7_saved
},
3660 { &stg_def_8
, &stg_def_8_saved
},
3661 { &stg_def_9
, &stg_def_9_saved
},
3664 for (i
= 0; i
< sizeof(test_data
)/sizeof(test_data
[0]); i
++)
3666 if (winetest_debug
> 1)
3667 trace("start testing storage def %d\n", i
);
3669 doc1
= create_storage_from_def(test_data
[i
].in
);
3670 if (!doc1
) continue;
3672 enumerated_streams
= matched_streams
= -1;
3673 check_storage_contents(doc1
, test_data
[i
].in
, &enumerated_streams
, &matched_streams
);
3674 ok(enumerated_streams
== matched_streams
, "%d in: enumerated %d != matched %d\n", i
,
3675 enumerated_streams
, matched_streams
);
3676 ok(enumerated_streams
== test_data
[i
].in
->stream_count
, "%d: created %d != def streams %d\n", i
,
3677 enumerated_streams
, test_data
[i
].in
->stream_count
);
3679 hr
= CreateDataCache(NULL
, &CLSID_NULL
, &IID_IUnknown
, (void **)&cache
);
3680 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3681 hr
= IOleCache2_QueryInterface(cache
, &IID_IPersistStorage
, (void **)&stg
);
3682 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3683 hr
= IPersistStorage_Load(stg
, doc1
);
3684 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3686 IStorage_Release(doc1
);
3688 hr
= StgCreateDocfile(NULL
, STGM_CREATE
| STGM_READWRITE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &doc2
);
3689 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3691 hr
= IPersistStorage_IsDirty(stg
);
3692 todo_wine_if(test_data
[i
].in
== &stg_def_4
|| test_data
[i
].in
== &stg_def_8
|| test_data
[i
].in
== &stg_def_9
)
3693 ok(hr
== S_FALSE
, "%d: unexpected %#x\n", i
, hr
);
3695 hr
= IPersistStorage_Save(stg
, doc2
, FALSE
);
3696 ok(hr
== S_OK
, "unexpected %#x\n", hr
);
3698 IPersistStorage_Release(stg
);
3700 enumerated_streams
= matched_streams
= -1;
3701 check_storage_contents(doc2
, test_data
[i
].out
, &enumerated_streams
, &matched_streams
);
3702 todo_wine_if(!(test_data
[i
].in
== &stg_def_0
|| test_data
[i
].in
== &stg_def_1
|| test_data
[i
].in
== &stg_def_2
))
3703 ok(enumerated_streams
== matched_streams
, "%d out: enumerated %d != matched %d\n", i
,
3704 enumerated_streams
, matched_streams
);
3705 todo_wine_if(!(test_data
[i
].in
== &stg_def_0
|| test_data
[i
].in
== &stg_def_5
))
3706 ok(enumerated_streams
== test_data
[i
].out
->stream_count
, "%d: saved streams %d != def streams %d\n", i
,
3707 enumerated_streams
, test_data
[i
].out
->stream_count
);
3709 IStorage_Release(doc2
);
3711 if (winetest_debug
> 1)
3712 trace("done testing storage def %d\n", i
);
3723 cf_test_1
= RegisterClipboardFormatA("cf_winetest_1");
3724 cf_test_2
= RegisterClipboardFormatA("cf_winetest_2");
3725 cf_test_3
= RegisterClipboardFormatA("cf_winetest_3");
3729 hr
= CoRegisterClassObject(&CLSID_Equation3
, (IUnknown
*)&OleObjectCF
, CLSCTX_INPROC_SERVER
, REGCLS_MULTIPLEUSE
, &dwRegister
);
3730 ok_ole_success(hr
, "CoRegisterClassObject");
3732 hr
= StgCreateDocfile(NULL
, STGM_READWRITE
| STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_DELETEONRELEASE
, 0, &pStorage
);
3733 ok_ole_success(hr
, "StgCreateDocfile");
3735 test_OleCreate(pStorage
);
3737 hr
= IStorage_Stat(pStorage
, &statstg
, STATFLAG_NONAME
);
3738 ok_ole_success(hr
, "IStorage_Stat");
3739 ok(IsEqualCLSID(&CLSID_Equation3
, &statstg
.clsid
), "Wrong CLSID in storage\n");
3741 test_OleLoad(pStorage
);
3743 IStorage_Release(pStorage
);
3745 hr
= CoRevokeClassObject(dwRegister
);
3746 ok_ole_success(hr
, "CoRevokeClassObject");
3748 Storage_SetClass_CLSID
= &CLSID_WineTest
;
3751 test_data_cache_dib_contents_stream( 0 );
3752 test_data_cache_dib_contents_stream( 1 );
3753 test_data_cache_bitmap();
3754 test_data_cache_init();
3755 test_data_cache_initnew();
3756 test_default_handler();
3759 test_OleLockRunning();
3761 test_OleDoAutoConvert();
3762 test_data_cache_save();
3763 test_data_cache_contents();