| /* | |
| * Object Linking and Embedding Tests | |
| * | |
| * Copyright 2005 Robert Shearman | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| */ | |
| #define COBJMACROS | |
| #define CONST_VTABLE | |
| #define WIN32_LEAN_AND_MEAN | |
| #include <stdarg.h> | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "wingdi.h" | |
| #include "objbase.h" | |
| #include "shlguid.h" | |
| #include "wine/test.h" | |
| #include "initguid.h" | |
| DEFINE_GUID(CLSID_Picture_Metafile,0x315,0,0,0xc0,0,0,0,0,0,0,0x46); | |
| DEFINE_GUID(CLSID_Picture_Dib,0x316,0,0,0xc0,0,0,0,0,0,0,0x46); | |
| DEFINE_GUID(CLSID_Picture_EnhMetafile,0x319,0,0,0xc0,0,0,0,0,0,0,0x46); | |
| #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) | |
| #define DEFINE_EXPECT(func) \ | |
| static BOOL expect_ ## func = FALSE, called_ ## func = FALSE | |
| #define SET_EXPECT(func) \ | |
| expect_ ## func = TRUE | |
| #define CHECK_EXPECT2(func) \ | |
| do { \ | |
| ok(expect_ ##func, "unexpected call " #func "\n"); \ | |
| called_ ## func = TRUE; \ | |
| }while(0) | |
| #define CHECK_EXPECT(func) \ | |
| do { \ | |
| CHECK_EXPECT2(func); \ | |
| expect_ ## func = FALSE; \ | |
| }while(0) | |
| #define CHECK_CALLED(func) \ | |
| do { \ | |
| ok(called_ ## func, "expected " #func "\n"); \ | |
| expect_ ## func = called_ ## func = FALSE; \ | |
| }while(0) | |
| DEFINE_EXPECT(Storage_Stat); | |
| DEFINE_EXPECT(Storage_OpenStream_CompObj); | |
| DEFINE_EXPECT(Storage_SetClass); | |
| DEFINE_EXPECT(Storage_CreateStream_CompObj); | |
| DEFINE_EXPECT(Storage_OpenStream_Ole); | |
| static IPersistStorage OleObjectPersistStg; | |
| static IOleCache *cache; | |
| static IRunnableObject *runnable; | |
| static const CLSID CLSID_WineTestOld = | |
| { /* 9474ba1a-258b-490b-bc13-516e9239acd0 */ | |
| 0x9474ba1a, | |
| 0x258b, | |
| 0x490b, | |
| {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xd0} | |
| }; | |
| static const CLSID CLSID_WineTest = | |
| { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */ | |
| 0x9474ba1a, | |
| 0x258b, | |
| 0x490b, | |
| {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0} | |
| }; | |
| static const IID IID_WineTest = | |
| { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */ | |
| 0x9474ba1a, | |
| 0x258b, | |
| 0x490b, | |
| {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1} | |
| }; | |
| #define TEST_OPTIONAL 0x1 | |
| #define TEST_TODO 0x2 | |
| struct expected_method | |
| { | |
| const char *method; | |
| unsigned int flags; | |
| }; | |
| static const struct expected_method *expected_method_list; | |
| static FORMATETC *g_expected_fetc = NULL; | |
| static BOOL g_showRunnable = TRUE; | |
| static BOOL g_isRunning = TRUE; | |
| static HRESULT g_GetMiscStatusFailsWith = S_OK; | |
| static HRESULT g_QIFailsWith; | |
| static UINT cf_test_1, cf_test_2, cf_test_3; | |
| /**************************************************************************** | |
| * PresentationDataHeader | |
| * | |
| * This structure represents the header of the \002OlePresXXX stream in | |
| * the OLE object storage. | |
| */ | |
| typedef struct PresentationDataHeader | |
| { | |
| /* clipformat: | |
| * - standard clipformat: | |
| * DWORD length = 0xffffffff; | |
| * DWORD cfFormat; | |
| * - or custom clipformat: | |
| * DWORD length; | |
| * CHAR format_name[length]; (null-terminated) | |
| */ | |
| DWORD unknown3; /* 4, possibly TYMED_ISTREAM */ | |
| DVASPECT dvAspect; | |
| DWORD lindex; | |
| DWORD advf; | |
| DWORD unknown7; /* 0 */ | |
| DWORD dwObjectExtentX; | |
| DWORD dwObjectExtentY; | |
| DWORD dwSize; | |
| } PresentationDataHeader; | |
| #define CHECK_EXPECTED_METHOD(method_name) \ | |
| do { \ | |
| trace("%s\n", method_name); \ | |
| ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \ | |
| if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \ | |
| { \ | |
| todo_wine ok(0, "Too many method calls.\n"); \ | |
| break; \ | |
| } \ | |
| if (expected_method_list->method) \ | |
| { \ | |
| while (expected_method_list->flags & TEST_OPTIONAL && \ | |
| strcmp(expected_method_list->method, method_name) != 0) \ | |
| expected_method_list++; \ | |
| todo_wine_if (expected_method_list->flags & TEST_TODO) \ | |
| ok(!strcmp(expected_method_list->method, method_name), \ | |
| "Expected %s to be called instead of %s\n", \ | |
| expected_method_list->method, method_name); \ | |
| expected_method_list++; \ | |
| } \ | |
| } while(0) | |
| #define CHECK_NO_EXTRA_METHODS() \ | |
| do { \ | |
| while (expected_method_list->flags & TEST_OPTIONAL) \ | |
| expected_method_list++; \ | |
| ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \ | |
| } while (0) | |
| static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_QueryInterface"); | |
| *ppv = NULL; | |
| if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject)) | |
| *ppv = iface; | |
| else if (IsEqualIID(riid, &IID_IPersistStorage)) | |
| *ppv = &OleObjectPersistStg; | |
| else if (IsEqualIID(riid, &IID_IOleCache)) | |
| *ppv = cache; | |
| else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable) | |
| *ppv = runnable; | |
| else if (IsEqualIID(riid, &IID_WineTest)) | |
| return g_QIFailsWith; | |
| if(*ppv) { | |
| IUnknown_AddRef((IUnknown*)*ppv); | |
| return S_OK; | |
| } | |
| trace("OleObject_QueryInterface: returning E_NOINTERFACE\n"); | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI OleObject_AddRef(IOleObject *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_AddRef"); | |
| return 2; | |
| } | |
| static ULONG WINAPI OleObject_Release(IOleObject *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_Release"); | |
| return 1; | |
| } | |
| static HRESULT WINAPI OleObject_SetClientSite | |
| ( | |
| IOleObject *iface, | |
| IOleClientSite *pClientSite | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_SetClientSite"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_GetClientSite | |
| ( | |
| IOleObject *iface, | |
| IOleClientSite **ppClientSite | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_GetClientSite"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleObject_SetHostNames | |
| ( | |
| IOleObject *iface, | |
| LPCOLESTR szContainerApp, | |
| LPCOLESTR szContainerObj | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_SetHostNames"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_Close | |
| ( | |
| IOleObject *iface, | |
| DWORD dwSaveOption | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_Close"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_SetMoniker | |
| ( | |
| IOleObject *iface, | |
| DWORD dwWhichMoniker, | |
| IMoniker *pmk | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_SetMoniker"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_GetMoniker | |
| ( | |
| IOleObject *iface, | |
| DWORD dwAssign, | |
| DWORD dwWhichMoniker, | |
| IMoniker **ppmk | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_GetMoniker"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_InitFromData | |
| ( | |
| IOleObject *iface, | |
| IDataObject *pDataObject, | |
| BOOL fCreation, | |
| DWORD dwReserved | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_InitFromData"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_GetClipboardData | |
| ( | |
| IOleObject *iface, | |
| DWORD dwReserved, | |
| IDataObject **ppDataObject | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_GetClipboardData"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleObject_DoVerb | |
| ( | |
| IOleObject *iface, | |
| LONG iVerb, | |
| LPMSG lpmsg, | |
| IOleClientSite *pActiveSite, | |
| LONG lindex, | |
| HWND hwndParent, | |
| LPCRECT lprcPosRect | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_DoVerb"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_EnumVerbs | |
| ( | |
| IOleObject *iface, | |
| IEnumOLEVERB **ppEnumOleVerb | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_EnumVerbs"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleObject_Update | |
| ( | |
| IOleObject *iface | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_Update"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_IsUpToDate | |
| ( | |
| IOleObject *iface | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_IsUpToDate"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_GetUserClassID | |
| ( | |
| IOleObject *iface, | |
| CLSID *pClsid | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_GetUserClassID"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleObject_GetUserType | |
| ( | |
| IOleObject *iface, | |
| DWORD dwFormOfType, | |
| LPOLESTR *pszUserType | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_GetUserType"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleObject_SetExtent | |
| ( | |
| IOleObject *iface, | |
| DWORD dwDrawAspect, | |
| SIZEL *psizel | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_SetExtent"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_GetExtent | |
| ( | |
| IOleObject *iface, | |
| DWORD dwDrawAspect, | |
| SIZEL *psizel | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_GetExtent"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleObject_Advise | |
| ( | |
| IOleObject *iface, | |
| IAdviseSink *pAdvSink, | |
| DWORD *pdwConnection | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_Advise"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_Unadvise | |
| ( | |
| IOleObject *iface, | |
| DWORD dwConnection | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_Unadvise"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObject_EnumAdvise | |
| ( | |
| IOleObject *iface, | |
| IEnumSTATDATA **ppenumAdvise | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_EnumAdvise"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleObject_GetMiscStatus | |
| ( | |
| IOleObject *iface, | |
| DWORD aspect, | |
| DWORD *pdwStatus | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus"); | |
| ok(aspect == DVASPECT_CONTENT, "got aspect %d\n", aspect); | |
| if (g_GetMiscStatusFailsWith == S_OK) | |
| { | |
| *pdwStatus = OLEMISC_RECOMPOSEONRESIZE; | |
| return S_OK; | |
| } | |
| else | |
| { | |
| *pdwStatus = 0x1234; | |
| return g_GetMiscStatusFailsWith; | |
| } | |
| } | |
| static HRESULT WINAPI OleObject_SetColorScheme | |
| ( | |
| IOleObject *iface, | |
| LOGPALETTE *pLogpal | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObject_SetColorScheme"); | |
| return E_NOTIMPL; | |
| } | |
| static const IOleObjectVtbl OleObjectVtbl = | |
| { | |
| OleObject_QueryInterface, | |
| OleObject_AddRef, | |
| OleObject_Release, | |
| OleObject_SetClientSite, | |
| OleObject_GetClientSite, | |
| OleObject_SetHostNames, | |
| OleObject_Close, | |
| OleObject_SetMoniker, | |
| OleObject_GetMoniker, | |
| OleObject_InitFromData, | |
| OleObject_GetClipboardData, | |
| OleObject_DoVerb, | |
| OleObject_EnumVerbs, | |
| OleObject_Update, | |
| OleObject_IsUpToDate, | |
| OleObject_GetUserClassID, | |
| OleObject_GetUserType, | |
| OleObject_SetExtent, | |
| OleObject_GetExtent, | |
| OleObject_Advise, | |
| OleObject_Unadvise, | |
| OleObject_EnumAdvise, | |
| OleObject_GetMiscStatus, | |
| OleObject_SetColorScheme | |
| }; | |
| static IOleObject OleObject = { &OleObjectVtbl }; | |
| static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv) | |
| { | |
| trace("OleObjectPersistStg_QueryInterface\n"); | |
| return IOleObject_QueryInterface(&OleObject, riid, ppv); | |
| } | |
| static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef"); | |
| return 2; | |
| } | |
| static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release"); | |
| return 1; | |
| } | |
| static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleObjectPersistStg_IsDirty | |
| ( | |
| IPersistStorage *iface | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectPersistStg_InitNew | |
| ( | |
| IPersistStorage *iface, | |
| IStorage *pStg | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectPersistStg_Load | |
| ( | |
| IPersistStorage *iface, | |
| IStorage *pStg | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectPersistStg_Save | |
| ( | |
| IPersistStorage *iface, | |
| IStorage *pStgSave, | |
| BOOL fSameAsLoad | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectPersistStg_SaveCompleted | |
| ( | |
| IPersistStorage *iface, | |
| IStorage *pStgNew | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage | |
| ( | |
| IPersistStorage *iface | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage"); | |
| return S_OK; | |
| } | |
| static const IPersistStorageVtbl OleObjectPersistStgVtbl = | |
| { | |
| OleObjectPersistStg_QueryInterface, | |
| OleObjectPersistStg_AddRef, | |
| OleObjectPersistStg_Release, | |
| OleObjectPersistStg_GetClassId, | |
| OleObjectPersistStg_IsDirty, | |
| OleObjectPersistStg_InitNew, | |
| OleObjectPersistStg_Load, | |
| OleObjectPersistStg_Save, | |
| OleObjectPersistStg_SaveCompleted, | |
| OleObjectPersistStg_HandsOffStorage | |
| }; | |
| static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl }; | |
| static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv) | |
| { | |
| return IOleObject_QueryInterface(&OleObject, riid, ppv); | |
| } | |
| static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectCache_AddRef"); | |
| return 2; | |
| } | |
| static ULONG WINAPI OleObjectCache_Release(IOleCache *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectCache_Release"); | |
| return 1; | |
| } | |
| static HRESULT WINAPI OleObjectCache_Cache | |
| ( | |
| IOleCache *iface, | |
| FORMATETC *pformatetc, | |
| DWORD advf, | |
| DWORD *pdwConnection | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectCache_Cache"); | |
| if (g_expected_fetc) { | |
| ok(pformatetc != NULL, "pformatetc should not be NULL\n"); | |
| if (pformatetc) { | |
| ok(pformatetc->cfFormat == g_expected_fetc->cfFormat, | |
| "cfFormat: %x\n", pformatetc->cfFormat); | |
| ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL), | |
| "ptd: %p\n", pformatetc->ptd); | |
| ok(pformatetc->dwAspect == g_expected_fetc->dwAspect, | |
| "dwAspect: %x\n", pformatetc->dwAspect); | |
| ok(pformatetc->lindex == g_expected_fetc->lindex, | |
| "lindex: %x\n", pformatetc->lindex); | |
| ok(pformatetc->tymed == g_expected_fetc->tymed, | |
| "tymed: %x\n", pformatetc->tymed); | |
| } | |
| } else | |
| ok(pformatetc == NULL, "pformatetc should be NULL\n"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectCache_Uncache | |
| ( | |
| IOleCache *iface, | |
| DWORD dwConnection | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectCache_Uncache"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectCache_EnumCache | |
| ( | |
| IOleCache *iface, | |
| IEnumSTATDATA **ppenumSTATDATA | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectCache_InitCache | |
| ( | |
| IOleCache *iface, | |
| IDataObject *pDataObject | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectCache_InitCache"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectCache_SetData | |
| ( | |
| IOleCache *iface, | |
| FORMATETC *pformatetc, | |
| STGMEDIUM *pmedium, | |
| BOOL fRelease | |
| ) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectCache_SetData"); | |
| return S_OK; | |
| } | |
| static const IOleCacheVtbl OleObjectCacheVtbl = | |
| { | |
| OleObjectCache_QueryInterface, | |
| OleObjectCache_AddRef, | |
| OleObjectCache_Release, | |
| OleObjectCache_Cache, | |
| OleObjectCache_Uncache, | |
| OleObjectCache_EnumCache, | |
| OleObjectCache_InitCache, | |
| OleObjectCache_SetData | |
| }; | |
| static IOleCache OleObjectCache = { &OleObjectCacheVtbl }; | |
| static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) | |
| { | |
| if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) | |
| { | |
| *ppv = iface; | |
| IClassFactory_AddRef(iface); | |
| return S_OK; | |
| } | |
| *ppv = NULL; | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface) | |
| { | |
| return 2; | |
| } | |
| static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface) | |
| { | |
| return 1; | |
| } | |
| static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv) | |
| { | |
| return IOleObject_QueryInterface(&OleObject, riid, ppv); | |
| } | |
| static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock) | |
| { | |
| return S_OK; | |
| } | |
| static const IClassFactoryVtbl OleObjectCFVtbl = | |
| { | |
| OleObjectCF_QueryInterface, | |
| OleObjectCF_AddRef, | |
| OleObjectCF_Release, | |
| OleObjectCF_CreateInstance, | |
| OleObjectCF_LockServer | |
| }; | |
| static IClassFactory OleObjectCF = { &OleObjectCFVtbl }; | |
| static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv) | |
| { | |
| return IOleObject_QueryInterface(&OleObject, riid, ppv); | |
| } | |
| static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef"); | |
| return 2; | |
| } | |
| static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectRunnable_Release"); | |
| return 1; | |
| } | |
| static HRESULT WINAPI OleObjectRunnable_GetRunningClass( | |
| IRunnableObject *iface, | |
| LPCLSID lpClsid) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleObjectRunnable_Run( | |
| IRunnableObject *iface, | |
| LPBINDCTX pbc) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectRunnable_Run"); | |
| return S_OK; | |
| } | |
| static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning"); | |
| return g_isRunning; | |
| } | |
| static HRESULT WINAPI OleObjectRunnable_LockRunning( | |
| IRunnableObject *iface, | |
| BOOL fLock, | |
| BOOL fLastUnlockCloses) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI OleObjectRunnable_SetContainedObject( | |
| IRunnableObject *iface, | |
| BOOL fContained) | |
| { | |
| CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject"); | |
| return S_OK; | |
| } | |
| static const IRunnableObjectVtbl OleObjectRunnableVtbl = | |
| { | |
| OleObjectRunnable_QueryInterface, | |
| OleObjectRunnable_AddRef, | |
| OleObjectRunnable_Release, | |
| OleObjectRunnable_GetRunningClass, | |
| OleObjectRunnable_Run, | |
| OleObjectRunnable_IsRunning, | |
| OleObjectRunnable_LockRunning, | |
| OleObjectRunnable_SetContainedObject | |
| }; | |
| static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl }; | |
| static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; | |
| static HRESULT WINAPI viewobject_QueryInterface(IViewObject *iface, REFIID riid, void **obj) | |
| { | |
| if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IViewObject)) | |
| { | |
| *obj = iface; | |
| return S_OK; | |
| } | |
| *obj = NULL; | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI viewobject_AddRef(IViewObject *iface) | |
| { | |
| return 2; | |
| } | |
| static ULONG WINAPI viewobject_Release(IViewObject *iface) | |
| { | |
| return 1; | |
| } | |
| static HRESULT WINAPI viewobject_Draw(IViewObject *iface, DWORD aspect, LONG index, | |
| void *paspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, | |
| LPCRECTL bounds, LPCRECTL wbounds, BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue), | |
| ULONG_PTR dwContinue) | |
| { | |
| ok(index == -1, "index=%d\n", index); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI viewobject_GetColorSet(IViewObject *iface, DWORD draw_aspect, LONG index, | |
| void *aspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **colorset) | |
| { | |
| ok(0, "unexpected call GetColorSet\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI viewobject_Freeze(IViewObject *iface, DWORD draw_aspect, LONG index, | |
| void *aspect, DWORD *freeze) | |
| { | |
| ok(0, "unexpected call Freeze\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI viewobject_Unfreeze(IViewObject *iface, DWORD freeze) | |
| { | |
| ok(0, "unexpected call Unfreeze\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI viewobject_SetAdvise(IViewObject *iface, DWORD aspects, DWORD advf, IAdviseSink *sink) | |
| { | |
| ok(0, "unexpected call SetAdvise\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI viewobject_GetAdvise(IViewObject *iface, DWORD *aspects, DWORD *advf, | |
| IAdviseSink **sink) | |
| { | |
| ok(0, "unexpected call GetAdvise\n"); | |
| return E_NOTIMPL; | |
| } | |
| static const struct IViewObjectVtbl viewobjectvtbl = { | |
| viewobject_QueryInterface, | |
| viewobject_AddRef, | |
| viewobject_Release, | |
| viewobject_Draw, | |
| viewobject_GetColorSet, | |
| viewobject_Freeze, | |
| viewobject_Unfreeze, | |
| viewobject_SetAdvise, | |
| viewobject_GetAdvise | |
| }; | |
| static IViewObject viewobject = { &viewobjectvtbl }; | |
| static void test_OleCreate(IStorage *pStorage) | |
| { | |
| HRESULT hr; | |
| IOleObject *pObject; | |
| FORMATETC formatetc; | |
| static const struct expected_method methods_olerender_none[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", TEST_OPTIONAL }, | |
| { "OleObject_Release", TEST_OPTIONAL }, | |
| { "OleObject_QueryInterface", TEST_OPTIONAL }, | |
| { "OleObjectPersistStg_AddRef", 0 }, | |
| { "OleObjectPersistStg_InitNew", 0 }, | |
| { "OleObjectPersistStg_Release", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { "OleObject_Release", TEST_OPTIONAL }, | |
| { NULL, 0 } | |
| }; | |
| static const struct expected_method methods_olerender_draw[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObjectPersistStg_AddRef", 0 }, | |
| { "OleObjectPersistStg_InitNew", 0 }, | |
| { "OleObjectPersistStg_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectRunnable_AddRef", 0 }, | |
| { "OleObjectRunnable_Run", 0 }, | |
| { "OleObjectRunnable_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectCache_AddRef", 0 }, | |
| { "OleObjectCache_Cache", 0 }, | |
| { "OleObjectCache_Release", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, | |
| { NULL, 0 } | |
| }; | |
| static const struct expected_method methods_olerender_draw_with_site[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_GetMiscStatus", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectPersistStg_AddRef", 0 }, | |
| { "OleObjectPersistStg_InitNew", 0 }, | |
| { "OleObjectPersistStg_Release", 0 }, | |
| { "OleObject_SetClientSite", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectRunnable_AddRef", 0 }, | |
| { "OleObjectRunnable_Run", 0 }, | |
| { "OleObjectRunnable_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectCache_AddRef", 0 }, | |
| { "OleObjectCache_Cache", 0 }, | |
| { "OleObjectCache_Release", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { NULL, 0 } | |
| }; | |
| static const struct expected_method methods_olerender_format[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_GetMiscStatus", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectPersistStg_AddRef", 0 }, | |
| { "OleObjectPersistStg_InitNew", 0 }, | |
| { "OleObjectPersistStg_Release", 0 }, | |
| { "OleObject_SetClientSite", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectRunnable_AddRef", 0 }, | |
| { "OleObjectRunnable_Run", 0 }, | |
| { "OleObjectRunnable_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectCache_AddRef", 0 }, | |
| { "OleObjectCache_Cache", 0 }, | |
| { "OleObjectCache_Release", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { NULL, 0 } | |
| }; | |
| static const struct expected_method methods_olerender_asis[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObjectPersistStg_AddRef", 0 }, | |
| { "OleObjectPersistStg_InitNew", 0 }, | |
| { "OleObjectPersistStg_Release", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, | |
| { NULL, 0 } | |
| }; | |
| static const struct expected_method methods_olerender_draw_no_runnable[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObjectPersistStg_AddRef", 0 }, | |
| { "OleObjectPersistStg_InitNew", 0 }, | |
| { "OleObjectPersistStg_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectCache_AddRef", 0 }, | |
| { "OleObjectCache_Cache", 0 }, | |
| { "OleObjectCache_Release", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, | |
| { NULL, 0 }, | |
| }; | |
| static const struct expected_method methods_olerender_draw_no_cache[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, | |
| { "OleObjectPersistStg_AddRef", 0 }, | |
| { "OleObjectPersistStg_InitNew", 0 }, | |
| { "OleObjectPersistStg_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectRunnable_AddRef", 0 }, | |
| { "OleObjectRunnable_Run", 0 }, | |
| { "OleObjectRunnable_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, | |
| { NULL, 0 } | |
| }; | |
| g_expected_fetc = &formatetc; | |
| formatetc.cfFormat = 0; | |
| formatetc.ptd = NULL; | |
| formatetc.dwAspect = DVASPECT_CONTENT; | |
| formatetc.lindex = -1; | |
| formatetc.tymed = TYMED_NULL; | |
| runnable = &OleObjectRunnable; | |
| cache = &OleObjectCache; | |
| expected_method_list = methods_olerender_none; | |
| trace("OleCreate with OLERENDER_NONE:\n"); | |
| hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject); | |
| ok_ole_success(hr, "OleCreate"); | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| expected_method_list = methods_olerender_draw; | |
| trace("OleCreate with OLERENDER_DRAW:\n"); | |
| hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject); | |
| ok_ole_success(hr, "OleCreate"); | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| expected_method_list = methods_olerender_draw_with_site; | |
| trace("OleCreate with OLERENDER_DRAW, with site:\n"); | |
| hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject); | |
| ok_ole_success(hr, "OleCreate"); | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| /* GetMiscStatus fails */ | |
| g_GetMiscStatusFailsWith = 0x8fafefaf; | |
| expected_method_list = methods_olerender_draw_with_site; | |
| trace("OleCreate with OLERENDER_DRAW, with site:\n"); | |
| hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject); | |
| ok_ole_success(hr, "OleCreate"); | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| g_GetMiscStatusFailsWith = S_OK; | |
| formatetc.cfFormat = CF_TEXT; | |
| formatetc.ptd = NULL; | |
| formatetc.dwAspect = DVASPECT_CONTENT; | |
| formatetc.lindex = -1; | |
| formatetc.tymed = TYMED_HGLOBAL; | |
| expected_method_list = methods_olerender_format; | |
| trace("OleCreate with OLERENDER_FORMAT:\n"); | |
| hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject); | |
| ok(hr == S_OK || | |
| broken(hr == E_INVALIDARG), /* win2k */ | |
| "OleCreate failed with error 0x%08x\n", hr); | |
| if (pObject) | |
| { | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| } | |
| expected_method_list = methods_olerender_asis; | |
| trace("OleCreate with OLERENDER_ASIS:\n"); | |
| hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject); | |
| ok_ole_success(hr, "OleCreate"); | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| formatetc.cfFormat = 0; | |
| formatetc.tymed = TYMED_NULL; | |
| runnable = NULL; | |
| expected_method_list = methods_olerender_draw_no_runnable; | |
| trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n"); | |
| hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject); | |
| ok_ole_success(hr, "OleCreate"); | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| runnable = &OleObjectRunnable; | |
| cache = NULL; | |
| expected_method_list = methods_olerender_draw_no_cache; | |
| trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n"); | |
| hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject); | |
| ok_ole_success(hr, "OleCreate"); | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| trace("end\n"); | |
| g_expected_fetc = NULL; | |
| } | |
| static void test_OleLoad(IStorage *pStorage) | |
| { | |
| HRESULT hr; | |
| IOleObject *pObject; | |
| DWORD fmt; | |
| static const struct expected_method methods_oleload[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_GetMiscStatus", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectPersistStg_AddRef", 0 }, | |
| { "OleObjectPersistStg_Load", 0 }, | |
| { "OleObjectPersistStg_Release", 0 }, | |
| { "OleObject_SetClientSite", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_GetMiscStatus", 0 }, | |
| { "OleObject_Release", 0 }, | |
| { NULL, 0 } | |
| }; | |
| /* Test once with IOleObject_GetMiscStatus failing */ | |
| expected_method_list = methods_oleload; | |
| g_GetMiscStatusFailsWith = E_FAIL; | |
| trace("OleLoad:\n"); | |
| hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject); | |
| ok(hr == S_OK || | |
| broken(hr == E_INVALIDARG), /* win98 and win2k */ | |
| "OleLoad failed with error 0x%08x\n", hr); | |
| if(pObject) | |
| { | |
| DWORD dwStatus = 0xdeadbeef; | |
| hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); | |
| ok(hr == E_FAIL, "Got 0x%08x\n", hr); | |
| ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus); | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| } | |
| g_GetMiscStatusFailsWith = S_OK; | |
| /* Test again, let IOleObject_GetMiscStatus succeed. */ | |
| expected_method_list = methods_oleload; | |
| trace("OleLoad:\n"); | |
| hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject); | |
| ok(hr == S_OK || | |
| broken(hr == E_INVALIDARG), /* win98 and win2k */ | |
| "OleLoad failed with error 0x%08x\n", hr); | |
| if (pObject) | |
| { | |
| DWORD dwStatus = 0xdeadbeef; | |
| hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); | |
| ok(hr == S_OK, "Got 0x%08x\n", hr); | |
| ok(dwStatus == 1, "Got 0x%08x\n", dwStatus); | |
| IOleObject_Release(pObject); | |
| CHECK_NO_EXTRA_METHODS(); | |
| } | |
| for (fmt = CF_TEXT; fmt < CF_MAX; fmt++) | |
| { | |
| static const WCHAR olrepres[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 }; | |
| IStorage *stg; | |
| IStream *stream; | |
| IUnknown *obj; | |
| DWORD data, i, data_size; | |
| PresentationDataHeader header; | |
| HDC hdc; | |
| HGDIOBJ hobj; | |
| RECT rc; | |
| char buf[256]; | |
| for (i = 0; i < 7; i++) | |
| { | |
| hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &stg); | |
| ok(hr == S_OK, "StgCreateDocfile error %#x\n", hr); | |
| hr = IStorage_SetClass(stg, &CLSID_WineTest); | |
| ok(hr == S_OK, "SetClass error %#x\n", hr); | |
| hr = IStorage_CreateStream(stg, olrepres, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stream); | |
| ok(hr == S_OK, "CreateStream error %#x\n", hr); | |
| data = ~0; | |
| hr = IStream_Write(stream, &data, sizeof(data), NULL); | |
| ok(hr == S_OK, "Write error %#x\n", hr); | |
| data = fmt; | |
| hr = IStream_Write(stream, &data, sizeof(data), NULL); | |
| ok(hr == S_OK, "Write error %#x\n", hr); | |
| switch (fmt) | |
| { | |
| case CF_BITMAP: | |
| /* FIXME: figure out stream format */ | |
| hobj = CreateBitmap(1, 1, 1, 1, NULL); | |
| data_size = GetBitmapBits(hobj, sizeof(buf), buf); | |
| DeleteObject(hobj); | |
| break; | |
| case CF_METAFILEPICT: | |
| case CF_ENHMETAFILE: | |
| hdc = CreateMetaFileA(NULL); | |
| hobj = CloseMetaFile(hdc); | |
| data_size = GetMetaFileBitsEx(hobj, sizeof(buf), buf); | |
| DeleteMetaFile(hobj); | |
| break; | |
| default: | |
| data_size = sizeof(buf); | |
| memset(buf, 'A', sizeof(buf)); | |
| break; | |
| } | |
| header.unknown3 = 4; | |
| header.dvAspect = DVASPECT_CONTENT; | |
| header.lindex = -1; | |
| header.advf = 1 << i; | |
| header.unknown7 = 0; | |
| header.dwObjectExtentX = 1; | |
| header.dwObjectExtentY = 1; | |
| header.dwSize = data_size; | |
| hr = IStream_Write(stream, &header, sizeof(header), NULL); | |
| ok(hr == S_OK, "Write error %#x\n", hr); | |
| hr = IStream_Write(stream, buf, data_size, NULL); | |
| ok(hr == S_OK, "Write error %#x\n", hr); | |
| IStream_Release(stream); | |
| hr = OleLoad(stg, &IID_IUnknown, NULL, (void **)&obj); | |
| /* FIXME: figure out stream format */ | |
| if (fmt == CF_BITMAP && hr != S_OK) | |
| { | |
| IStorage_Release(stg); | |
| continue; | |
| } | |
| ok(hr == S_OK, "OleLoad error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); | |
| hdc = CreateCompatibleDC(0); | |
| SetRect(&rc, 0, 0, 100, 100); | |
| hr = OleDraw(obj, DVASPECT_CONTENT, hdc, &rc); | |
| DeleteDC(hdc); | |
| if (fmt == CF_METAFILEPICT) | |
| ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); | |
| else if (fmt == CF_ENHMETAFILE) | |
| todo_wine | |
| ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); | |
| else | |
| 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); | |
| IUnknown_Release(obj); | |
| IStorage_Release(stg); | |
| } | |
| } | |
| } | |
| static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param) | |
| { | |
| CHECK_EXPECTED_METHOD("draw_continue"); | |
| return TRUE; | |
| } | |
| static BOOL STDMETHODCALLTYPE draw_continue_false(ULONG_PTR param) | |
| { | |
| CHECK_EXPECTED_METHOD("draw_continue_false"); | |
| return FALSE; | |
| } | |
| static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv) | |
| { | |
| if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown)) | |
| { | |
| *ppv = iface; | |
| IAdviseSink_AddRef(iface); | |
| return S_OK; | |
| } | |
| *ppv = NULL; | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface) | |
| { | |
| return 2; | |
| } | |
| static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface) | |
| { | |
| return 1; | |
| } | |
| static void WINAPI AdviseSink_OnDataChange( | |
| IAdviseSink *iface, | |
| FORMATETC *pFormatetc, | |
| STGMEDIUM *pStgmed) | |
| { | |
| CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange"); | |
| } | |
| static void WINAPI AdviseSink_OnViewChange( | |
| IAdviseSink *iface, | |
| DWORD dwAspect, | |
| LONG lindex) | |
| { | |
| CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange"); | |
| } | |
| static void WINAPI AdviseSink_OnRename( | |
| IAdviseSink *iface, | |
| IMoniker *pmk) | |
| { | |
| CHECK_EXPECTED_METHOD("AdviseSink_OnRename"); | |
| } | |
| static void WINAPI AdviseSink_OnSave(IAdviseSink *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("AdviseSink_OnSave"); | |
| } | |
| static void WINAPI AdviseSink_OnClose(IAdviseSink *iface) | |
| { | |
| CHECK_EXPECTED_METHOD("AdviseSink_OnClose"); | |
| } | |
| static const IAdviseSinkVtbl AdviseSinkVtbl = | |
| { | |
| AdviseSink_QueryInterface, | |
| AdviseSink_AddRef, | |
| AdviseSink_Release, | |
| AdviseSink_OnDataChange, | |
| AdviseSink_OnViewChange, | |
| AdviseSink_OnRename, | |
| AdviseSink_OnSave, | |
| AdviseSink_OnClose | |
| }; | |
| static IAdviseSink AdviseSink = { &AdviseSinkVtbl }; | |
| static HRESULT WINAPI DataObject_QueryInterface( | |
| IDataObject* iface, | |
| REFIID riid, | |
| void** ppvObject) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_QueryInterface"); | |
| if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown)) | |
| { | |
| *ppvObject = iface; | |
| return S_OK; | |
| } | |
| *ppvObject = NULL; | |
| return S_OK; | |
| } | |
| static ULONG WINAPI DataObject_AddRef( | |
| IDataObject* iface) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_AddRef"); | |
| return 2; | |
| } | |
| static ULONG WINAPI DataObject_Release( | |
| IDataObject* iface) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_Release"); | |
| return 1; | |
| } | |
| static HRESULT WINAPI DataObject_GetData( | |
| IDataObject* iface, | |
| LPFORMATETC pformatetcIn, | |
| STGMEDIUM* pmedium) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_GetData"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI DataObject_GetDataHere( | |
| IDataObject* iface, | |
| LPFORMATETC pformatetc, | |
| STGMEDIUM* pmedium) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_GetDataHere"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI DataObject_QueryGetData( | |
| IDataObject* iface, | |
| LPFORMATETC pformatetc) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_QueryGetData"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI DataObject_GetCanonicalFormatEtc( | |
| IDataObject* iface, | |
| LPFORMATETC pformatectIn, | |
| LPFORMATETC pformatetcOut) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI DataObject_SetData( | |
| IDataObject* iface, | |
| LPFORMATETC pformatetc, | |
| STGMEDIUM* pmedium, | |
| BOOL fRelease) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_SetData"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI DataObject_EnumFormatEtc( | |
| IDataObject* iface, | |
| DWORD dwDirection, | |
| IEnumFORMATETC** ppenumFormatEtc) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI DataObject_DAdvise( | |
| IDataObject* iface, | |
| FORMATETC* pformatetc, | |
| DWORD advf, | |
| IAdviseSink* pAdvSink, | |
| DWORD* pdwConnection) | |
| { | |
| STGMEDIUM stgmedium; | |
| CHECK_EXPECTED_METHOD("DataObject_DAdvise"); | |
| *pdwConnection = 1; | |
| if(advf & ADVF_PRIMEFIRST) | |
| { | |
| ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat); | |
| stgmedium.tymed = TYMED_HGLOBAL; | |
| U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4); | |
| stgmedium.pUnkForRelease = NULL; | |
| IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium); | |
| } | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI DataObject_DUnadvise( | |
| IDataObject* iface, | |
| DWORD dwConnection) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_DUnadvise"); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI DataObject_EnumDAdvise( | |
| IDataObject* iface, | |
| IEnumSTATDATA** ppenumAdvise) | |
| { | |
| CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise"); | |
| return OLE_E_ADVISENOTSUPPORTED; | |
| } | |
| static IDataObjectVtbl DataObjectVtbl = | |
| { | |
| DataObject_QueryInterface, | |
| DataObject_AddRef, | |
| DataObject_Release, | |
| DataObject_GetData, | |
| DataObject_GetDataHere, | |
| DataObject_QueryGetData, | |
| DataObject_GetCanonicalFormatEtc, | |
| DataObject_SetData, | |
| DataObject_EnumFormatEtc, | |
| DataObject_DAdvise, | |
| DataObject_DUnadvise, | |
| DataObject_EnumDAdvise | |
| }; | |
| static IDataObject DataObject = { &DataObjectVtbl }; | |
| static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) | |
| { | |
| *ppv = NULL; | |
| if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface; | |
| if (*ppv) | |
| { | |
| IUnknown_AddRef((IUnknown *)*ppv); | |
| return S_OK; | |
| } | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI Unknown_AddRef(IUnknown *iface) | |
| { | |
| return 2; | |
| } | |
| static ULONG WINAPI Unknown_Release(IUnknown *iface) | |
| { | |
| return 1; | |
| } | |
| static const IUnknownVtbl UnknownVtbl = | |
| { | |
| Unknown_QueryInterface, | |
| Unknown_AddRef, | |
| Unknown_Release | |
| }; | |
| static IUnknown unknown = { &UnknownVtbl }; | |
| static void check_enum_cache(IOleCache2 *cache, const STATDATA *expect, int num) | |
| { | |
| IEnumSTATDATA *enum_stat; | |
| STATDATA stat; | |
| HRESULT hr; | |
| hr = IOleCache2_EnumCache( cache, &enum_stat ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| while (IEnumSTATDATA_Next(enum_stat, 1, &stat, NULL) == S_OK) | |
| { | |
| ok( stat.formatetc.cfFormat == expect->formatetc.cfFormat, "got %d expect %d\n", | |
| stat.formatetc.cfFormat, expect->formatetc.cfFormat ); | |
| ok( !stat.formatetc.ptd == !expect->formatetc.ptd, "got %p expect %p\n", | |
| stat.formatetc.ptd, expect->formatetc.ptd ); | |
| ok( stat.formatetc.dwAspect == expect->formatetc.dwAspect, "got %d expect %d\n", | |
| stat.formatetc.dwAspect, expect->formatetc.dwAspect ); | |
| ok( stat.formatetc.lindex == expect->formatetc.lindex, "got %d expect %d\n", | |
| stat.formatetc.lindex, expect->formatetc.lindex ); | |
| ok( stat.formatetc.tymed == expect->formatetc.tymed, "got %d expect %d\n", | |
| stat.formatetc.tymed, expect->formatetc.tymed ); | |
| ok( stat.advf == expect->advf, "got %d expect %d\n", stat.advf, expect->advf ); | |
| ok( stat.pAdvSink == 0, "got %p\n", stat.pAdvSink ); | |
| ok( stat.dwConnection == expect->dwConnection, "got %d expect %d\n", stat.dwConnection, expect->dwConnection ); | |
| num--; | |
| expect++; | |
| } | |
| ok( num == 0, "incorrect number. num %d\n", num ); | |
| IEnumSTATDATA_Release( enum_stat ); | |
| } | |
| static void test_data_cache(void) | |
| { | |
| HRESULT hr; | |
| IOleCache2 *pOleCache; | |
| IOleCache *olecache; | |
| IStorage *pStorage; | |
| IUnknown *unk, *unk2; | |
| IPersistStorage *pPS; | |
| IViewObject *pViewObject; | |
| IOleCacheControl *pOleCacheControl; | |
| IDataObject *pCacheDataObject; | |
| FORMATETC fmtetc; | |
| STGMEDIUM stgmedium; | |
| DWORD dwConnection; | |
| DWORD dwFreeze; | |
| RECTL rcBounds; | |
| HDC hdcMem; | |
| CLSID clsid; | |
| char szSystemDir[MAX_PATH]; | |
| WCHAR wszPath[MAX_PATH]; | |
| static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0}; | |
| static const struct expected_method methods_cacheinitnew[] = | |
| { | |
| { "AdviseSink_OnViewChange", 0 }, | |
| { "AdviseSink_OnViewChange", 0 }, | |
| { "draw_continue", 1 }, | |
| { "draw_continue_false", 1 }, | |
| { "DataObject_DAdvise", 0 }, | |
| { "DataObject_DAdvise", 0 }, | |
| { "DataObject_DUnadvise", 0 }, | |
| { "DataObject_DUnadvise", 0 }, | |
| { NULL, 0 } | |
| }; | |
| static const struct expected_method methods_cacheload[] = | |
| { | |
| { "AdviseSink_OnViewChange", 0 }, | |
| { "draw_continue", 1 }, | |
| { "draw_continue", 1 }, | |
| { "draw_continue", 1 }, | |
| { "DataObject_GetData", 0 }, | |
| { "DataObject_GetData", 0 }, | |
| { "DataObject_GetData", 0 }, | |
| { NULL, 0 } | |
| }; | |
| static const struct expected_method methods_cachethenrun[] = | |
| { | |
| { "DataObject_DAdvise", 0 }, | |
| { "DataObject_DAdvise", 0 }, | |
| { "DataObject_DAdvise", 0 }, | |
| { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */ | |
| { "DataObject_DAdvise", 0 }, | |
| { "DataObject_DUnadvise", 0 }, | |
| { "DataObject_DUnadvise", 0 }, | |
| { "DataObject_DUnadvise", 0 }, | |
| { "DataObject_DUnadvise", 0 }, | |
| { NULL, 0 } | |
| }; | |
| GetSystemDirectoryA(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0])); | |
| expected_method_list = methods_cacheinitnew; | |
| fmtetc.cfFormat = CF_METAFILEPICT; | |
| fmtetc.dwAspect = DVASPECT_ICON; | |
| fmtetc.lindex = -1; | |
| fmtetc.ptd = NULL; | |
| fmtetc.tymed = TYMED_MFPICT; | |
| hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage); | |
| ok_ole_success(hr, "StgCreateDocfile"); | |
| /* aggregation */ | |
| /* requested is not IUnknown */ | |
| hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IOleCache2, (void**)&pOleCache); | |
| ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); | |
| hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IUnknown, (void**)&unk); | |
| ok(hr == S_OK, "got 0x%08x\n", hr); | |
| hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache); | |
| ok(hr == S_OK, "got 0x%08x\n", hr); | |
| hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache); | |
| ok(hr == S_OK, "got 0x%08x\n", hr); | |
| ok(unk != (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk); | |
| ok(unk != (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk); | |
| IOleCache2_Release(pOleCache); | |
| IOleCache_Release(olecache); | |
| IUnknown_Release(unk); | |
| hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void**)&unk); | |
| ok(hr == S_OK, "got 0x%08x\n", hr); | |
| hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache); | |
| ok(hr == S_OK, "got 0x%08x\n", hr); | |
| hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache); | |
| ok(hr == S_OK, "got 0x%08x\n", hr); | |
| hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void**)&unk2); | |
| ok(hr == S_OK, "got 0x%08x\n", hr); | |
| ok(unk == (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk); | |
| ok(unk == (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk); | |
| ok(unk == unk2, "got %p, expected %p\n", unk2, unk); | |
| IUnknown_Release(unk2); | |
| IOleCache2_Release(pOleCache); | |
| IOleCache_Release(olecache); | |
| IUnknown_Release(unk); | |
| /* Test with new data */ | |
| hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); | |
| ok_ole_success(hr, "CreateDataCache"); | |
| hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS); | |
| ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)"); | |
| hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject); | |
| ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)"); | |
| hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl); | |
| ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)"); | |
| hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink); | |
| ok_ole_success(hr, "IViewObject_SetAdvise"); | |
| hr = IPersistStorage_InitNew(pPS, pStorage); | |
| ok_ole_success(hr, "IPersistStorage_InitNew"); | |
| hr = IPersistStorage_IsDirty(pPS); | |
| ok_ole_success(hr, "IPersistStorage_IsDirty"); | |
| hr = IPersistStorage_GetClassID(pPS, &clsid); | |
| ok_ole_success(hr, "IPersistStorage_GetClassID"); | |
| ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n"); | |
| hr = IOleCache2_Uncache(pOleCache, 0xdeadbeef); | |
| ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr); | |
| /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */ | |
| if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg")) | |
| { | |
| hr = IOleCache2_Cache(pOleCache, NULL, 0, &dwConnection); | |
| ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr); | |
| hr = IOleCache2_Cache(pOleCache, NULL, 0, NULL); | |
| ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr); | |
| } | |
| else | |
| { | |
| skip("tests with NULL parameters will crash on NT4 and below\n"); | |
| } | |
| for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++) | |
| { | |
| int i; | |
| fmtetc.dwAspect = DVASPECT_THUMBNAIL; | |
| for (i = 0; i < 7; i++) | |
| { | |
| fmtetc.tymed = 1 << i; | |
| hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); | |
| if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) || | |
| (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) || | |
| (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) || | |
| (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF)) | |
| ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n", | |
| fmtetc.cfFormat, fmtetc.tymed, hr); | |
| else if (fmtetc.tymed == TYMED_HGLOBAL) | |
| ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED || | |
| broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */, | |
| "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n", | |
| fmtetc.cfFormat, fmtetc.tymed, hr); | |
| else | |
| ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n", | |
| fmtetc.cfFormat, fmtetc.tymed, hr); | |
| if (SUCCEEDED(hr)) | |
| { | |
| hr = IOleCache2_Uncache(pOleCache, dwConnection); | |
| ok_ole_success(hr, "IOleCache_Uncache"); | |
| } | |
| } | |
| } | |
| fmtetc.cfFormat = CF_BITMAP; | |
| fmtetc.dwAspect = DVASPECT_THUMBNAIL; | |
| fmtetc.tymed = TYMED_GDI; | |
| hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); | |
| ok_ole_success(hr, "IOleCache_Cache"); | |
| fmtetc.cfFormat = 0; | |
| fmtetc.dwAspect = DVASPECT_ICON; | |
| fmtetc.tymed = TYMED_MFPICT; | |
| hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); | |
| ok_ole_success(hr, "IOleCache_Cache"); | |
| MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0])); | |
| memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32)); | |
| fmtetc.cfFormat = CF_METAFILEPICT; | |
| stgmedium.tymed = TYMED_MFPICT; | |
| U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel( | |
| LoadIconA(NULL, (LPSTR)IDI_APPLICATION), wszPath, wszPath, 0); | |
| stgmedium.pUnkForRelease = NULL; | |
| fmtetc.dwAspect = DVASPECT_CONTENT; | |
| hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE); | |
| ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr); | |
| fmtetc.dwAspect = DVASPECT_ICON; | |
| hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE); | |
| ok_ole_success(hr, "IOleCache_SetData"); | |
| ReleaseStgMedium(&stgmedium); | |
| hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze); | |
| todo_wine { | |
| ok_ole_success(hr, "IViewObject_Freeze"); | |
| hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze); | |
| ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); | |
| } | |
| rcBounds.left = 0; | |
| rcBounds.top = 0; | |
| rcBounds.right = 100; | |
| rcBounds.bottom = 100; | |
| hdcMem = CreateCompatibleDC(NULL); | |
| hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); | |
| ok_ole_success(hr, "IViewObject_Draw"); | |
| hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); | |
| ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); | |
| /* a NULL draw_continue fn ptr */ | |
| hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef); | |
| ok_ole_success(hr, "IViewObject_Draw"); | |
| /* draw_continue that returns FALSE to abort drawing */ | |
| hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef); | |
| ok(hr == E_ABORT || | |
| broken(hr == S_OK), /* win9x may skip the callbacks */ | |
| "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr); | |
| DeleteDC(hdcMem); | |
| hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject); | |
| ok_ole_success(hr, "IOleCacheControl_OnRun"); | |
| hr = IPersistStorage_Save(pPS, pStorage, TRUE); | |
| ok_ole_success(hr, "IPersistStorage_Save"); | |
| hr = IPersistStorage_SaveCompleted(pPS, NULL); | |
| ok_ole_success(hr, "IPersistStorage_SaveCompleted"); | |
| hr = IPersistStorage_IsDirty(pPS); | |
| ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr); | |
| IPersistStorage_Release(pPS); | |
| IViewObject_Release(pViewObject); | |
| IOleCache2_Release(pOleCache); | |
| IOleCacheControl_Release(pOleCacheControl); | |
| CHECK_NO_EXTRA_METHODS(); | |
| /* Test with loaded data */ | |
| trace("Testing loaded data with CreateDataCache:\n"); | |
| expected_method_list = methods_cacheload; | |
| hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); | |
| ok_ole_success(hr, "CreateDataCache"); | |
| hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS); | |
| ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)"); | |
| hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject); | |
| ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)"); | |
| hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink); | |
| ok_ole_success(hr, "IViewObject_SetAdvise"); | |
| hr = IPersistStorage_Load(pPS, pStorage); | |
| ok_ole_success(hr, "IPersistStorage_Load"); | |
| hr = IPersistStorage_IsDirty(pPS); | |
| ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr); | |
| fmtetc.cfFormat = 0; | |
| fmtetc.dwAspect = DVASPECT_ICON; | |
| fmtetc.lindex = -1; | |
| fmtetc.ptd = NULL; | |
| fmtetc.tymed = TYMED_MFPICT; | |
| hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); | |
| ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr); | |
| rcBounds.left = 0; | |
| rcBounds.top = 0; | |
| rcBounds.right = 100; | |
| rcBounds.bottom = 100; | |
| hdcMem = CreateCompatibleDC(NULL); | |
| hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); | |
| ok_ole_success(hr, "IViewObject_Draw"); | |
| hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); | |
| ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); | |
| /* unload the cached storage object, causing it to be reloaded */ | |
| hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE); | |
| ok_ole_success(hr, "IOleCache2_DiscardCache"); | |
| hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); | |
| ok_ole_success(hr, "IViewObject_Draw"); | |
| /* unload the cached storage object, but don't allow it to be reloaded */ | |
| hr = IPersistStorage_HandsOffStorage(pPS); | |
| ok_ole_success(hr, "IPersistStorage_HandsOffStorage"); | |
| hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); | |
| ok_ole_success(hr, "IViewObject_Draw"); | |
| hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE); | |
| ok_ole_success(hr, "IOleCache2_DiscardCache"); | |
| hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); | |
| ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); | |
| DeleteDC(hdcMem); | |
| todo_wine { | |
| hr = IOleCache2_InitCache(pOleCache, &DataObject); | |
| ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr); | |
| } | |
| IPersistStorage_Release(pPS); | |
| IViewObject_Release(pViewObject); | |
| IOleCache2_Release(pOleCache); | |
| todo_wine { | |
| CHECK_NO_EXTRA_METHODS(); | |
| } | |
| hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); | |
| ok_ole_success(hr, "CreateDataCache"); | |
| expected_method_list = methods_cachethenrun; | |
| hr = IOleCache2_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject); | |
| ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)"); | |
| hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl); | |
| ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)"); | |
| fmtetc.cfFormat = CF_METAFILEPICT; | |
| fmtetc.dwAspect = DVASPECT_CONTENT; | |
| fmtetc.tymed = TYMED_MFPICT; | |
| hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); | |
| ok_ole_success(hr, "IOleCache_Cache"); | |
| hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); | |
| ok(hr == OLE_E_BLANK, "got %08x\n", hr); | |
| fmtetc.cfFormat = cf_test_1; | |
| fmtetc.dwAspect = DVASPECT_CONTENT; | |
| fmtetc.tymed = TYMED_HGLOBAL; | |
| hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); | |
| ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr); | |
| hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); | |
| ok(hr == OLE_E_BLANK, "got %08x\n", hr); | |
| fmtetc.cfFormat = cf_test_2; | |
| hr = IOleCache2_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection); | |
| ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr); | |
| hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); | |
| ok(hr == OLE_E_BLANK, "got %08x\n", hr); | |
| hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject); | |
| ok_ole_success(hr, "IOleCacheControl_OnRun"); | |
| fmtetc.cfFormat = cf_test_3; | |
| hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); | |
| ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr); | |
| fmtetc.cfFormat = cf_test_1; | |
| hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); | |
| ok(hr == OLE_E_BLANK, "got %08x\n", hr); | |
| fmtetc.cfFormat = cf_test_2; | |
| hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); | |
| ok(hr == S_OK, "got %08x\n", hr); | |
| ReleaseStgMedium(&stgmedium); | |
| fmtetc.cfFormat = cf_test_3; | |
| hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); | |
| ok(hr == OLE_E_BLANK, "got %08x\n", hr); | |
| IOleCacheControl_Release(pOleCacheControl); | |
| IDataObject_Release(pCacheDataObject); | |
| IOleCache2_Release(pOleCache); | |
| CHECK_NO_EXTRA_METHODS(); | |
| IStorage_Release(pStorage); | |
| } | |
| static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0}; | |
| /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */ | |
| static BYTE dib[] = | |
| { | |
| 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, | |
| 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, | |
| 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, | |
| 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, | |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, | |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | |
| }; | |
| static IStorage *create_storage( int num ) | |
| { | |
| IStorage *stg; | |
| IStream *stm; | |
| HRESULT hr; | |
| ULONG written; | |
| hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IStorage_SetClass( stg, &CLSID_Picture_Dib ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IStorage_CreateStream( stg, CONTENTS, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stm ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| if (num == 1) /* Set biXPelsPerMeter = 0 */ | |
| { | |
| dib[0x26] = 0; | |
| dib[0x27] = 0; | |
| } | |
| hr = IStream_Write( stm, dib, sizeof(dib), &written ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| IStream_Release( stm ); | |
| return stg; | |
| } | |
| static HGLOBAL create_dib( void ) | |
| { | |
| HGLOBAL h; | |
| void *ptr; | |
| h = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) - sizeof(BITMAPFILEHEADER) ); | |
| ptr = GlobalLock( h ); | |
| memcpy( ptr, dib + sizeof(BITMAPFILEHEADER), sizeof(dib) - sizeof(BITMAPFILEHEADER) ); | |
| GlobalUnlock( h ); | |
| return h; | |
| } | |
| static void test_data_cache_dib_contents_stream(int num) | |
| { | |
| HRESULT hr; | |
| IUnknown *unk; | |
| IPersistStorage *persist; | |
| IDataObject *data; | |
| IViewObject2 *view; | |
| IStorage *stg; | |
| IOleCache2 *cache; | |
| FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; | |
| STGMEDIUM med; | |
| CLSID cls; | |
| SIZEL sz; | |
| BYTE *ptr; | |
| BITMAPINFOHEADER expect_info; | |
| STATDATA enum_expect[] = | |
| { | |
| {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, | |
| {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, | |
| }; | |
| hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk ); | |
| ok( SUCCEEDED(hr), "got %08x\n", hr ); | |
| hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void **)&persist ); | |
| ok( SUCCEEDED(hr), "got %08x\n", hr ); | |
| hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void **)&data ); | |
| ok( SUCCEEDED(hr), "got %08x\n", hr ); | |
| hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view ); | |
| ok( SUCCEEDED(hr), "got %08x\n", hr ); | |
| hr = IUnknown_QueryInterface( unk, &IID_IOleCache2, (void **)&cache ); | |
| ok( SUCCEEDED(hr), "got %08x\n", hr ); | |
| stg = create_storage( num ); | |
| hr = IPersistStorage_Load( persist, stg ); | |
| ok( SUCCEEDED(hr), "got %08x\n", hr ); | |
| IStorage_Release( stg ); | |
| hr = IPersistStorage_GetClassID( persist, &cls ); | |
| ok( SUCCEEDED(hr), "got %08x\n", hr ); | |
| ok( IsEqualCLSID( &cls, &CLSID_Picture_Dib ), "class id mismatch\n" ); | |
| hr = IDataObject_GetData( data, &fmt, &med ); | |
| ok( SUCCEEDED(hr), "got %08x\n", hr ); | |
| ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed ); | |
| ok( GlobalSize( U(med).hGlobal ) >= sizeof(dib) - sizeof(BITMAPFILEHEADER), | |
| "got %lu\n", GlobalSize( U(med).hGlobal ) ); | |
| ptr = GlobalLock( U(med).hGlobal ); | |
| expect_info = *(BITMAPINFOHEADER *)(dib + sizeof(BITMAPFILEHEADER)); | |
| if (expect_info.biXPelsPerMeter == 0 || expect_info.biYPelsPerMeter == 0) | |
| { | |
| HDC hdc = GetDC( 0 ); | |
| expect_info.biXPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSX ), 10000, 254 ); | |
| expect_info.biYPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSY ), 10000, 254 ); | |
| ReleaseDC( 0, hdc ); | |
| } | |
| ok( !memcmp( ptr, &expect_info, sizeof(expect_info) ), "mismatch\n" ); | |
| ok( !memcmp( ptr + sizeof(expect_info), dib + sizeof(BITMAPFILEHEADER) + sizeof(expect_info), | |
| sizeof(dib) - sizeof(BITMAPFILEHEADER) - sizeof(expect_info) ), "mismatch\n" ); | |
| GlobalUnlock( U(med).hGlobal ); | |
| ReleaseStgMedium( &med ); | |
| check_enum_cache( cache, enum_expect, 2 ); | |
| hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz ); | |
| ok( SUCCEEDED(hr), "got %08x\n", hr ); | |
| if (num == 0) | |
| { | |
| ok( sz.cx == 1000, "got %d\n", sz.cx ); | |
| ok( sz.cy == 250, "got %d\n", sz.cy ); | |
| } | |
| else | |
| { | |
| HDC hdc = GetDC( 0 ); | |
| LONG x = 2 * 2540 / GetDeviceCaps( hdc, LOGPIXELSX ); | |
| LONG y = 1 * 2540 / GetDeviceCaps( hdc, LOGPIXELSY ); | |
| ok( sz.cx == x, "got %d %d\n", sz.cx, x ); | |
| ok( sz.cy == y, "got %d %d\n", sz.cy, y ); | |
| ReleaseDC( 0, hdc ); | |
| } | |
| IOleCache2_Release( cache ); | |
| IViewObject2_Release( view ); | |
| IDataObject_Release( data ); | |
| IPersistStorage_Release( persist ); | |
| IUnknown_Release( unk ); | |
| } | |
| static void check_bitmap_size( HBITMAP h, int cx, int cy ) | |
| { | |
| BITMAP bm; | |
| GetObjectW( h, sizeof(bm), &bm ); | |
| ok( bm.bmWidth == cx, "got %d expect %d\n", bm.bmWidth, cx ); | |
| ok( bm.bmHeight == cy, "got %d expect %d\n", bm.bmHeight, cy ); | |
| } | |
| static void check_dib_size( HGLOBAL h, int cx, int cy ) | |
| { | |
| BITMAPINFO *info; | |
| info = GlobalLock( h ); | |
| ok( info->bmiHeader.biWidth == cx, "got %d expect %d\n", info->bmiHeader.biWidth, cx ); | |
| ok( info->bmiHeader.biHeight == cy, "got %d expect %d\n", info->bmiHeader.biHeight, cy ); | |
| GlobalUnlock( h ); | |
| } | |
| static void test_data_cache_bitmap(void) | |
| { | |
| HRESULT hr; | |
| IOleCache2 *cache; | |
| IDataObject *data; | |
| FORMATETC fmt; | |
| DWORD conn; | |
| STGMEDIUM med; | |
| STATDATA expect[] = | |
| { | |
| {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 }, | |
| {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 }, | |
| {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 0 }, | |
| {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 } | |
| }; | |
| hr = CreateDataCache( NULL, &CLSID_NULL, &IID_IOleCache2, (void **)&cache ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| /* create a dib entry which will also create a bitmap entry too */ | |
| fmt.cfFormat = CF_DIB; | |
| fmt.ptd = NULL; | |
| fmt.dwAspect = DVASPECT_CONTENT; | |
| fmt.lindex = -1; | |
| fmt.tymed = TYMED_HGLOBAL; | |
| hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( conn == 2, "got %d\n", conn ); | |
| expect[0].dwConnection = conn; | |
| expect[1].dwConnection = conn; | |
| check_enum_cache( cache, expect, 2 ); | |
| /* now try to add a bitmap */ | |
| fmt.cfFormat = CF_BITMAP; | |
| fmt.tymed = TYMED_GDI; | |
| hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); | |
| ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr ); | |
| /* metafile */ | |
| fmt.cfFormat = CF_METAFILEPICT; | |
| fmt.tymed = TYMED_MFPICT; | |
| hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( conn == 3, "got %d\n", conn ); | |
| expect[2].dwConnection = conn; | |
| check_enum_cache( cache, expect, 3); | |
| /* enhmetafile */ | |
| fmt.cfFormat = CF_ENHMETAFILE; | |
| fmt.tymed = TYMED_ENHMF; | |
| hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( conn == 4, "got %d\n", conn ); | |
| expect[3].dwConnection = conn; | |
| check_enum_cache( cache, expect, 4 ); | |
| /* uncache everything */ | |
| hr = IOleCache2_Uncache( cache, expect[3].dwConnection ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| hr = IOleCache2_Uncache( cache, expect[2].dwConnection ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| hr = IOleCache2_Uncache( cache, expect[0].dwConnection ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| hr = IOleCache2_Uncache( cache, expect[0].dwConnection ); | |
| ok( hr == OLE_E_NOCONNECTION, "got %08x\n", hr ); | |
| check_enum_cache( cache, expect, 0 ); | |
| /* just create a bitmap entry which again adds both dib and bitmap */ | |
| fmt.cfFormat = CF_BITMAP; | |
| fmt.tymed = TYMED_GDI; | |
| hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| expect[0].dwConnection = conn; | |
| expect[1].dwConnection = conn; | |
| check_enum_cache( cache, expect, 2 ); | |
| /* Try setting a 1x1 bitmap */ | |
| hr = IOleCache2_QueryInterface( cache, &IID_IDataObject, (void **) &data ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| med.tymed = TYMED_GDI; | |
| U(med).hBitmap = CreateBitmap( 1, 1, 1, 1, NULL ); | |
| med.pUnkForRelease = NULL; | |
| hr = IOleCache2_SetData( cache, &fmt, &med, TRUE ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| hr = IDataObject_GetData( data, &fmt, &med ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed ); | |
| check_bitmap_size( U(med).hBitmap, 1, 1 ); | |
| ReleaseStgMedium( &med ); | |
| fmt.cfFormat = CF_DIB; | |
| fmt.tymed = TYMED_HGLOBAL; | |
| hr = IDataObject_GetData( data, &fmt, &med ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed ); | |
| check_dib_size( U(med).hGlobal, 1, 1 ); | |
| ReleaseStgMedium( &med ); | |
| /* Now set a 2x1 dib */ | |
| fmt.cfFormat = CF_DIB; | |
| fmt.tymed = TYMED_HGLOBAL; | |
| med.tymed = TYMED_HGLOBAL; | |
| U(med).hGlobal = create_dib(); | |
| hr = IOleCache2_SetData( cache, &fmt, &med, TRUE ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| fmt.cfFormat = CF_BITMAP; | |
| fmt.tymed = TYMED_GDI; | |
| hr = IDataObject_GetData( data, &fmt, &med ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed ); | |
| check_bitmap_size( U(med).hBitmap, 2, 1 ); | |
| ReleaseStgMedium( &med ); | |
| fmt.cfFormat = CF_DIB; | |
| fmt.tymed = TYMED_HGLOBAL; | |
| hr = IDataObject_GetData( data, &fmt, &med ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed ); | |
| check_dib_size( U(med).hGlobal, 2, 1 ); | |
| ReleaseStgMedium( &med ); | |
| IDataObject_Release( data ); | |
| IOleCache2_Release( cache ); | |
| } | |
| /* The CLSID_Picture_ classes automatically create appropriate cache entries */ | |
| static void test_data_cache_init(void) | |
| { | |
| HRESULT hr; | |
| IOleCache2 *cache; | |
| IPersistStorage *persist; | |
| int i; | |
| CLSID clsid; | |
| static const STATDATA enum_expect[] = | |
| { | |
| {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, | |
| {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, | |
| {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 }, | |
| {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 1 } | |
| }; | |
| static const struct | |
| { | |
| const CLSID *clsid; | |
| int enum_start, enum_num; | |
| } data[] = | |
| { | |
| { &CLSID_NULL, 0, 0 }, | |
| { &CLSID_WineTestOld, 0, 0 }, | |
| { &CLSID_Picture_Dib, 0, 2 }, | |
| { &CLSID_Picture_Metafile, 2, 1 }, | |
| { &CLSID_Picture_EnhMetafile, 3, 1 } | |
| }; | |
| for (i = 0; i < sizeof(data) / sizeof(data[0]); i++) | |
| { | |
| hr = CreateDataCache( NULL, data[i].clsid, &IID_IOleCache2, (void **)&cache ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| check_enum_cache( cache, enum_expect + data[i].enum_start , data[i].enum_num ); | |
| IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist ); | |
| hr = IPersistStorage_GetClassID( persist, &clsid ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( IsEqualCLSID( &clsid, data[i].clsid ), "class id mismatch %s %s\n", wine_dbgstr_guid( &clsid ), | |
| wine_dbgstr_guid( data[i].clsid ) ); | |
| IPersistStorage_Release( persist ); | |
| IOleCache2_Release( cache ); | |
| } | |
| } | |
| static void test_data_cache_initnew(void) | |
| { | |
| HRESULT hr; | |
| IOleCache2 *cache; | |
| IPersistStorage *persist; | |
| IStorage *stg_dib, *stg_mf, *stg_wine; | |
| CLSID clsid; | |
| static const STATDATA initnew_expect[] = | |
| { | |
| {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, | |
| {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, | |
| }; | |
| static const STATDATA initnew2_expect[] = | |
| { | |
| {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 }, | |
| {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 }, | |
| {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 }, | |
| }; | |
| static const STATDATA initnew3_expect[] = | |
| { | |
| {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, | |
| {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, | |
| {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 }, | |
| {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 }, | |
| {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 }, | |
| }; | |
| static const STATDATA initnew4_expect[] = | |
| { | |
| {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 }, | |
| {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 }, | |
| {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 }, | |
| {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 4 }, | |
| {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 4 }, | |
| }; | |
| hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_dib ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IStorage_SetClass( stg_dib, &CLSID_Picture_Dib ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_mf ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IStorage_SetClass( stg_mf, &CLSID_Picture_Metafile ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_wine ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IStorage_SetClass( stg_wine, &CLSID_WineTestOld ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = CreateDataCache( NULL, &CLSID_WineTestOld, &IID_IOleCache2, (void **)&cache ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist ); | |
| hr = IPersistStorage_InitNew( persist, stg_dib ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IPersistStorage_GetClassID( persist, &clsid ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) ); | |
| check_enum_cache( cache, initnew_expect, 2 ); | |
| hr = IPersistStorage_InitNew( persist, stg_mf ); | |
| ok( hr == CO_E_ALREADYINITIALIZED, "got %08x\n", hr); | |
| hr = IPersistStorage_HandsOffStorage( persist ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IPersistStorage_GetClassID( persist, &clsid ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) ); | |
| hr = IPersistStorage_InitNew( persist, stg_mf ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IPersistStorage_GetClassID( persist, &clsid ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( IsEqualCLSID( &clsid, &CLSID_Picture_Metafile ), "got %s\n", wine_dbgstr_guid( &clsid ) ); | |
| check_enum_cache( cache, initnew2_expect, 3 ); | |
| hr = IPersistStorage_HandsOffStorage( persist ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IPersistStorage_InitNew( persist, stg_dib ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IPersistStorage_GetClassID( persist, &clsid ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) ); | |
| check_enum_cache( cache, initnew3_expect, 5 ); | |
| hr = IPersistStorage_HandsOffStorage( persist ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IPersistStorage_InitNew( persist, stg_wine ); | |
| ok( hr == S_OK, "got %08x\n", hr); | |
| hr = IPersistStorage_GetClassID( persist, &clsid ); | |
| ok( hr == S_OK, "got %08x\n", hr ); | |
| ok( IsEqualCLSID( &clsid, &CLSID_WineTestOld ), "got %s\n", wine_dbgstr_guid( &clsid ) ); | |
| check_enum_cache( cache, initnew4_expect, 5 ); | |
| IStorage_Release( stg_wine ); | |
| IStorage_Release( stg_mf ); | |
| IStorage_Release( stg_dib ); | |
| IPersistStorage_Release( persist ); | |
| IOleCache2_Release( cache ); | |
| } | |
| static void test_default_handler(void) | |
| { | |
| HRESULT hr; | |
| IOleObject *pObject; | |
| IRunnableObject *pRunnableObject; | |
| IOleClientSite *pClientSite; | |
| IDataObject *pDataObject; | |
| SIZEL sizel; | |
| DWORD dwStatus; | |
| CLSID clsid; | |
| LPOLESTR pszUserType; | |
| LOGPALETTE palette; | |
| DWORD dwAdvConn; | |
| IMoniker *pMoniker; | |
| FORMATETC fmtetc; | |
| IOleInPlaceObject *pInPlaceObj; | |
| IEnumOLEVERB *pEnumVerbs; | |
| DWORD dwRegister; | |
| static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0}; | |
| static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0}; | |
| static const WCHAR wszDelim[] = {'!',0}; | |
| static const struct expected_method methods_embeddinghelper[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_AddRef", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_QueryInterface", TEST_TODO }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */ | |
| { "OleObject_Release", TEST_TODO }, | |
| { "WINE_EXTRA", TEST_OPTIONAL }, | |
| { NULL, 0 } | |
| }; | |
| hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject); | |
| ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); | |
| hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject); | |
| ok_ole_success(hr, "OleCreateDefaultHandler"); | |
| hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj); | |
| ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr); | |
| hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn); | |
| ok_ole_success(hr, "IOleObject_Advise"); | |
| hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE); | |
| ok_ole_success(hr, "IOleObject_Close"); | |
| /* FIXME: test IOleObject_EnumAdvise */ | |
| hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs); | |
| ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); | |
| hr = IOleObject_GetClientSite(pObject, &pClientSite); | |
| ok_ole_success(hr, "IOleObject_GetClientSite"); | |
| hr = IOleObject_SetClientSite(pObject, pClientSite); | |
| ok_ole_success(hr, "IOleObject_SetClientSite"); | |
| hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject); | |
| ok(hr == OLE_E_NOTRUNNING, | |
| "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", | |
| hr); | |
| hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel); | |
| ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n", | |
| hr); | |
| hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); | |
| ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); | |
| hr = IOleObject_GetUserClassID(pObject, &clsid); | |
| ok_ole_success(hr, "IOleObject_GetUserClassID"); | |
| ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n"); | |
| hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType); | |
| todo_wine { | |
| ok_ole_success(hr, "IOleObject_GetUserType"); | |
| ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n"); | |
| } | |
| hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0); | |
| ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); | |
| hr = IOleObject_IsUpToDate(pObject); | |
| ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); | |
| palette.palNumEntries = 1; | |
| palette.palVersion = 2; | |
| memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0])); | |
| hr = IOleObject_SetColorScheme(pObject, &palette); | |
| ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); | |
| sizel.cx = sizel.cy = 0; | |
| hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel); | |
| ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); | |
| hr = IOleObject_SetHostNames(pObject, wszHostName, NULL); | |
| ok_ole_success(hr, "IOleObject_SetHostNames"); | |
| hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker); | |
| ok_ole_success(hr, "CreateItemMoniker"); | |
| hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker); | |
| ok_ole_success(hr, "IOleObject_SetMoniker"); | |
| IMoniker_Release(pMoniker); | |
| hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker); | |
| ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr); | |
| hr = IOleObject_Update(pObject); | |
| todo_wine | |
| ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); | |
| hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject); | |
| ok_ole_success(hr, "IOleObject_QueryInterface"); | |
| fmtetc.cfFormat = CF_TEXT; | |
| fmtetc.ptd = NULL; | |
| fmtetc.dwAspect = DVASPECT_CONTENT; | |
| fmtetc.lindex = -1; | |
| fmtetc.tymed = TYMED_NULL; | |
| hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn); | |
| ok_ole_success(hr, "IDataObject_DAdvise"); | |
| fmtetc.cfFormat = CF_ENHMETAFILE; | |
| fmtetc.ptd = NULL; | |
| fmtetc.dwAspect = DVASPECT_CONTENT; | |
| fmtetc.lindex = -1; | |
| fmtetc.tymed = TYMED_ENHMF; | |
| hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn); | |
| ok_ole_success(hr, "IDataObject_DAdvise"); | |
| fmtetc.cfFormat = CF_ENHMETAFILE; | |
| fmtetc.ptd = NULL; | |
| fmtetc.dwAspect = DVASPECT_CONTENT; | |
| fmtetc.lindex = -1; | |
| fmtetc.tymed = TYMED_ENHMF; | |
| hr = IDataObject_QueryGetData(pDataObject, &fmtetc); | |
| ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); | |
| fmtetc.cfFormat = CF_TEXT; | |
| fmtetc.ptd = NULL; | |
| fmtetc.dwAspect = DVASPECT_CONTENT; | |
| fmtetc.lindex = -1; | |
| fmtetc.tymed = TYMED_NULL; | |
| hr = IDataObject_QueryGetData(pDataObject, &fmtetc); | |
| ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); | |
| hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject); | |
| ok_ole_success(hr, "IOleObject_QueryInterface"); | |
| hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE); | |
| ok_ole_success(hr, "IRunnableObject_SetContainedObject"); | |
| hr = IRunnableObject_Run(pRunnableObject, NULL); | |
| ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); | |
| hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE); | |
| ok_ole_success(hr, "IOleObject_Close"); | |
| IRunnableObject_Release(pRunnableObject); | |
| IOleObject_Release(pObject); | |
| /* Test failure propagation from delegate ::QueryInterface */ | |
| hr = CoRegisterClassObject(&CLSID_WineTest, (IUnknown*)&OleObjectCF, | |
| CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister); | |
| ok_ole_success(hr, "CoRegisterClassObject"); | |
| if(SUCCEEDED(hr)) | |
| { | |
| expected_method_list = methods_embeddinghelper; | |
| hr = OleCreateEmbeddingHelper(&CLSID_WineTest, NULL, EMBDHLP_INPROC_SERVER, | |
| &OleObjectCF, &IID_IOleObject, (void**)&pObject); | |
| ok_ole_success(hr, "OleCreateEmbeddingHelper"); | |
| if(SUCCEEDED(hr)) | |
| { | |
| IUnknown *punk; | |
| g_QIFailsWith = E_FAIL; | |
| hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); | |
| ok(hr == E_FAIL, "Got 0x%08x\n", hr); | |
| g_QIFailsWith = E_NOINTERFACE; | |
| hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); | |
| ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr); | |
| g_QIFailsWith = CO_E_OBJNOTCONNECTED; | |
| hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); | |
| ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr); | |
| g_QIFailsWith = 0x87654321; | |
| hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); | |
| ok(hr == 0x87654321, "Got 0x%08x\n", hr); | |
| IOleObject_Release(pObject); | |
| } | |
| CHECK_NO_EXTRA_METHODS(); | |
| hr = CoRevokeClassObject(dwRegister); | |
| ok_ole_success(hr, "CoRevokeClassObject"); | |
| } | |
| } | |
| static void test_runnable(void) | |
| { | |
| static const struct expected_method methods_query_runnable[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { "OleObjectRunnable_AddRef", 0 }, | |
| { "OleObjectRunnable_IsRunning", 0 }, | |
| { "OleObjectRunnable_Release", 0 }, | |
| { NULL, 0 } | |
| }; | |
| static const struct expected_method methods_no_runnable[] = | |
| { | |
| { "OleObject_QueryInterface", 0 }, | |
| { NULL, 0 } | |
| }; | |
| BOOL ret; | |
| IOleObject *object = &OleObject; | |
| /* null argument */ | |
| ret = OleIsRunning(NULL); | |
| ok(ret == FALSE, "got %d\n", ret); | |
| expected_method_list = methods_query_runnable; | |
| ret = OleIsRunning(object); | |
| ok(ret == TRUE, "Object should be running\n"); | |
| CHECK_NO_EXTRA_METHODS(); | |
| g_isRunning = FALSE; | |
| expected_method_list = methods_query_runnable; | |
| ret = OleIsRunning(object); | |
| ok(ret == FALSE, "Object should not be running\n"); | |
| CHECK_NO_EXTRA_METHODS(); | |
| g_showRunnable = FALSE; /* QueryInterface(IID_IRunnableObject, ...) will fail */ | |
| expected_method_list = methods_no_runnable; | |
| ret = OleIsRunning(object); | |
| ok(ret == TRUE, "Object without IRunnableObject should be running\n"); | |
| CHECK_NO_EXTRA_METHODS(); | |
| g_isRunning = TRUE; | |
| g_showRunnable = TRUE; | |
| } | |
| static HRESULT WINAPI OleRun_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv) | |
| { | |
| *ppv = NULL; | |
| if (IsEqualIID(riid, &IID_IUnknown) || | |
| IsEqualIID(riid, &IID_IRunnableObject)) { | |
| *ppv = iface; | |
| } | |
| if (*ppv) | |
| { | |
| IUnknown_AddRef((IUnknown *)*ppv); | |
| return S_OK; | |
| } | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI OleRun_AddRef(IRunnableObject *iface) | |
| { | |
| return 2; | |
| } | |
| static ULONG WINAPI OleRun_Release(IRunnableObject *iface) | |
| { | |
| return 1; | |
| } | |
| static HRESULT WINAPI OleRun_GetRunningClass(IRunnableObject *iface, CLSID *clsid) | |
| { | |
| ok(0, "unexpected\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleRun_Run(IRunnableObject *iface, LPBINDCTX ctx) | |
| { | |
| ok(ctx == NULL, "got %p\n", ctx); | |
| return 0xdeadc0de; | |
| } | |
| static BOOL WINAPI OleRun_IsRunning(IRunnableObject *iface) | |
| { | |
| ok(0, "unexpected\n"); | |
| return FALSE; | |
| } | |
| static HRESULT WINAPI OleRun_LockRunning(IRunnableObject *iface, BOOL lock, | |
| BOOL last_unlock_closes) | |
| { | |
| ok(0, "unexpected\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI OleRun_SetContainedObject(IRunnableObject *iface, BOOL contained) | |
| { | |
| ok(0, "unexpected\n"); | |
| return E_NOTIMPL; | |
| } | |
| static const IRunnableObjectVtbl oleruntestvtbl = | |
| { | |
| OleRun_QueryInterface, | |
| OleRun_AddRef, | |
| OleRun_Release, | |
| OleRun_GetRunningClass, | |
| OleRun_Run, | |
| OleRun_IsRunning, | |
| OleRun_LockRunning, | |
| OleRun_SetContainedObject | |
| }; | |
| static IRunnableObject testrunnable = { &oleruntestvtbl }; | |
| static void test_OleRun(void) | |
| { | |
| HRESULT hr; | |
| /* doesn't support IRunnableObject */ | |
| hr = OleRun(&unknown); | |
| ok(hr == S_OK, "OleRun failed 0x%08x\n", hr); | |
| hr = OleRun((IUnknown*)&testrunnable); | |
| ok(hr == 0xdeadc0de, "got 0x%08x\n", hr); | |
| } | |
| static void test_OleLockRunning(void) | |
| { | |
| HRESULT hr; | |
| hr = OleLockRunning(&unknown, TRUE, FALSE); | |
| ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr); | |
| } | |
| static void test_OleDraw(void) | |
| { | |
| HRESULT hr; | |
| RECT rect; | |
| hr = OleDraw((IUnknown*)&viewobject, 0, (HDC)0x1, NULL); | |
| ok(hr == S_OK, "got 0x%08x\n", hr); | |
| hr = OleDraw(NULL, 0, (HDC)0x1, NULL); | |
| ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); | |
| hr = OleDraw(NULL, 0, (HDC)0x1, &rect); | |
| ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); | |
| } | |
| static const WCHAR comp_objW[] = {1,'C','o','m','p','O','b','j',0}; | |
| static IStream *comp_obj_stream; | |
| static IStream *ole_stream; | |
| static HRESULT WINAPI Storage_QueryInterface(IStorage *iface, REFIID riid, void **ppvObject) | |
| { | |
| ok(0, "unexpected call to QueryInterface\n"); | |
| return E_NOTIMPL; | |
| } | |
| static ULONG WINAPI Storage_AddRef(IStorage *iface) | |
| { | |
| ok(0, "unexpected call to AddRef\n"); | |
| return 2; | |
| } | |
| static ULONG WINAPI Storage_Release(IStorage *iface) | |
| { | |
| ok(0, "unexpected call to Release\n"); | |
| return 1; | |
| } | |
| static HRESULT WINAPI Storage_CreateStream(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm) | |
| { | |
| ULARGE_INTEGER size = {{0}}; | |
| LARGE_INTEGER pos = {{0}}; | |
| HRESULT hr; | |
| CHECK_EXPECT(Storage_CreateStream_CompObj); | |
| ok(!lstrcmpW(pwcsName, comp_objW), "pwcsName = %s\n", wine_dbgstr_w(pwcsName)); | |
| todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); | |
| ok(!reserved1, "reserved1 = %x\n", reserved1); | |
| ok(!reserved2, "reserved2 = %x\n", reserved2); | |
| ok(!!ppstm, "ppstm = NULL\n"); | |
| *ppstm = comp_obj_stream; | |
| IStream_AddRef(comp_obj_stream); | |
| hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); | |
| ok(hr == S_OK, "IStream_Seek returned %x\n", hr); | |
| hr = IStream_SetSize(comp_obj_stream, size); | |
| ok(hr == S_OK, "IStream_SetSize returned %x\n", hr); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm) | |
| { | |
| static const WCHAR ole1W[] = {1,'O','l','e',0}; | |
| LARGE_INTEGER pos = {{0}}; | |
| HRESULT hr; | |
| ok(!reserved1, "reserved1 = %p\n", reserved1); | |
| ok(!reserved2, "reserved2 = %x\n", reserved2); | |
| ok(!!ppstm, "ppstm = NULL\n"); | |
| if(!lstrcmpW(pwcsName, comp_objW)) { | |
| CHECK_EXPECT2(Storage_OpenStream_CompObj); | |
| ok(grfMode == STGM_SHARE_EXCLUSIVE, "grfMode = %x\n", grfMode); | |
| *ppstm = comp_obj_stream; | |
| IStream_AddRef(comp_obj_stream); | |
| hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); | |
| ok(hr == S_OK, "IStream_Seek returned %x\n", hr); | |
| return S_OK; | |
| }else if(!lstrcmpW(pwcsName, ole1W)) { | |
| CHECK_EXPECT(Storage_OpenStream_Ole); | |
| ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); | |
| *ppstm = ole_stream; | |
| IStream_AddRef(ole_stream); | |
| hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL); | |
| ok(hr == S_OK, "IStream_Seek returned %x\n", hr); | |
| return S_OK; | |
| } | |
| ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName)); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_CreateStorage(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD dwStgFmt, DWORD reserved2, IStorage **ppstg) | |
| { | |
| ok(0, "unexpected call to CreateStorage\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_OpenStorage(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg) | |
| { | |
| ok(0, "unexpected call to OpenStorage\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_CopyTo(IStorage *iface, DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest) | |
| { | |
| ok(0, "unexpected call to CopyTo\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_MoveElementTo(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgDest, LPCOLESTR pwcsNewName, DWORD grfFlags) | |
| { | |
| ok(0, "unexpected call to MoveElementTo\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_Commit(IStorage *iface, DWORD grfCommitFlags) | |
| { | |
| ok(0, "unexpected call to Commit\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_Revert(IStorage *iface) | |
| { | |
| ok(0, "unexpected call to Revert\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_EnumElements(IStorage *iface, DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum) | |
| { | |
| ok(0, "unexpected call to EnumElements\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_DestroyElement(IStorage *iface, LPCOLESTR pwcsName) | |
| { | |
| ok(0, "unexpected call to DestroyElement\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_RenameElement(IStorage *iface, LPCOLESTR pwcsOldName, LPCOLESTR pwcsNewName) | |
| { | |
| ok(0, "unexpected call to RenameElement\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_SetElementTimes(IStorage *iface, LPCOLESTR pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime) | |
| { | |
| ok(0, "unexpected call to SetElementTimes\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_SetClass(IStorage *iface, REFCLSID clsid) | |
| { | |
| CHECK_EXPECT(Storage_SetClass); | |
| ok(IsEqualIID(clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(clsid)); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI Storage_SetStateBits(IStorage *iface, DWORD grfStateBits, DWORD grfMask) | |
| { | |
| ok(0, "unexpected call to SetStateBits\n"); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI Storage_Stat(IStorage *iface, STATSTG *pstatstg, DWORD grfStatFlag) | |
| { | |
| CHECK_EXPECT2(Storage_Stat); | |
| ok(pstatstg != NULL, "pstatstg = NULL\n"); | |
| ok(grfStatFlag == STATFLAG_NONAME, "grfStatFlag = %x\n", grfStatFlag); | |
| memset(pstatstg, 0, sizeof(STATSTG)); | |
| pstatstg->type = STGTY_STORAGE; | |
| pstatstg->clsid = CLSID_WineTestOld; | |
| return S_OK; | |
| } | |
| static IStorageVtbl StorageVtbl = | |
| { | |
| Storage_QueryInterface, | |
| Storage_AddRef, | |
| Storage_Release, | |
| Storage_CreateStream, | |
| Storage_OpenStream, | |
| Storage_CreateStorage, | |
| Storage_OpenStorage, | |
| Storage_CopyTo, | |
| Storage_MoveElementTo, | |
| Storage_Commit, | |
| Storage_Revert, | |
| Storage_EnumElements, | |
| Storage_DestroyElement, | |
| Storage_RenameElement, | |
| Storage_SetElementTimes, | |
| Storage_SetClass, | |
| Storage_SetStateBits, | |
| Storage_Stat | |
| }; | |
| static IStorage Storage = { &StorageVtbl }; | |
| static void test_OleDoAutoConvert(void) | |
| { | |
| static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0}; | |
| static struct { | |
| DWORD reserved1; | |
| DWORD version; | |
| DWORD reserved2[5]; | |
| DWORD ansi_user_type_len; | |
| DWORD ansi_clipboard_format_len; | |
| DWORD reserved3; | |
| DWORD unicode_marker; | |
| DWORD unicode_user_type_len; | |
| DWORD unicode_clipboard_format_len; | |
| DWORD reserved4; | |
| } comp_obj_data; | |
| static struct { | |
| DWORD version; | |
| DWORD flags; | |
| DWORD link_update_option; | |
| DWORD reserved1; | |
| DWORD reserved_moniker_stream_size; | |
| DWORD relative_source_moniker_stream_size; | |
| DWORD absolute_source_moniker_stream_size; | |
| DWORD clsid_indicator; | |
| CLSID clsid; | |
| DWORD reserved_display_name; | |
| DWORD reserved2; | |
| DWORD local_update_time; | |
| DWORD local_check_update_time; | |
| DWORD remote_update_time; | |
| } ole_data; | |
| LARGE_INTEGER pos = {{0}}; | |
| WCHAR buf[39+6]; | |
| DWORD i, ret; | |
| HKEY root; | |
| CLSID clsid; | |
| HRESULT hr; | |
| hr = CreateStreamOnHGlobal(NULL, TRUE, &comp_obj_stream); | |
| ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr); | |
| hr = IStream_Write(comp_obj_stream, (char*)&comp_obj_data, sizeof(comp_obj_data), NULL); | |
| ok(hr == S_OK, "IStream_Write returned %x\n", hr); | |
| hr = CreateStreamOnHGlobal(NULL, TRUE, &ole_stream); | |
| ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr); | |
| hr = IStream_Write(ole_stream, (char*)&ole_data, sizeof(ole_data), NULL); | |
| ok(hr == S_OK, "IStream_Write returned %x\n", hr); | |
| clsid = IID_WineTest; | |
| hr = OleDoAutoConvert(NULL, &clsid); | |
| ok(hr == E_INVALIDARG, "OleDoAutoConvert returned %x\n", hr); | |
| ok(IsEqualIID(&clsid, &IID_NULL), "clsid = %s\n", wine_dbgstr_guid(&clsid)); | |
| if(0) /* crashes on Win7 */ | |
| OleDoAutoConvert(&Storage, NULL); | |
| clsid = IID_WineTest; | |
| SET_EXPECT(Storage_Stat); | |
| hr = OleDoAutoConvert(&Storage, &clsid); | |
| ok(hr == REGDB_E_CLASSNOTREG, "OleDoAutoConvert returned %x\n", hr); | |
| CHECK_CALLED(Storage_Stat); | |
| ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid)); | |
| lstrcpyW(buf, clsidW); | |
| StringFromGUID2(&CLSID_WineTestOld, buf+6, 39); | |
| ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0, | |
| KEY_READ | KEY_WRITE | KEY_CREATE_SUB_KEY, NULL, &root, NULL); | |
| if(ret != ERROR_SUCCESS) { | |
| win_skip("not enough permissions to create CLSID key (%u)\n", ret); | |
| return; | |
| } | |
| clsid = IID_WineTest; | |
| SET_EXPECT(Storage_Stat); | |
| hr = OleDoAutoConvert(&Storage, &clsid); | |
| ok(hr == REGDB_E_KEYMISSING, "OleDoAutoConvert returned %x\n", hr); | |
| CHECK_CALLED(Storage_Stat); | |
| ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid)); | |
| hr = OleSetAutoConvert(&CLSID_WineTestOld, &CLSID_WineTest); | |
| ok_ole_success(hr, "OleSetAutoConvert"); | |
| hr = OleGetAutoConvert(&CLSID_WineTestOld, &clsid); | |
| ok_ole_success(hr, "OleGetAutoConvert"); | |
| ok(IsEqualIID(&clsid, &CLSID_WineTest), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid)); | |
| clsid = IID_WineTest; | |
| SET_EXPECT(Storage_Stat); | |
| SET_EXPECT(Storage_OpenStream_CompObj); | |
| SET_EXPECT(Storage_SetClass); | |
| SET_EXPECT(Storage_CreateStream_CompObj); | |
| SET_EXPECT(Storage_OpenStream_Ole); | |
| hr = OleDoAutoConvert(&Storage, &clsid); | |
| ok(hr == S_OK, "OleDoAutoConvert returned %x\n", hr); | |
| CHECK_CALLED(Storage_Stat); | |
| CHECK_CALLED(Storage_OpenStream_CompObj); | |
| CHECK_CALLED(Storage_SetClass); | |
| CHECK_CALLED(Storage_CreateStream_CompObj); | |
| CHECK_CALLED(Storage_OpenStream_Ole); | |
| ok(IsEqualIID(&clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(&clsid)); | |
| hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); | |
| ok(hr == S_OK, "IStream_Seek returned %x\n", hr); | |
| hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL); | |
| ok(hr == S_OK, "IStream_Read returned %x\n", hr); | |
| ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1); | |
| ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version); | |
| ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]); | |
| ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1))); | |
| ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len); | |
| ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len); | |
| ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3); | |
| ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker); | |
| ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len); | |
| ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len); | |
| ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4); | |
| hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL); | |
| ok(hr == S_OK, "IStream_Seek returned %x\n", hr); | |
| hr = IStream_Read(ole_stream, &ole_data, sizeof(ole_data), NULL); | |
| ok(hr == S_OK, "IStream_Read returned %x\n", hr); | |
| ok(ole_data.version == 0, "version = %x\n", ole_data.version); | |
| ok(ole_data.flags == 4, "flags = %x\n", ole_data.flags); | |
| for(i=2; i<sizeof(ole_data)/sizeof(DWORD); i++) | |
| ok(((DWORD*)&ole_data)[i] == 0, "ole_data[%d] = %x\n", i, ((DWORD*)&ole_data)[i]); | |
| SET_EXPECT(Storage_OpenStream_Ole); | |
| hr = SetConvertStg(&Storage, TRUE); | |
| ok(hr == S_OK, "SetConvertStg returned %x\n", hr); | |
| CHECK_CALLED(Storage_OpenStream_Ole); | |
| SET_EXPECT(Storage_OpenStream_CompObj); | |
| SET_EXPECT(Storage_Stat); | |
| SET_EXPECT(Storage_CreateStream_CompObj); | |
| hr = WriteFmtUserTypeStg(&Storage, 0, NULL); | |
| ok(hr == S_OK, "WriteFmtUserTypeStg returned %x\n", hr); | |
| todo_wine CHECK_CALLED(Storage_OpenStream_CompObj); | |
| CHECK_CALLED(Storage_Stat); | |
| CHECK_CALLED(Storage_CreateStream_CompObj); | |
| hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); | |
| ok(hr == S_OK, "IStream_Seek returned %x\n", hr); | |
| hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL); | |
| ok(hr == S_OK, "IStream_Read returned %x\n", hr); | |
| ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1); | |
| ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version); | |
| ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]); | |
| ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1))); | |
| ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len); | |
| ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len); | |
| ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3); | |
| ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker); | |
| ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len); | |
| ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len); | |
| ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4); | |
| ret = IStream_Release(comp_obj_stream); | |
| ok(!ret, "comp_obj_stream was not freed\n"); | |
| ret = IStream_Release(ole_stream); | |
| ok(!ret, "ole_stream was not freed\n"); | |
| ret = RegDeleteKeyA(root, "AutoConvertTo"); | |
| ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret); | |
| ret = RegDeleteKeyA(root, ""); | |
| ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret); | |
| RegCloseKey(root); | |
| } | |
| START_TEST(ole2) | |
| { | |
| DWORD dwRegister; | |
| IStorage *pStorage; | |
| STATSTG statstg; | |
| HRESULT hr; | |
| cf_test_1 = RegisterClipboardFormatA("cf_winetest_1"); | |
| cf_test_2 = RegisterClipboardFormatA("cf_winetest_2"); | |
| cf_test_3 = RegisterClipboardFormatA("cf_winetest_3"); | |
| CoInitialize(NULL); | |
| hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister); | |
| ok_ole_success(hr, "CoRegisterClassObject"); | |
| hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage); | |
| ok_ole_success(hr, "StgCreateDocfile"); | |
| test_OleCreate(pStorage); | |
| hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME); | |
| ok_ole_success(hr, "IStorage_Stat"); | |
| ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n"); | |
| test_OleLoad(pStorage); | |
| IStorage_Release(pStorage); | |
| hr = CoRevokeClassObject(dwRegister); | |
| ok_ole_success(hr, "CoRevokeClassObject"); | |
| test_data_cache(); | |
| test_data_cache_dib_contents_stream( 0 ); | |
| test_data_cache_dib_contents_stream( 1 ); | |
| test_data_cache_bitmap(); | |
| test_data_cache_init(); | |
| test_data_cache_initnew(); | |
| test_default_handler(); | |
| test_runnable(); | |
| test_OleRun(); | |
| test_OleLockRunning(); | |
| test_OleDraw(); | |
| test_OleDoAutoConvert(); | |
| CoUninitialize(); | |
| } |