From 00257531cae3c975fe26ba2e146737d974c7382f Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Thu, 17 May 2012 15:17:09 +0000 Subject: [PATCH] [OLE32_WINETEST] * Sync to Wine 1.5.4. See issue #7070 for more details. svn path=/trunk/; revision=56598 --- rostests/winetests/ole32/clipboard.c | 127 +++++----- rostests/winetests/ole32/compobj.c | 116 +++++++-- rostests/winetests/ole32/dragdrop.c | 2 +- rostests/winetests/ole32/hglobalstream.c | 6 +- rostests/winetests/ole32/marshal.c | 148 ++++++++--- rostests/winetests/ole32/moniker.c | 40 +-- rostests/winetests/ole32/ole2.c | 304 +++++++++++++++++++++-- rostests/winetests/ole32/propvariant.c | 2 +- rostests/winetests/ole32/stg_prop.c | 13 +- rostests/winetests/ole32/storage32.c | 124 ++++++++- rostests/winetests/ole32/usrmarshal.c | 3 +- 11 files changed, 717 insertions(+), 168 deletions(-) diff --git a/rostests/winetests/ole32/clipboard.c b/rostests/winetests/ole32/clipboard.c index 626d244c073..1029a682726 100644 --- a/rostests/winetests/ole32/clipboard.c +++ b/rostests/winetests/ole32/clipboard.c @@ -19,6 +19,7 @@ */ #define COBJMACROS +#define CONST_VTABLE #define NONAMELESSUNION #include @@ -49,7 +50,7 @@ static inline char *dump_fmtetc(FORMATETC *fmt) } typedef struct DataObjectImpl { - const IDataObjectVtbl *lpVtbl; + IDataObject IDataObject_iface; LONG ref; FORMATETC *fmtetc; @@ -61,7 +62,7 @@ typedef struct DataObjectImpl { } DataObjectImpl; typedef struct EnumFormatImpl { - const IEnumFORMATETCVtbl *lpVtbl; + IEnumFORMATETC IEnumFORMATETC_iface; LONG ref; FORMATETC *fmtetc; @@ -79,9 +80,19 @@ static UINT cf_stream, cf_storage, cf_global, cf_another, cf_onemore; static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT size, LPENUMFORMATETC *lplpformatetc); +static inline DataObjectImpl *impl_from_IDataObject(IDataObject *iface) +{ + return CONTAINING_RECORD(iface, DataObjectImpl, IDataObject_iface); +} + +static inline EnumFormatImpl *impl_from_IEnumFORMATETC(IEnumFORMATETC *iface) +{ + return CONTAINING_RECORD(iface, EnumFormatImpl, IEnumFORMATETC_iface); +} + static HRESULT WINAPI EnumFormatImpl_QueryInterface(IEnumFORMATETC *iface, REFIID riid, LPVOID *ppvObj) { - EnumFormatImpl *This = (EnumFormatImpl*)iface; + EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface); if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumFORMATETC)) { IEnumFORMATETC_AddRef(iface); @@ -94,14 +105,14 @@ static HRESULT WINAPI EnumFormatImpl_QueryInterface(IEnumFORMATETC *iface, REFII static ULONG WINAPI EnumFormatImpl_AddRef(IEnumFORMATETC *iface) { - EnumFormatImpl *This = (EnumFormatImpl*)iface; + EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface); LONG ref = InterlockedIncrement(&This->ref); return ref; } static ULONG WINAPI EnumFormatImpl_Release(IEnumFORMATETC *iface) { - EnumFormatImpl *This = (EnumFormatImpl*)iface; + EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface); ULONG ref = InterlockedDecrement(&This->ref); if(!ref) { @@ -115,7 +126,7 @@ static ULONG WINAPI EnumFormatImpl_Release(IEnumFORMATETC *iface) static HRESULT WINAPI EnumFormatImpl_Next(IEnumFORMATETC *iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) { - EnumFormatImpl *This = (EnumFormatImpl*)iface; + EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface); ULONG count, i; trace("next: count %d cur %d\n", celt, This->cur); @@ -147,7 +158,7 @@ static HRESULT WINAPI EnumFormatImpl_Skip(IEnumFORMATETC *iface, ULONG celt) static HRESULT WINAPI EnumFormatImpl_Reset(IEnumFORMATETC *iface) { - EnumFormatImpl *This = (EnumFormatImpl*)iface; + EnumFormatImpl *This = impl_from_IEnumFORMATETC(iface); This->cur = 0; return S_OK; @@ -174,7 +185,7 @@ static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFO EnumFormatImpl *ret; ret = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumFormatImpl)); - ret->lpVtbl = &VT_EnumFormatImpl; + ret->IEnumFORMATETC_iface.lpVtbl = &VT_EnumFormatImpl; ret->ref = 1; ret->cur = 0; ret->fmtetc_cnt = fmtetc_cnt; @@ -186,7 +197,7 @@ static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFO static HRESULT WINAPI DataObjectImpl_QueryInterface(IDataObject *iface, REFIID riid, LPVOID *ppvObj) { - DataObjectImpl *This = (DataObjectImpl*)iface; + DataObjectImpl *This = impl_from_IDataObject(iface); if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDataObject)) { IDataObject_AddRef(iface); @@ -199,14 +210,14 @@ static HRESULT WINAPI DataObjectImpl_QueryInterface(IDataObject *iface, REFIID r static ULONG WINAPI DataObjectImpl_AddRef(IDataObject* iface) { - DataObjectImpl *This = (DataObjectImpl*)iface; + DataObjectImpl *This = impl_from_IDataObject(iface); ULONG ref = InterlockedIncrement(&This->ref); return ref; } static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface) { - DataObjectImpl *This = (DataObjectImpl*)iface; + DataObjectImpl *This = impl_from_IDataObject(iface); ULONG ref = InterlockedDecrement(&This->ref); if(!ref) @@ -226,7 +237,7 @@ static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface) static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pformatetc, STGMEDIUM *pmedium) { - DataObjectImpl *This = (DataObjectImpl*)iface; + DataObjectImpl *This = impl_from_IDataObject(iface); UINT i; BOOL foundFormat = FALSE; @@ -282,7 +293,7 @@ static HRESULT WINAPI DataObjectImpl_GetDataHere(IDataObject* iface, FORMATETC * static HRESULT WINAPI DataObjectImpl_QueryGetData(IDataObject* iface, FORMATETC *pformatetc) { - DataObjectImpl *This = (DataObjectImpl*)iface; + DataObjectImpl *This = impl_from_IDataObject(iface); UINT i; BOOL foundFormat = FALSE; @@ -320,7 +331,7 @@ static HRESULT WINAPI DataObjectImpl_SetData(IDataObject* iface, FORMATETC *pfor static HRESULT WINAPI DataObjectImpl_EnumFormatEtc(IDataObject* iface, DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc) { - DataObjectImpl *This = (DataObjectImpl*)iface; + DataObjectImpl *This = impl_from_IDataObject(iface); DataObjectImpl_EnumFormatEtc_calls++; @@ -371,7 +382,7 @@ static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj) DataObjectImpl *obj; obj = HeapAlloc(GetProcessHeap(), 0, sizeof(DataObjectImpl)); - obj->lpVtbl = &VT_DataObjectImpl; + obj->IDataObject_iface.lpVtbl = &VT_DataObjectImpl; obj->ref = 1; obj->text = GlobalAlloc(GMEM_MOVEABLE, strlen(text) + 1); strcpy(GlobalLock(obj->text), text); @@ -387,9 +398,9 @@ static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj) return S_OK; } -const char *cmpl_stm_data = "complex stream"; -const char *cmpl_text_data = "complex text"; -const WCHAR device_name[] = {'m','y','d','e','v',0}; +static const char *cmpl_stm_data = "complex stream"; +static const char *cmpl_text_data = "complex text"; +static const WCHAR device_name[] = {'m','y','d','e','v',0}; static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj) { @@ -398,7 +409,7 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj) DEVMODEW dm; obj = HeapAlloc(GetProcessHeap(), 0, sizeof(DataObjectImpl)); - obj->lpVtbl = &VT_DataObjectImpl; + obj->IDataObject_iface.lpVtbl = &VT_DataObjectImpl; obj->ref = 1; obj->text = GlobalAlloc(GMEM_MOVEABLE, strlen(cmpl_text_data) + 1); strcpy(GlobalLock(obj->text), cmpl_text_data); @@ -417,18 +428,21 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj) InitFormatEtc(obj->fmtetc[1], cf_stream, TYMED_ISTREAM); InitFormatEtc(obj->fmtetc[2], cf_storage, TYMED_ISTORAGE); InitFormatEtc(obj->fmtetc[3], cf_another, TYMED_ISTORAGE|TYMED_ISTREAM|TYMED_HGLOBAL); - memset(&dm, 0, sizeof(dm)); - dm.dmSize = sizeof(dm); - dm.dmDriverExtra = 0; - lstrcpyW(dm.dmDeviceName, device_name); - obj->fmtetc[3].ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra); - obj->fmtetc[3].ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra; - obj->fmtetc[3].ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData); - obj->fmtetc[3].ptd->tdDeviceNameOffset = 0; - obj->fmtetc[3].ptd->tdPortNameOffset = 0; - obj->fmtetc[3].ptd->tdExtDevmodeOffset = obj->fmtetc[3].ptd->tdDriverNameOffset + sizeof(device_name); - lstrcpyW((WCHAR*)obj->fmtetc[3].ptd->tdData, device_name); - memcpy(obj->fmtetc[3].ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra); + if (0) /* Causes crashes on both Wine and Windows */ + { + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + dm.dmDriverExtra = 0; + lstrcpyW(dm.dmDeviceName, device_name); + obj->fmtetc[3].ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra); + obj->fmtetc[3].ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra; + obj->fmtetc[3].ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData); + obj->fmtetc[3].ptd->tdDeviceNameOffset = 0; + obj->fmtetc[3].ptd->tdPortNameOffset = 0; + obj->fmtetc[3].ptd->tdExtDevmodeOffset = obj->fmtetc[3].ptd->tdDriverNameOffset + sizeof(device_name); + lstrcpyW((WCHAR*)obj->fmtetc[3].ptd->tdData, device_name); + memcpy(obj->fmtetc[3].ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra); + } InitFormatEtc(obj->fmtetc[4], cf_global, TYMED_HGLOBAL); InitFormatEtc(obj->fmtetc[5], cf_another, TYMED_HGLOBAL); @@ -812,15 +826,15 @@ static void test_set_clipboard(void) cf_onemore = RegisterClipboardFormatA("one more format"); hr = DataObjectImpl_CreateText("data1", &data1); - ok(SUCCEEDED(hr), "Failed to create data1 object: 0x%08x\n", hr); + ok(hr == S_OK, "Failed to create data1 object: 0x%08x\n", hr); if(FAILED(hr)) return; hr = DataObjectImpl_CreateText("data2", &data2); - ok(SUCCEEDED(hr), "Failed to create data2 object: 0x%08x\n", hr); + ok(hr == S_OK, "Failed to create data2 object: 0x%08x\n", hr); if(FAILED(hr)) return; hr = DataObjectImpl_CreateComplex(&data_cmpl); - ok(SUCCEEDED(hr), "Failed to create complex data object: 0x%08x\n", hr); + ok(hr == S_OK, "Failed to create complex data object: 0x%08x\n", hr); if(FAILED(hr)) return; @@ -1180,32 +1194,33 @@ static void test_flushed_getdata(void) /* complex format with target device */ InitFormatEtc(fmt, cf_another, 0xffff); - hr = IDataObject_GetData(get, &fmt, &med); - ok(hr == DV_E_FORMATETC || - broken(hr == S_OK), /* win9x, winme & nt4 */ - "got %08x\n", hr); - if(SUCCEEDED(hr)) ReleaseStgMedium(&med); - - InitFormatEtc(fmt, cf_another, 0xffff); - memset(&dm, 0, sizeof(dm)); - dm.dmSize = sizeof(dm); - dm.dmDriverExtra = 0; - lstrcpyW(dm.dmDeviceName, device_name); - fmt.ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra); - fmt.ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra; - fmt.ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData); - fmt.ptd->tdDeviceNameOffset = 0; - fmt.ptd->tdPortNameOffset = 0; - fmt.ptd->tdExtDevmodeOffset = fmt.ptd->tdDriverNameOffset + sizeof(device_name); - lstrcpyW((WCHAR*)fmt.ptd->tdData, device_name); - memcpy(fmt.ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra); - hr = IDataObject_GetData(get, &fmt, &med); ok(hr == S_OK, "got %08x\n", hr); - ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed); if(SUCCEEDED(hr)) ReleaseStgMedium(&med); - HeapFree(GetProcessHeap(), 0, fmt.ptd); + if (0) /* Causes crashes on both Wine and Windows */ + { + InitFormatEtc(fmt, cf_another, 0xffff); + memset(&dm, 0, sizeof(dm)); + dm.dmSize = sizeof(dm); + dm.dmDriverExtra = 0; + lstrcpyW(dm.dmDeviceName, device_name); + fmt.ptd = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra); + fmt.ptd->tdSize = FIELD_OFFSET(DVTARGETDEVICE, tdData) + sizeof(device_name) + dm.dmSize + dm.dmDriverExtra; + fmt.ptd->tdDriverNameOffset = FIELD_OFFSET(DVTARGETDEVICE, tdData); + fmt.ptd->tdDeviceNameOffset = 0; + fmt.ptd->tdPortNameOffset = 0; + fmt.ptd->tdExtDevmodeOffset = fmt.ptd->tdDriverNameOffset + sizeof(device_name); + lstrcpyW((WCHAR*)fmt.ptd->tdData, device_name); + memcpy(fmt.ptd->tdData + sizeof(device_name), &dm, dm.dmSize + dm.dmDriverExtra); + + hr = IDataObject_GetData(get, &fmt, &med); + ok(hr == S_OK, "got %08x\n", hr); + ok(med.tymed == TYMED_ISTORAGE, "got %x\n", med.tymed); + if(SUCCEEDED(hr)) ReleaseStgMedium(&med); + + HeapFree(GetProcessHeap(), 0, fmt.ptd); + } IDataObject_Release(get); diff --git a/rostests/winetests/ole32/compobj.c b/rostests/winetests/ole32/compobj.c index 755d15a9f66..ffb6910211c 100644 --- a/rostests/winetests/ole32/compobj.c +++ b/rostests/winetests/ole32/compobj.c @@ -38,11 +38,11 @@ extern const IID GUID_NULL; /* functions that are not present on all versions of Windows */ -HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit); -HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv); -HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppOldObject); -HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew); -HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token); +static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit); +static HRESULT (WINAPI * pCoGetObjectContext)(REFIID riid, LPVOID *ppv); +static HRESULT (WINAPI * pCoSwitchCallContext)(IUnknown *pObject, IUnknown **ppOldObject); +static HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew); +static HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token); #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks) @@ -117,7 +117,7 @@ static ULONG WINAPI Test_IClassFactory_Release(LPCLASSFACTORY iface) static HRESULT WINAPI Test_IClassFactory_CreateInstance( LPCLASSFACTORY iface, - LPUNKNOWN pUnkOuter, + IUnknown *pUnkOuter, REFIID riid, LPVOID *ppvObj) { @@ -192,6 +192,9 @@ static void test_CLSIDFromProgID(void) static void test_CLSIDFromString(void) { CLSID clsid; + WCHAR wszCLSID_Broken[50]; + UINT i; + HRESULT hr = CLSIDFromString(wszCLSID_StdFont, &clsid); ok_ole_success(hr, "CLSIDFromString"); ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n"); @@ -199,6 +202,60 @@ static void test_CLSIDFromString(void) hr = CLSIDFromString(NULL, &clsid); ok_ole_success(hr, "CLSIDFromString"); ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n"); + + lstrcpyW(wszCLSID_Broken, wszCLSID_StdFont); + for(i = lstrlenW(wszCLSID_StdFont); i < 49; i++) + wszCLSID_Broken[i] = 'A'; + wszCLSID_Broken[i] = '\0'; + + memset(&clsid, 0, sizeof(CLSID)); + hr = CLSIDFromString(wszCLSID_Broken, &clsid); + ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr); + ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n"); + + wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = 'A'; + memset(&clsid, 0, sizeof(CLSID)); + hr = CLSIDFromString(wszCLSID_Broken, &clsid); + ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr); + ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n"); + + wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)] = '\0'; + memset(&clsid, 0, sizeof(CLSID)); + hr = CLSIDFromString(wszCLSID_Broken, &clsid); + ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr); + ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n"); + + wszCLSID_Broken[lstrlenW(wszCLSID_StdFont)-1] = '\0'; + memset(&clsid, 0, sizeof(CLSID)); + hr = CLSIDFromString(wszCLSID_Broken, &clsid); + ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr); + ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n"); + + memset(&clsid, 0xcc, sizeof(CLSID)); + hr = CLSIDFromString(wszCLSID_Broken+1, &clsid); + ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr); + ok(IsEqualCLSID(&clsid, &CLSID_NULL), "clsid wasn't equal to CLSID_NULL\n"); + + wszCLSID_Broken[9] = '*'; + memset(&clsid, 0xcc, sizeof(CLSID)); + hr = CLSIDFromString(wszCLSID_Broken, &clsid); + ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr); + ok(clsid.Data1 == CLSID_StdFont.Data1, "Got %08x\n", clsid.Data1); + ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2); + + wszCLSID_Broken[3] = '*'; + memset(&clsid, 0xcc, sizeof(CLSID)); + hr = CLSIDFromString(wszCLSID_Broken, &clsid); + ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr); + ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1); + ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2); + + wszCLSID_Broken[3] = '\0'; + memset(&clsid, 0xcc, sizeof(CLSID)); + hr = CLSIDFromString(wszCLSID_Broken, &clsid); + ok(hr == CO_E_CLASSSTRING, "Got %08x\n", hr); + ok(clsid.Data1 == 0xb, "Got %08x\n", clsid.Data1); + ok(clsid.Data2 == 0xcccc, "Got %04x\n", clsid.Data2); } static void test_StringFromGUID2(void) @@ -515,7 +572,7 @@ static void test_CoRegisterMessageFilter(void) } static HRESULT WINAPI Test_IUnknown_QueryInterface( - LPUNKNOWN iface, + IUnknown *iface, REFIID riid, LPVOID *ppvObj) { @@ -533,12 +590,12 @@ static HRESULT WINAPI Test_IUnknown_QueryInterface( return E_NOINTERFACE; } -static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface) +static ULONG WINAPI Test_IUnknown_AddRef(IUnknown *iface) { return 2; /* non-heap-based object */ } -static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface) +static ULONG WINAPI Test_IUnknown_Release(IUnknown *iface) { return 1; /* non-heap-based object */ } @@ -872,7 +929,7 @@ static void test_CoRegisterClassObject(void) /* crashes with at least win9x DCOM! */ if (0) - hr = CoRevokeClassObject(cookie); + CoRevokeClassObject(cookie); CoUninitialize(); } @@ -1216,10 +1273,15 @@ static void test_CoGetObjectContext(void) } typedef struct { - const IUnknownVtbl *lpVtbl; + IUnknown IUnknown_iface; LONG refs; } Test_CallContext; +static inline Test_CallContext *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, Test_CallContext, IUnknown_iface); +} + static HRESULT WINAPI Test_CallContext_QueryInterface( IUnknown *iface, REFIID riid, @@ -1240,13 +1302,13 @@ static HRESULT WINAPI Test_CallContext_QueryInterface( static ULONG WINAPI Test_CallContext_AddRef(IUnknown *iface) { - Test_CallContext *This = (Test_CallContext*)iface; + Test_CallContext *This = impl_from_IUnknown(iface); return InterlockedIncrement(&This->refs); } static ULONG WINAPI Test_CallContext_Release(IUnknown *iface) { - Test_CallContext *This = (Test_CallContext*)iface; + Test_CallContext *This = impl_from_IUnknown(iface); ULONG refs = InterlockedDecrement(&This->refs); if (!refs) HeapFree(GetProcessHeap(), 0, This); @@ -1265,7 +1327,7 @@ static void test_CoGetCallContext(void) HRESULT hr; ULONG refs; IUnknown *pUnk; - IUnknown *test_object; + Test_CallContext *test_object; if (!pCoSwitchCallContext) { @@ -1276,41 +1338,43 @@ static void test_CoGetCallContext(void) CoInitialize(NULL); test_object = HeapAlloc(GetProcessHeap(), 0, sizeof(Test_CallContext)); - ((Test_CallContext*)test_object)->lpVtbl = &TestCallContext_Vtbl; - ((Test_CallContext*)test_object)->refs = 1; + test_object->IUnknown_iface.lpVtbl = &TestCallContext_Vtbl; + test_object->refs = 1; hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk); ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr); pUnk = (IUnknown*)0xdeadbeef; - hr = pCoSwitchCallContext(test_object, &pUnk); + hr = pCoSwitchCallContext(&test_object->IUnknown_iface, &pUnk); ok_ole_success(hr, "CoSwitchCallContext"); ok(pUnk == NULL, "expected NULL, got %p\n", pUnk); - refs = IUnknown_AddRef(test_object); + refs = IUnknown_AddRef(&test_object->IUnknown_iface); ok(refs == 2, "Expected refcount 2, got %d\n", refs); - IUnknown_Release(test_object); + IUnknown_Release(&test_object->IUnknown_iface); pUnk = (IUnknown*)0xdeadbeef; hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk); ok_ole_success(hr, "CoGetCallContext"); - ok(pUnk == test_object, "expected %p, got %p\n", test_object, pUnk); - refs = IUnknown_AddRef(test_object); + ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n", + &test_object->IUnknown_iface, pUnk); + refs = IUnknown_AddRef(&test_object->IUnknown_iface); ok(refs == 3, "Expected refcount 3, got %d\n", refs); - IUnknown_Release(test_object); + IUnknown_Release(&test_object->IUnknown_iface); IUnknown_Release(pUnk); pUnk = (IUnknown*)0xdeadbeef; hr = pCoSwitchCallContext(NULL, &pUnk); ok_ole_success(hr, "CoSwitchCallContext"); - ok(pUnk == test_object, "expected %p, got %p\n", test_object, pUnk); - refs = IUnknown_AddRef(test_object); + ok(pUnk == &test_object->IUnknown_iface, "expected %p, got %p\n", + &test_object->IUnknown_iface, pUnk); + refs = IUnknown_AddRef(&test_object->IUnknown_iface); ok(refs == 2, "Expected refcount 2, got %d\n", refs); - IUnknown_Release(test_object); + IUnknown_Release(&test_object->IUnknown_iface); hr = CoGetCallContext(&IID_IUnknown, (void**)&pUnk); ok(hr == RPC_E_CALL_COMPLETE, "Expected RPC_E_CALL_COMPLETE, got 0x%08x\n", hr); - IUnknown_Release(test_object); + IUnknown_Release(&test_object->IUnknown_iface); CoUninitialize(); } diff --git a/rostests/winetests/ole32/dragdrop.c b/rostests/winetests/ole32/dragdrop.c index 18674dd5b09..b0e1259f52e 100644 --- a/rostests/winetests/ole32/dragdrop.c +++ b/rostests/winetests/ole32/dragdrop.c @@ -39,7 +39,7 @@ static int droptarget_refs; static HRESULT WINAPI DropTarget_QueryInterface(IDropTarget* iface, REFIID riid, void** ppvObject) { - trace("DropTarget_QueryInterface\n"); + ok(0, "DropTarget_QueryInterface() shouldn't be called\n"); if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropTarget)) { diff --git a/rostests/winetests/ole32/hglobalstream.c b/rostests/winetests/ole32/hglobalstream.c index 0810d9fa5d8..769d5a1a1ed 100644 --- a/rostests/winetests/ole32/hglobalstream.c +++ b/rostests/winetests/ole32/hglobalstream.c @@ -175,7 +175,7 @@ static void test_streamonhglobal(IStream *pStream) ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; - ll.u.LowPart = -sizeof(data); + ll.u.LowPart = -(DWORD)sizeof(data); hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok_ole_success(hr, "IStream_Seek"); ok(ull.u.LowPart == 0, "LowPart set to %d\n", ull.u.LowPart); @@ -190,7 +190,7 @@ static void test_streamonhglobal(IStream *pStream) ull.u.HighPart = 0xCAFECAFE; ull.u.LowPart = 0xCAFECAFE; ll.u.HighPart = 0; - ll.u.LowPart = -sizeof(data)-1; + ll.u.LowPart = -(DWORD)sizeof(data)-1; hr = IStream_Seek(pStream, ll, STREAM_SEEK_CUR, &ull); ok(hr == STG_E_SEEKERROR, "IStream_Seek should have returned STG_E_SEEKERROR instead of 0x%08x\n", hr); ok(ull.u.LowPart == sizeof(data), "LowPart set to %d\n", ull.u.LowPart); @@ -421,6 +421,8 @@ static void test_copyto(void) static const LARGE_INTEGER llZero; char buffer[15]; + ok_ole_success(hr, "CreateStreamOnHGlobal"); + expected_method_list = methods_copyto; hr = IStream_Write(pStream, szHello, sizeof(szHello), &written); diff --git a/rostests/winetests/ole32/marshal.c b/rostests/winetests/ole32/marshal.c index 20b0d8ba8ef..c1789125831 100644 --- a/rostests/winetests/ole32/marshal.c +++ b/rostests/winetests/ole32/marshal.c @@ -36,9 +36,10 @@ #include "wine/test.h" DEFINE_GUID(CLSID_StdGlobalInterfaceTable,0x00000323,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); +DEFINE_GUID(CLSID_ManualResetEvent, 0x0000032c,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); /* functions that are not present on all versions of Windows */ -HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit); +static HRESULT (WINAPI * pCoInitializeEx)(LPVOID lpReserved, DWORD dwCoInit); /* helper macros to make tests a bit leaner */ #define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks) @@ -1437,14 +1438,8 @@ static DWORD CALLBACK bad_thread_proc(LPVOID p) /* Win9x returns E_NOINTERFACE, whilst NT returns RPC_E_WRONG_THREAD */ trace("call to proxy's QueryInterface from wrong apartment returned 0x%08x\n", hr); - /* this statement causes Win9x DCOM to crash during CoUninitialize of - * other apartment, so don't test this on Win9x (signified by NT-only - * export of CoRegisterSurrogateEx) */ - if (GetProcAddress(GetModuleHandle("ole32"), "CoRegisterSurrogateEx")) - /* now be really bad and release the proxy from the wrong apartment */ - IUnknown_Release(cf); - else - skip("skipping test for releasing proxy from wrong apartment that will succeed, but cause a crash during CoUninitialize\n"); + /* now be really bad and release the proxy from the wrong apartment */ + IUnknown_Release(cf); CoUninitialize(); @@ -1703,10 +1698,15 @@ static void test_proxy_interfaces(void) typedef struct { - const IUnknownVtbl *lpVtbl; + IUnknown IUnknown_iface; ULONG refs; } HeapUnknown; +static inline HeapUnknown *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface); +} + static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { if (IsEqualIID(riid, &IID_IUnknown)) @@ -1721,13 +1721,13 @@ static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, v static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface) { - HeapUnknown *This = (HeapUnknown *)iface; + HeapUnknown *This = impl_from_IUnknown(iface); return InterlockedIncrement((LONG*)&This->refs); } static ULONG WINAPI HeapUnknown_Release(IUnknown *iface) { - HeapUnknown *This = (HeapUnknown *)iface; + HeapUnknown *This = impl_from_IUnknown(iface); ULONG refs = InterlockedDecrement((LONG*)&This->refs); if (!refs) HeapFree(GetProcessHeap(), 0, This); return refs; @@ -1750,7 +1750,7 @@ static void test_proxybuffer(REFIID riid) CLSID clsid; HeapUnknown *pUnkOuter = HeapAlloc(GetProcessHeap(), 0, sizeof(*pUnkOuter)); - pUnkOuter->lpVtbl = &HeapUnknown_Vtbl; + pUnkOuter->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl; pUnkOuter->refs = 1; hr = CoGetPSClsid(riid, &clsid); @@ -1759,21 +1759,17 @@ static void test_proxybuffer(REFIID riid) hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (LPVOID*)&psfb); ok_ole_success(hr, CoGetClassObject); - hr = IPSFactoryBuffer_CreateProxy(psfb, (IUnknown*)pUnkOuter, riid, &proxy, &lpvtbl); + hr = IPSFactoryBuffer_CreateProxy(psfb, &pUnkOuter->IUnknown_iface, riid, &proxy, &lpvtbl); ok_ole_success(hr, IPSFactoryBuffer_CreateProxy); ok(lpvtbl != NULL, "IPSFactoryBuffer_CreateProxy succeeded, but returned a NULL vtable!\n"); /* release our reference to the outer unknown object - the PS factory * buffer will have AddRef's it in the CreateProxy call */ - refs = IUnknown_Release((IUnknown *)pUnkOuter); + refs = IUnknown_Release(&pUnkOuter->IUnknown_iface); ok(refs == 1, "Ref count of outer unknown should have been 1 instead of %d\n", refs); - refs = IPSFactoryBuffer_Release(psfb); - if (0) - { - /* not reliable on native. maybe it leaks references! */ - ok(refs == 0, "Ref-count leak of %d on IPSFactoryBuffer\n", refs); - } + /* Not checking return, unreliable on native. Maybe it leaks references? */ + IPSFactoryBuffer_Release(psfb); refs = IUnknown_Release((IUnknown *)lpvtbl); ok(refs == 0, "Ref-count leak of %d on IRpcProxyBuffer\n", refs); @@ -1801,12 +1797,8 @@ static void test_stubbuffer(REFIID riid) hr = IPSFactoryBuffer_CreateStub(psfb, riid, (IUnknown*)&Test_ClassFactory, &stub); ok_ole_success(hr, IPSFactoryBuffer_CreateStub); - refs = IPSFactoryBuffer_Release(psfb); - if (0) - { - /* not reliable on native. maybe it leaks references */ - ok(refs == 0, "Ref-count leak of %d on IPSFactoryBuffer\n", refs); - } + /* Not checking return, unreliable on native. Maybe it leaks references? */ + IPSFactoryBuffer_Release(psfb); ok_more_than_one_lock(); @@ -1845,7 +1837,7 @@ static const IClassFactoryVtbl TestREClassFactory_Vtbl = Test_IClassFactory_LockServer }; -IClassFactory TestRE_ClassFactory = { &TestREClassFactory_Vtbl }; +static IClassFactory TestRE_ClassFactory = { &TestREClassFactory_Vtbl }; static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { @@ -1878,6 +1870,7 @@ static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l /* note the use of the magic IID_IWineTest value to tell remote thread * to try to send a message back to us */ hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IWineTest, (void **)&object); + ok(hr == S_FALSE, "expected S_FALSE, got %d\n", hr); IClassFactory_Release(proxy); @@ -1917,6 +1910,7 @@ static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l * WM_QUIT message doesn't stop the call from succeeding */ PostMessage(hwnd, WM_QUIT, 0, 0); hr = IClassFactory_CreateInstance(proxy, NULL, &IID_IUnknown, (void **)&object); + ok(hr == S_FALSE, "IClassFactory_CreateInstance returned 0x%08x, expected S_FALSE\n", hr); IClassFactory_Release(proxy); @@ -2011,7 +2005,7 @@ static IClassFactoryVtbl TestMsgClassFactory_Vtbl = Test_IClassFactory_LockServer }; -IClassFactory TestMsg_ClassFactory = { &TestMsgClassFactory_Vtbl }; +static IClassFactory TestMsg_ClassFactory = { &TestMsgClassFactory_Vtbl }; static void test_call_from_message(void) { @@ -2274,7 +2268,7 @@ static void test_freethreadedmarshaler(void) IMarshal_Release(pFTMarshal); } -static void reg_unreg_wine_test_class(BOOL Register) +static HRESULT reg_unreg_wine_test_class(BOOL Register) { HRESULT hr; char buffer[256]; @@ -2292,9 +2286,16 @@ static void reg_unreg_wine_test_class(BOOL Register) if (Register) { error = RegCreateKeyEx(HKEY_CLASSES_ROOT, buffer, 0, NULL, 0, KEY_SET_VALUE, NULL, &hkey, &dwDisposition); + if (error == ERROR_ACCESS_DENIED) + { + skip("Not authorized to modify the Classes key\n"); + return E_FAIL; + } ok(error == ERROR_SUCCESS, "RegCreateKeyEx failed with error %d\n", error); + if (error != ERROR_SUCCESS) hr = E_FAIL; error = RegSetValueEx(hkey, NULL, 0, REG_SZ, (const unsigned char *)"\"ole32.dll\"", strlen("\"ole32.dll\"") + 1); ok(error == ERROR_SUCCESS, "RegSetValueEx failed with error %d\n", error); + if (error != ERROR_SUCCESS) hr = E_FAIL; RegCloseKey(hkey); } else @@ -2303,6 +2304,7 @@ static void reg_unreg_wine_test_class(BOOL Register) *strrchr(buffer, '\\') = '\0'; RegDeleteKey(HKEY_CLASSES_ROOT, buffer); } + return hr; } static void test_inproc_handler(void) @@ -2311,7 +2313,8 @@ static void test_inproc_handler(void) IUnknown *pObject; IUnknown *pObject2; - reg_unreg_wine_test_class(TRUE); + if (FAILED(reg_unreg_wine_test_class(TRUE))) + return; hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pObject); ok_ole_success(hr, "CoCreateInstance"); @@ -2392,7 +2395,8 @@ static void test_handler_marshaling(void) HANDLE thread; static const LARGE_INTEGER ullZero; - reg_unreg_wine_test_class(TRUE); + if (FAILED(reg_unreg_wine_test_class(TRUE))) + return; cLocks = 0; hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream); @@ -2645,6 +2649,7 @@ static HANDLE create_target_process(const char *arg) { char **argv; char cmdline[MAX_PATH]; + BOOL ret; PROCESS_INFORMATION pi; STARTUPINFO si = { 0 }; si.cb = sizeof(si); @@ -2653,8 +2658,8 @@ static HANDLE create_target_process(const char *arg) pi.hProcess = NULL; winetest_get_mainargs( &argv ); sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg); - ok(CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, - &si, &pi) != 0, "CreateProcess failed with error: %u\n", GetLastError()); + ret = CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + ok(ret, "CreateProcess failed with error: %u\n", GetLastError()); if (pi.hThread) CloseHandle(pi.hThread); return pi.hProcess; } @@ -2843,6 +2848,68 @@ static void test_globalinterfacetable(void) IGlobalInterfaceTable_Release(git); } +static void test_manualresetevent(void) +{ + ISynchronize *psync1, *psync2; + IUnknown *punk; + LONG ref; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&punk); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(!!punk, "Got NULL.\n"); + IUnknown_Release(punk); + + hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_ISynchronize, (void**)&psync1); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(!!psync1, "Got NULL.\n"); + + hr = ISynchronize_Wait(psync1, 0, 5); + ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr); + + hr = ISynchronize_Reset(psync1); + ok(hr == S_OK, "Got 0x%08x\n", hr); + hr = ISynchronize_Signal(psync1); + ok(hr == S_OK, "Got 0x%08x\n", hr); + hr = ISynchronize_Wait(psync1, 0, 5); + ok(hr == S_OK, "Got 0x%08x\n", hr); + hr = ISynchronize_Wait(psync1, 0, 5); + ok(hr == S_OK, "Got 0x%08x\n", hr); + hr = ISynchronize_Reset(psync1); + ok(hr == S_OK, "Got 0x%08x\n", hr); + hr = ISynchronize_Wait(psync1, 0, 5); + ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr); + + hr = CoCreateInstance(&CLSID_ManualResetEvent, NULL, CLSCTX_INPROC_SERVER, &IID_ISynchronize, (void**)&psync2); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(!!psync2, "Got NULL.\n"); + ok(psync1 != psync2, "psync1 == psync2.\n"); + hr = ISynchronize_Wait(psync2, 0, 5); + ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr); + + hr = ISynchronize_Reset(psync1); + ok(hr == S_OK, "Got 0x%08x\n", hr); + hr = ISynchronize_Reset(psync2); + ok(hr == S_OK, "Got 0x%08x\n", hr); + hr = ISynchronize_Signal(psync1); + ok(hr == S_OK, "Got 0x%08x\n", hr); + hr = ISynchronize_Wait(psync2, 0, 5); + ok(hr == RPC_S_CALLPENDING, "Got 0x%08x\n", hr); + + ref = ISynchronize_AddRef(psync1); + ok(ref == 2, "Got ref: %d\n", ref); + ref = ISynchronize_AddRef(psync1); + ok(ref == 3, "Got ref: %d\n", ref); + ref = ISynchronize_Release(psync1); + ok(ref == 2, "Got nonzero ref: %d\n", ref); + ref = ISynchronize_Release(psync2); + ok(!ref, "Got nonzero ref: %d\n", ref); + ref = ISynchronize_Release(psync1); + ok(ref == 1, "Got nonzero ref: %d\n", ref); + ref = ISynchronize_Release(psync1); + ok(!ref, "Got nonzero ref: %d\n", ref); +} + static const char *debugstr_iid(REFIID riid) { static char name[256]; @@ -3060,7 +3127,12 @@ START_TEST(marshal) int argc; char **argv; - if (!(pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx"))) goto no_test; + if (!GetProcAddress(hOle32, "CoRegisterSurrogateEx")) { + win_skip("skipping test on win9x\n"); + return; + } + + pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx"); argc = winetest_get_mainargs( &argv ); if (argc > 2 && (!strcmp(argv[2], "-Embedding"))) @@ -3122,14 +3194,10 @@ START_TEST(marshal) test_local_server(); test_globalinterfacetable(); + test_manualresetevent(); /* must be last test as channel hooks can't be unregistered */ test_channel_hook(); CoUninitialize(); - return; - -no_test: - trace("You need DCOM95 installed to run this test\n"); - return; } diff --git a/rostests/winetests/ole32/moniker.c b/rostests/winetests/ole32/moniker.c index 876d034bcbc..a407a3776eb 100644 --- a/rostests/winetests/ole32/moniker.c +++ b/rostests/winetests/ole32/moniker.c @@ -28,6 +28,7 @@ #include "windef.h" #include "winbase.h" #include "objbase.h" +#include "ocidl.h" #include "initguid.h" #include "comcat.h" #include "olectl.h" @@ -156,10 +157,15 @@ static IClassFactory Test_ClassFactory = { &TestClassFactory_Vtbl }; typedef struct { - const IUnknownVtbl *lpVtbl; + IUnknown IUnknown_iface; ULONG refs; } HeapUnknown; +static inline HeapUnknown *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, HeapUnknown, IUnknown_iface); +} + static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { if (IsEqualIID(riid, &IID_IUnknown)) @@ -174,13 +180,13 @@ static HRESULT WINAPI HeapUnknown_QueryInterface(IUnknown *iface, REFIID riid, v static ULONG WINAPI HeapUnknown_AddRef(IUnknown *iface) { - HeapUnknown *This = (HeapUnknown *)iface; + HeapUnknown *This = impl_from_IUnknown(iface); return InterlockedIncrement((LONG*)&This->refs); } static ULONG WINAPI HeapUnknown_Release(IUnknown *iface) { - HeapUnknown *This = (HeapUnknown *)iface; + HeapUnknown *This = impl_from_IUnknown(iface); ULONG refs = InterlockedDecrement((LONG*)&This->refs); if (!refs) HeapFree(GetProcessHeap(), 0, This); return refs; @@ -1007,7 +1013,6 @@ static void test_MkParseDisplayName(void) hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1); /* Register a couple of Monikers and check is ok */ ok(hr==0, "IEnumMoniker_QueryInterface hr %08x %p\n", hr, lpEM1); - hr = MK_E_NOOBJECT; matchCnt = count_moniker_matches(pbc, spEM1); trace("Number of matches is %i\n", matchCnt); @@ -1271,6 +1276,7 @@ static void test_moniker( IROTData_Release(rotdata); hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok_ole_success(hr, CreateStreamOnHGlobal); /* Saving */ @@ -1451,6 +1457,7 @@ static void test_file_moniker(WCHAR* path) ok_ole_success(hr, CreateFileMoniker); hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok_ole_success(hr, CreateStreamOnHGlobal); /* Marshal */ hr = CoMarshalInterface(stream, &IID_IMoniker, (IUnknown *)moniker1, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL); @@ -1774,9 +1781,9 @@ static void test_pointer_moniker(void) /* Hashing */ hr = IMoniker_Hash(moniker, &hash); ok_ole_success(hr, IMoniker_Hash); - ok(hash == (DWORD)&Test_ClassFactory, + ok(hash == PtrToUlong(&Test_ClassFactory), "Hash value should have been 0x%08x, instead of 0x%08x\n", - (DWORD)&Test_ClassFactory, hash); + PtrToUlong(&Test_ClassFactory), hash); /* IsSystemMoniker test */ hr = IMoniker_IsSystemMoniker(moniker, &moniker_type); @@ -1880,9 +1887,9 @@ static void test_bind_context(void) ok(hr == E_INVALIDARG, "IBindCtx_RegisterObjectParam should have returned E_INVALIDARG instead of 0x%08x\n", hr); unknown = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown)); - unknown->lpVtbl = &HeapUnknown_Vtbl; + unknown->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl; unknown->refs = 1; - hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, (IUnknown *)&unknown->lpVtbl); + hr = IBindCtx_RegisterObjectParam(pBindCtx, (WCHAR *)wszParamName, &unknown->IUnknown_iface); ok_ole_success(hr, "IBindCtx_RegisterObjectParam"); hr = IBindCtx_GetObjectParam(pBindCtx, (WCHAR *)wszParamName, ¶m_obj); @@ -1907,23 +1914,23 @@ static void test_bind_context(void) ok(hr == E_INVALIDARG, "IBindCtx_RevokeObjectBound(NULL) should have return E_INVALIDARG instead of 0x%08x\n", hr); unknown2 = HeapAlloc(GetProcessHeap(), 0, sizeof(*unknown)); - unknown2->lpVtbl = &HeapUnknown_Vtbl; + unknown2->IUnknown_iface.lpVtbl = &HeapUnknown_Vtbl; unknown2->refs = 1; - hr = IBindCtx_RegisterObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl); + hr = IBindCtx_RegisterObjectBound(pBindCtx, &unknown2->IUnknown_iface); ok_ole_success(hr, "IBindCtx_RegisterObjectBound"); - hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl); + hr = IBindCtx_RevokeObjectBound(pBindCtx, &unknown2->IUnknown_iface); ok_ole_success(hr, "IBindCtx_RevokeObjectBound"); - hr = IBindCtx_RevokeObjectBound(pBindCtx, (IUnknown *)&unknown2->lpVtbl); + hr = IBindCtx_RevokeObjectBound(pBindCtx, &unknown2->IUnknown_iface); ok(hr == MK_E_NOTBOUND, "IBindCtx_RevokeObjectBound with not bound object should have returned MK_E_NOTBOUND instead of 0x%08x\n", hr); IBindCtx_Release(pBindCtx); - refs = IUnknown_Release((IUnknown *)&unknown->lpVtbl); + refs = IUnknown_Release(&unknown->IUnknown_iface); ok(!refs, "object param should have been destroyed, instead of having %d refs\n", refs); - refs = IUnknown_Release((IUnknown *)&unknown2->lpVtbl); + refs = IUnknown_Release(&unknown2->IUnknown_iface); ok(!refs, "bound object should have been destroyed, instead of having %d refs\n", refs); } @@ -1998,6 +2005,11 @@ static void test_save_load_filemoniker(void) START_TEST(moniker) { + if (!GetProcAddress(GetModuleHandleA("ole32.dll"), "CoRegisterSurrogateEx")) { + win_skip("skipping test on win9x\n"); + return; + } + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); test_ROT(); diff --git a/rostests/winetests/ole32/ole2.c b/rostests/winetests/ole32/ole2.c index 6d02206d3bc..7b4f36a8215 100644 --- a/rostests/winetests/ole32/ole2.c +++ b/rostests/winetests/ole32/ole2.c @@ -20,9 +20,10 @@ #define COBJMACROS #define CONST_VTABLE +#define WIN32_LEAN_AND_MEAN #include -#define NOCRYPT + #include "windef.h" #include "winbase.h" #include "objbase.h" @@ -44,7 +45,16 @@ static const CLSID CLSID_WineTest = {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 { @@ -53,21 +63,38 @@ struct expected_method }; static const struct expected_method *expected_method_list; +static FORMATETC *g_expected_fetc = NULL; -BOOL g_showRunnable = TRUE; -BOOL g_isRunning = TRUE; +static BOOL g_showRunnable = TRUE; +static BOOL g_isRunning = TRUE; +static BOOL g_failGetMiscStatus; +static HRESULT g_QIFailsWith; + +static UINT cf_test_1, cf_test_2, cf_test_3; #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++; \ - ok(!strcmp(expected_method_list->method, method_name), "Expected %s to be called instead of %s\n", \ - expected_method_list->method, method_name); \ + if (expected_method_list->flags & TEST_TODO) \ + todo_wine \ + ok(!strcmp(expected_method_list->method, method_name), \ + "Expected %s to be called instead of %s\n", \ + expected_method_list->method, method_name); \ + else \ + 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) @@ -93,6 +120,8 @@ static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, v *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); @@ -327,8 +356,16 @@ static HRESULT WINAPI OleObject_GetMiscStatus ) { CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus"); - *pdwStatus = DVASPECT_CONTENT; - return S_OK; + if(!g_failGetMiscStatus) + { + *pdwStatus = OLEMISC_RECOMPOSEONRESIZE; + return S_OK; + } + else + { + *pdwStatus = 0x1234; + return E_FAIL; + } } static HRESULT WINAPI OleObject_SetColorScheme @@ -496,6 +533,22 @@ static HRESULT WINAPI OleObjectCache_Cache ) { 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; } @@ -796,6 +849,12 @@ static void test_OleCreate(IStorage *pStorage) { 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; @@ -836,6 +895,8 @@ static void test_OleCreate(IStorage *pStorage) 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"); @@ -853,6 +914,7 @@ static void test_OleCreate(IStorage *pStorage) IOleObject_Release(pObject); CHECK_NO_EXTRA_METHODS(); trace("end\n"); + g_expected_fetc = NULL; } static void test_OleLoad(IStorage *pStorage) @@ -874,10 +936,32 @@ static void test_OleLoad(IStorage *pStorage) { "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_failGetMiscStatus = TRUE; + 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(); + } + + /* Test again, let IOleObject_GetMiscStatus succeed. */ + g_failGetMiscStatus = FALSE; expected_method_list = methods_oleload; trace("OleLoad:\n"); hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject); @@ -886,6 +970,11 @@ static void test_OleLoad(IStorage *pStorage) "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(); } @@ -897,6 +986,12 @@ static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param) 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)) @@ -972,6 +1067,8 @@ static HRESULT WINAPI DataObject_QueryInterface( REFIID riid, void** ppvObject) { + CHECK_EXPECTED_METHOD("DataObject_QueryInterface"); + if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown)) { *ppvObject = iface; @@ -984,12 +1081,14 @@ static HRESULT WINAPI DataObject_QueryInterface( 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; } @@ -1054,8 +1153,20 @@ static HRESULT WINAPI DataObject_DAdvise( 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; } @@ -1101,6 +1212,7 @@ static void test_data_cache(void) IPersistStorage *pPS; IViewObject *pViewObject; IOleCacheControl *pOleCacheControl; + IDataObject *pCacheDataObject; FORMATETC fmtetc; STGMEDIUM stgmedium; DWORD dwConnection; @@ -1116,7 +1228,8 @@ static void test_data_cache(void) { { "AdviseSink_OnViewChange", 0 }, { "AdviseSink_OnViewChange", 0 }, - { "draw_continue", 0 }, + { "draw_continue", 1 }, + { "draw_continue_false", 1 }, { "DataObject_DAdvise", 0 }, { "DataObject_DAdvise", 0 }, { "DataObject_DUnadvise", 0 }, @@ -1126,14 +1239,27 @@ static void test_data_cache(void) static const struct expected_method methods_cacheload[] = { { "AdviseSink_OnViewChange", 0 }, - { "draw_continue", 0 }, - { "draw_continue", 0 }, - { "draw_continue", 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 } + }; GetSystemDirectory(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0])); @@ -1248,6 +1374,7 @@ static void test_data_cache(void) fmtetc.dwAspect = DVASPECT_ICON; hr = IOleCache_SetData(pOleCache, &fmtetc, &stgmedium, FALSE); ok_ole_success(hr, "IOleCache_SetData"); + ReleaseStgMedium(&stgmedium); hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze); todo_wine { @@ -1268,12 +1395,20 @@ static void test_data_cache(void) 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); - todo_wine { ok_ole_success(hr, "IOleCacheControl_OnRun"); - } hr = IPersistStorage_Save(pPS, pStorage, TRUE); ok_ole_success(hr, "IPersistStorage_Save"); @@ -1289,9 +1424,7 @@ static void test_data_cache(void) IOleCache_Release(pOleCache); IOleCacheControl_Release(pOleCacheControl); - todo_wine { CHECK_NO_EXTRA_METHODS(); - } /* Test with loaded data */ trace("Testing loaded data with CreateDataCache:\n"); @@ -1365,8 +1498,70 @@ static void test_data_cache(void) CHECK_NO_EXTRA_METHODS(); } - IStorage_Release(pStorage); + hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); + ok_ole_success(hr, "CreateDataCache"); + + expected_method_list = methods_cachethenrun; + + hr = IOleCache_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject); + ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)"); + hr = IOleCache_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 = IOleCache_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 = IOleCache_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 = IOleCache_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 = IOleCache_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); + IOleCache_Release(pOleCache); + + CHECK_NO_EXTRA_METHODS(); + + IStorage_Release(pStorage); } static void test_default_handler(void) @@ -1386,10 +1581,25 @@ static void test_default_handler(void) 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); @@ -1449,6 +1659,7 @@ static void test_default_handler(void) 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"); @@ -1517,6 +1728,45 @@ static void test_default_handler(void) 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) @@ -1536,20 +1786,28 @@ static void test_runnable(void) { 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; - ok(OleIsRunning(object), "Object should be running\n"); + ret = OleIsRunning(object); + ok(ret == TRUE, "Object should be running\n"); CHECK_NO_EXTRA_METHODS(); g_isRunning = FALSE; expected_method_list = methods_query_runnable; - ok(OleIsRunning(object) == FALSE, "Object should not be running\n"); + 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; - ok(OleIsRunning(object), "Object without IRunnableObject should be running\n"); + ret = OleIsRunning(object); + ok(ret == TRUE, "Object without IRunnableObject should be running\n"); CHECK_NO_EXTRA_METHODS(); g_isRunning = TRUE; @@ -1585,13 +1843,13 @@ static const IUnknownVtbl UnknownVtbl = Unknown_Release }; -static IUnknown Unknown = { &UnknownVtbl }; +static IUnknown unknown = { &UnknownVtbl }; static void test_OleLockRunning(void) { HRESULT hr; - hr = OleLockRunning((LPUNKNOWN)&Unknown, TRUE, FALSE); + hr = OleLockRunning((LPUNKNOWN)&unknown, TRUE, FALSE); ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr); } @@ -1602,6 +1860,10 @@ START_TEST(ole2) 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); diff --git a/rostests/winetests/ole32/propvariant.c b/rostests/winetests/ole32/propvariant.c index 380dc141652..4d3411747af 100644 --- a/rostests/winetests/ole32/propvariant.c +++ b/rostests/winetests/ole32/propvariant.c @@ -32,7 +32,7 @@ #define PROP_V1A 2 #define PROP_TODO 0x80 -struct valid_mapping +static const struct valid_mapping { BYTE simple; BYTE with_array; diff --git a/rostests/winetests/ole32/stg_prop.c b/rostests/winetests/ole32/stg_prop.c index dff3361bdc6..db4c14246a2 100644 --- a/rostests/winetests/ole32/stg_prop.c +++ b/rostests/winetests/ole32/stg_prop.c @@ -186,7 +186,7 @@ static void testProps(void) spec.ulKind = PRSPEC_PROPID; U(spec).propid = PIDSI_THUMBNAIL; hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var); - ok(SUCCEEDED(hr), "ReadMultiple failed: 0x%08x\n", hr); + ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr); ok(var.vt == VT_CF, "variant type wrong\n"); ok(U(var).pclipdata->ulClipFmt == CF_ENHMETAFILE, "clipboard type wrong\n"); @@ -315,13 +315,18 @@ static void testProps(void) spec.ulKind = PRSPEC_PROPID; U(spec).propid = PID_FIRST_USABLE; + var.vt = VT_I4; U(var).lVal = 1; hr = IPropertyStorage_WriteMultiple(propertyStorage, 1, &spec, &var, 0); ok(hr == S_OK, "WriteMultiple failed: 0x%08x\n", hr); + hr = IPropertyStorage_Commit(propertyStorage, STGC_DEFAULT); + ok(hr == S_OK, "Commit failed: 0x%08x\n", hr); + IPropertyStorage_Release(propertyStorage); IPropertySetStorage_Release(propSetStorage); IStorage_Release(storage); + propertyStorage = NULL; /* now open it again */ hr = StgOpenStorage(filename, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, @@ -338,7 +343,11 @@ static void testProps(void) spec.ulKind = PRSPEC_PROPID; U(spec).propid = PID_FIRST_USABLE; hr = IPropertyStorage_ReadMultiple(propertyStorage, 1, &spec, &var); - ok(hr == S_FALSE, "ReadMultiple failed: 0x%08x\n", hr); + ok(hr == S_OK, "ReadMultiple failed: 0x%08x\n", hr); + + ok(var.vt == VT_I4 && U(var).lVal == 1, + "Didn't get expected type or value for property (got type %d, value %d)\n", + var.vt, U(var).lVal); IPropertyStorage_Release(propertyStorage); IPropertySetStorage_Release(propSetStorage); diff --git a/rostests/winetests/ole32/storage32.c b/rostests/winetests/ole32/storage32.c index 9bd8f339844..bc0cc250d30 100644 --- a/rostests/winetests/ole32/storage32.c +++ b/rostests/winetests/ole32/storage32.c @@ -66,6 +66,9 @@ static void test_hglobal_storage_stat(void) r = CreateILockBytesOnHGlobal( NULL, TRUE, &ilb ); ok( r == S_OK, "CreateILockBytesOnHGlobal failed\n"); + r = StgIsStorageILockBytes( ilb ); + ok( r == S_FALSE, "StgIsStorageILockBytes should have failed\n"); + mode = STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE;/*0x1012*/ r = StgCreateDocfileOnILockBytes( ilb, mode, 0, &stg ); ok( r == S_OK, "StgCreateDocfileOnILockBytes failed\n"); @@ -73,6 +76,9 @@ static void test_hglobal_storage_stat(void) r = WriteClassStg( stg, &test_stg_cls ); ok( r == S_OK, "WriteClassStg failed\n"); + r = StgIsStorageILockBytes( ilb ); + ok( r == S_OK, "StgIsStorageILockBytes failed\n"); + memset( &stat, 0, sizeof stat ); r = IStorage_Stat( stg, &stat, 0 ); @@ -241,6 +247,59 @@ static void test_create_storage_modes(void) ok(DeleteFileA(filenameA), "failed to delete file\n"); } +static void test_stgcreatestorageex(void) +{ + HRESULT (WINAPI *pStgCreateStorageEx)(const WCHAR* pwcsName, DWORD grfMode, DWORD stgfmt, DWORD grfAttrs, STGOPTIONS* pStgOptions, void* reserved, REFIID riid, void** ppObjectOpen); + HMODULE hOle32 = GetModuleHandle("ole32"); + IStorage *stg = NULL; + STGOPTIONS stgoptions = {1, 0, 4096}; + HRESULT r; + + pStgCreateStorageEx = (void *) GetProcAddress(hOle32, "StgCreateStorageEx"); + if (!pStgCreateStorageEx) + { + win_skip("skipping test on NT4\n"); + return; + } + + DeleteFileA(filenameA); + + /* Verify that StgCreateStorageEx can accept an options param */ + r = pStgCreateStorageEx( filename, + STGM_SHARE_EXCLUSIVE | STGM_READWRITE, + STGFMT_DOCFILE, + 0, + &stgoptions, + NULL, + &IID_IStorage, + (void **) &stg); + ok(r==S_OK || r==STG_E_UNIMPLEMENTEDFUNCTION, "StgCreateStorageEx with options failed\n"); + if (r==STG_E_UNIMPLEMENTEDFUNCTION) + { + /* We're on win98 which means all bets are off. Let's get out of here. */ + win_skip("skipping test on win9x\n"); + return; + } + + r = IStorage_Release(stg); + ok(r == 0, "storage not released\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); + + /* Verify that StgCreateStorageEx can accept a NULL pStgOptions */ + r = pStgCreateStorageEx( filename, + STGM_SHARE_EXCLUSIVE | STGM_READWRITE, + STGFMT_STORAGE, + 0, + NULL, + NULL, + &IID_IStorage, + (void **) &stg); + ok(r==S_OK, "StgCreateStorageEx with NULL options failed\n"); + r = IStorage_Release(stg); + ok(r == 0, "storage not released\n"); + ok(DeleteFileA(filenameA), "failed to delete file\n"); +} + static void test_storage_stream(void) { static const WCHAR stmname[] = { 'C','O','N','T','E','N','T','S',0 }; @@ -822,7 +881,7 @@ static void test_storage_refcount(void) STATSTG statstg; r = IStorage_Stat( stg, &statstg, STATFLAG_NONAME ); - ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r); + ok(r == S_OK, "Stat should have succeeded instead of returning 0x%08x\n", r); ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type); ok(U(statstg.cbSize).LowPart == 0, "Statstg cbSize.LowPart should have been 0 instead of %d\n", U(statstg.cbSize).LowPart); ok(U(statstg.cbSize).HighPart == 0, "Statstg cbSize.HighPart should have been 0 instead of %d\n", U(statstg.cbSize).HighPart); @@ -837,7 +896,7 @@ static void test_storage_refcount(void) ok(r == S_OK, "CreateStorage should have succeeded instead of returning 0x%08x\n", r); r = IStorage_Stat( stg2, &statstg, STATFLAG_DEFAULT ); - ok(r == S_OK, "Stat should have succeded instead of returning 0x%08x\n", r); + ok(r == S_OK, "Stat should have succeeded instead of returning 0x%08x\n", r); ok(!memcmp(statstg.pwcsName, stgname, sizeof(stgname)), "Statstg pwcsName should have been the name the storage was created with\n"); ok(statstg.type == STGTY_STORAGE, "Statstg type should have been STGTY_STORAGE instead of %d\n", statstg.type); @@ -955,6 +1014,7 @@ static void test_streamenum(void) CoTaskMemFree(stat.pwcsName); r = IEnumSTATSTG_Release(ee); + ok(r==S_OK, "EnumSTATSTG_Release failed with error 0x%08x\n", r); /* second enum... destroy the stream before reading */ r = IStorage_EnumElements(stg, 0, NULL, 0, &ee); @@ -985,6 +1045,7 @@ static void test_streamenum(void) ok(r==S_OK, "IStorage->CreateStream failed\n"); r = IStream_Release(stm); + ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r); count = 0xf00; r = IEnumSTATSTG_Next(ee, 1, &stat, &count); @@ -1001,6 +1062,7 @@ static void test_streamenum(void) ok(r==S_OK, "IStorage->CreateStream failed\n"); r = IStream_Release(stm); + ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r); count = 0xf00; r = IEnumSTATSTG_Next(ee, 1, &stat, &count); @@ -1018,6 +1080,7 @@ static void test_streamenum(void) ok(r==S_OK, "IStorage->CreateStream failed\n"); r = IStream_Release(stm); + ok(r==S_OK, "Stream_Release failed with error 0x%08x\n", r); r = IEnumSTATSTG_Reset(ee); ok(r==S_OK, "IEnumSTATSTG->Reset failed\n"); @@ -1363,6 +1426,7 @@ static void test_revert(void) ok(r==S_OK, "IStorage->CreateStorage failed, hr=%08x\n", r); r = IStorage_Revert(stg); + ok(r==S_OK, "Storage_Revert failed with error 0x%08x\n", r); /* all open objects become invalid */ r = IStream_Write(stm, "this shouldn't work\n", 20, NULL); @@ -1497,7 +1561,7 @@ static void test_parent_free(void) if (r == S_OK) { r = IStream_Write(stm, "this should fail\n", 17, NULL); - ok(r==STG_E_REVERTED, "IStream->Write sould fail, hr=%x\n", r); + ok(r==STG_E_REVERTED, "IStream->Write should fail, hr=%x\n", r); IStream_Release(stm); @@ -2679,6 +2743,7 @@ static void test_toplevel_stat(void) ok(r==S_OK, "StgCreateDocfile failed\n"); r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r); ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); CoTaskMemFree(stat.pwcsName); @@ -2689,6 +2754,7 @@ static void test_toplevel_stat(void) ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r); r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r); ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); CoTaskMemFree(stat.pwcsName); @@ -2712,6 +2778,7 @@ static void test_toplevel_stat(void) ok(r==S_OK, "StgCreateDocfile failed\n"); r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r); ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); CoTaskMemFree(stat.pwcsName); @@ -2722,6 +2789,7 @@ static void test_toplevel_stat(void) ok(r==S_OK, "StgOpenStorage failed with error 0x%08x\n", r); r = IStorage_Stat( stg, &stat, STATFLAG_DEFAULT ); + ok(r==S_OK, "Storage_Stat failed with error 0x%08x\n", r); ok(!strcmp_ww(stat.pwcsName, filename), "expected %s, got %s\n", wine_dbgstr_w(filename), wine_dbgstr_w(stat.pwcsName)); CoTaskMemFree(stat.pwcsName); @@ -2819,7 +2887,7 @@ static void test_copyto_locking(void) /* Try to copy the storage while the substorage is open */ r = IStorage_CopyTo(stg2, 0, NULL, NULL, stg3); - todo_wine ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r); + ok(r==S_OK, "IStorage->CopyTo failed, hr=%08x\n", r); IStorage_Release(stg4); IStorage_Release(stg3); @@ -2881,6 +2949,52 @@ static void test_copyto_recursive(void) ok( r == TRUE, "deleted file\n"); } +static void test_hglobal_storage_creation(void) +{ + ILockBytes *ilb = NULL; + IStorage *stg = NULL; + HRESULT r; + STATSTG stat; + char junk[512]; + ULARGE_INTEGER offset; + + r = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb); + ok(r == S_OK, "CreateILockBytesOnHGlobal failed, hr=%x\n", r); + + offset.QuadPart = 0; + memset(junk, 0xaa, 512); + r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL); + ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r); + + offset.QuadPart = 2000; + r = ILockBytes_WriteAt(ilb, offset, junk, 512, NULL); + ok(r == S_OK, "ILockBytes_WriteAt failed, hr=%x\n", r); + + r = StgCreateDocfileOnILockBytes(ilb, STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE, 0, &stg); + ok(r == S_OK, "StgCreateDocfileOnILockBytes failed, hr=%x\n", r); + + IStorage_Release(stg); + + r = StgOpenStorageOnILockBytes(ilb, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, + NULL, 0, &stg); + ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r); + + if (SUCCEEDED(r)) + { + r = IStorage_Stat(stg, &stat, STATFLAG_NONAME); + ok(r == S_OK, "StgOpenStorageOnILockBytes failed, hr=%x\n", r); + ok(IsEqualCLSID(&stat.clsid, &GUID_NULL), "unexpected CLSID value\n"); + + IStorage_Release(stg); + } + + r = ILockBytes_Stat(ilb, &stat, STATFLAG_NONAME); + ok(r == S_OK, "ILockBytes_Stat failed, hr=%x\n", r); + ok(stat.cbSize.u.LowPart < 2512, "expected truncated size, got %d\n", stat.cbSize.u.LowPart); + + ILockBytes_Release(ilb); +} + START_TEST(storage32) { CHAR temp[MAX_PATH]; @@ -2896,6 +3010,7 @@ START_TEST(storage32) test_hglobal_storage_stat(); test_create_storage_modes(); + test_stgcreatestorageex(); test_storage_stream(); test_open_storage(); test_storage_suminfo(); @@ -2922,4 +3037,5 @@ START_TEST(storage32) test_substorage_enum(); test_copyto_locking(); test_copyto_recursive(); + test_hglobal_storage_creation(); } diff --git a/rostests/winetests/ole32/usrmarshal.c b/rostests/winetests/ole32/usrmarshal.c index a40e66b2916..ed09558ed9b 100644 --- a/rostests/winetests/ole32/usrmarshal.c +++ b/rostests/winetests/ole32/usrmarshal.c @@ -182,6 +182,7 @@ static void test_marshal_HGLOBAL(void) wirehglobal += sizeof(ULONG); ok(*(ULONG *)wirehglobal == 0, "buffer+4 should be HGLOBAL\n"); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); + hglobal2 = NULL; HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2); ok(hglobal2 == hglobal, "Didn't unmarshal properly\n"); HeapFree(GetProcessHeap(), 0, buffer); @@ -227,6 +228,7 @@ static void test_marshal_HGLOBAL(void) ok(wirehglobal[i] == i, "buffer+0x%x should be %d\n", 0x10 + i, i); init_user_marshal_cb(&umcb, &stub_msg, &rpc_msg, buffer, size, MSHCTX_LOCAL); + hglobal2 = NULL; HGLOBAL_UserUnmarshal(&umcb.Flags, buffer, &hglobal2); ok(hglobal2 != NULL, "Didn't unmarshal properly\n"); HeapFree(GetProcessHeap(), 0, buffer); @@ -578,7 +580,6 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx) ok(size == 0, "size should be 0 bytes, not %d\n", size); buffer = HeapAlloc(GetProcessHeap(), 0, size); buffer_end = WdtpInterfacePointer_UserMarshal(&umcb.Flags, ctx, buffer, unk, &IID_IUnknown); - wireip = buffer; HeapFree(GetProcessHeap(), 0, buffer); /* Now for a non-NULL pointer. The marshalled data are two size DWORDS and then -- 2.17.1