From 82997f0e3b03f7441cb512dcd5d1c0d7bb987d26 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sat, 3 Jun 2017 22:33:48 +0000 Subject: [PATCH 1/1] [OLE32_WINETEST] Sync with Wine Staging 2.9. CORE-13362 svn path=/trunk/; revision=74830 --- rostests/winetests/ole32/clipboard.c | 18 +- rostests/winetests/ole32/compobj.c | 34 +++- rostests/winetests/ole32/ole2.c | 235 ++++++++++++++++++++++++++- 3 files changed, 281 insertions(+), 6 deletions(-) diff --git a/rostests/winetests/ole32/clipboard.c b/rostests/winetests/ole32/clipboard.c index 386f568e26d..ff3b03da0d5 100644 --- a/rostests/winetests/ole32/clipboard.c +++ b/rostests/winetests/ole32/clipboard.c @@ -252,6 +252,10 @@ static HRESULT WINAPI DataObjectImpl_GetData(IDataObject* iface, FORMATETC *pfor DataObjectImpl_GetData_calls++; + ok(pmedium->tymed == 0, "pmedium->tymed = %u\n", pmedium->tymed); + ok(U(*pmedium).hGlobal == NULL, "pmedium->hGlobal = %p\n", U(*pmedium).hGlobal); + ok(pmedium->pUnkForRelease == NULL, "pmedium->pUnkForRelease = %p\n", pmedium->pUnkForRelease); + if(pformatetc->lindex != -1) return DV_E_FORMATETC; @@ -1189,9 +1193,21 @@ static void test_consumer_refs(void) IDataObject_Release(get1); IDataObject_Release(src2); - IDataObject_Release(src); + + /* Show that OleUninitialize() doesn't release the + dataobject's ref, and thus the object is leaked. */ + old_refs = count_refs(src); + ok(old_refs == 1, "%d\n", old_refs); + + OleSetClipboard(src); + refs = count_refs(src); + ok(refs > old_refs, "%d %d\n", refs, old_refs); OleUninitialize(); + refs = count_refs(src); + ok(refs == 2, "%d\n", refs); + + IDataObject_Release(src); } static void test_flushed_getdata(void) diff --git a/rostests/winetests/ole32/compobj.c b/rostests/winetests/ole32/compobj.c index cc230eee344..846abea48af 100644 --- a/rostests/winetests/ole32/compobj.c +++ b/rostests/winetests/ole32/compobj.c @@ -105,6 +105,7 @@ static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, DEFINE_GUID(CLSID_InProcFreeMarshaler, 0x0000033a,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(CLSID_testclsid, 0xacd014c7,0x9535,0x4fac,0x8b,0x53,0xa4,0x8c,0xa7,0xf4,0xd7,0x26); +DEFINE_GUID(CLSID_GlobalOptions, 0x0000034b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); static const WCHAR stdfont[] = {'S','t','d','F','o','n','t',0}; static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0}; @@ -363,11 +364,13 @@ static void test_ProgIDFromCLSID(void) CoTaskMemFree(progid); /* classes without default progid, progid list is not used */ + progid = (void *)0xdeadbeef; hr = ProgIDFromCLSID(&IID_Testiface5, &progid); - ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr); + ok(hr == REGDB_E_CLASSNOTREG && progid == NULL, "got 0x%08x, progid %p\n", hr, progid); + progid = (void *)0xdeadbeef; hr = ProgIDFromCLSID(&IID_Testiface6, &progid); - ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr); + ok(hr == REGDB_E_CLASSNOTREG && progid == NULL, "got 0x%08x, progid %p\n", hr, progid); pDeactivateActCtx(0, cookie); pReleaseActCtx(handle); @@ -3567,6 +3570,32 @@ todo_wine { CoUninitialize(); } +static void test_GlobalOptions(void) +{ + IGlobalOptions *global_options; + HRESULT hres; + + CoInitialize(NULL); + + hres = CoCreateInstance(&CLSID_GlobalOptions, NULL, CLSCTX_INPROC_SERVER, + &IID_IGlobalOptions, (void**)&global_options); + ok(hres == S_OK || broken(hres == E_NOINTERFACE), "CoCreateInstance(CLSID_GlobalOptions) failed: %08x\n", hres); + if(FAILED(hres)) + { + win_skip("CLSID_GlobalOptions not available\n"); + CoUninitialize(); + return; + } + + IGlobalOptions_Release(global_options); + + hres = CoCreateInstance(&CLSID_GlobalOptions, (IUnknown*)0xdeadbeef, CLSCTX_INPROC_SERVER, + &IID_IGlobalOptions, (void**)&global_options); + ok(hres == E_INVALIDARG, "CoCreateInstance(CLSID_GlobalOptions) failed: %08x\n", hres); + + CoUninitialize(); +} + static void init_funcs(void) { HMODULE hOle32 = GetModuleHandleA("ole32"); @@ -3638,4 +3667,5 @@ START_TEST(compobj) test_CoGetCurrentLogicalThreadId(); test_IInitializeSpy(); test_CoGetInstanceFromFile(); + test_GlobalOptions(); } diff --git a/rostests/winetests/ole32/ole2.c b/rostests/winetests/ole32/ole2.c index 0a730f6c573..4173e2687b0 100644 --- a/rostests/winetests/ole32/ole2.c +++ b/rostests/winetests/ole32/ole2.c @@ -1529,6 +1529,39 @@ static const IUnknownVtbl UnknownVtbl = static IUnknown unknown = { &UnknownVtbl }; +static void check_enum_cache(IOleCache2 *cache, 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; @@ -1967,6 +2000,18 @@ static IStorage *create_storage( int num ) 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; @@ -1975,10 +2020,18 @@ static void test_data_cache_dib_contents_stream(int num) 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 ); @@ -1988,6 +2041,8 @@ static void test_data_cache_dib_contents_stream(int num) 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 ); @@ -2001,11 +2056,26 @@ static void test_data_cache_dib_contents_stream(int num) hr = IDataObject_GetData( data, &fmt, &med ); ok( SUCCEEDED(hr), "got %08x\n", hr ); - if (SUCCEEDED(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) { - ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed ); - ReleaseStgMedium( &med ); + 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 ); @@ -2025,12 +2095,170 @@ static void test_data_cache_dib_contents_stream(int num) 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 ); + 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 ); + 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 ); + 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 ); +} + static void test_default_handler(void) { HRESULT hr; @@ -2783,6 +3011,7 @@ START_TEST(ole2) test_data_cache(); test_data_cache_dib_contents_stream( 0 ); test_data_cache_dib_contents_stream( 1 ); + test_data_cache_bitmap(); test_default_handler(); test_runnable(); test_OleRun(); -- 2.17.1