From 902eeb69b2e575cb43ad0d61c29e0d4d33626432 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 7 Jun 2016 10:49:20 +0000 Subject: [PATCH] [OLE32_WINETEST] Sync with Wine Staging 1.9.11. CORE-11368 svn path=/trunk/; revision=71580 --- rostests/winetests/ole32/clipboard.c | 4 +- rostests/winetests/ole32/compobj.c | 542 ++++++++++++++++++++++++--- rostests/winetests/ole32/dragdrop.c | 344 ++++++++++++----- rostests/winetests/ole32/moniker.c | 12 +- rostests/winetests/ole32/ole2.c | 42 ++- rostests/winetests/ole32/stg_prop.c | 168 ++++++--- 6 files changed, 909 insertions(+), 203 deletions(-) diff --git a/rostests/winetests/ole32/clipboard.c b/rostests/winetests/ole32/clipboard.c index f38ca934c2f..167fa99fbd4 100644 --- a/rostests/winetests/ole32/clipboard.c +++ b/rostests/winetests/ole32/clipboard.c @@ -461,7 +461,7 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj) return S_OK; } -static void test_get_clipboard_unitialized(void) +static void test_get_clipboard_uninitialized(void) { HRESULT hr; IDataObject *pDObj; @@ -1609,7 +1609,7 @@ static void test_get_clipboard_locked(void) START_TEST(clipboard) { - test_get_clipboard_unitialized(); + test_get_clipboard_uninitialized(); test_set_clipboard(); test_consumer_refs(); test_flushed_getdata(); diff --git a/rostests/winetests/ole32/compobj.c b/rostests/winetests/ole32/compobj.c index 8cb1570552e..bc640db6dab 100644 --- a/rostests/winetests/ole32/compobj.c +++ b/rostests/winetests/ole32/compobj.c @@ -104,6 +104,7 @@ static const GUID IID_Testiface6 = { 0x72222222, 0x1234, 0x1234, { 0x12, 0x34, 0 static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 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); 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}; @@ -1302,6 +1303,12 @@ static void test_CoGetPSClsid(void) ok(!res, "RegCreateKeyEx returned %d\n", res); res = RegCreateKeyExA(hkey_iface, clsidDeadBeef, 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey, NULL); + if (res == ERROR_ACCESS_DENIED) + { + win_skip("Failed to create a key, skipping some of CoGetPSClsid() tests\n"); + goto cleanup; + } + ok(!res, "RegCreateKeyEx returned %d\n", res); res = RegCreateKeyExA(hkey, "ProxyStubClsid32", 0, NULL, 0, KEY_ALL_ACCESS | opposite, NULL, &hkey_psclsid, NULL); @@ -1319,6 +1326,8 @@ static void test_CoGetPSClsid(void) RegCloseKey(hkey); res = pRegDeleteKeyExA(hkey_iface, clsidDeadBeef, opposite, 0); ok(!res, "RegDeleteKeyEx returned %d\n", res); + + cleanup: RegCloseKey(hkey_iface); } @@ -1775,7 +1784,7 @@ static void test_CoGetObjectContext(void) { HRESULT hr; ULONG refs; - IComThreadingInfo *pComThreadingInfo; + IComThreadingInfo *pComThreadingInfo, *threadinginfo2; IContextCallback *pContextCallback; IObjContext *pObjContext; APTTYPE apttype; @@ -1783,10 +1792,11 @@ static void test_CoGetObjectContext(void) struct info info; HANDLE thread; DWORD tid, exitcode; + GUID id, id2; if (!pCoGetObjectContext) { - skip("CoGetObjectContext not present\n"); + win_skip("CoGetObjectContext not present\n"); return; } @@ -1811,6 +1821,23 @@ static void test_CoGetObjectContext(void) pComThreadingInfo = NULL; hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo); ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + + threadinginfo2 = NULL; + hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&threadinginfo2); + ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + ok(pComThreadingInfo == threadinginfo2, "got different instance\n"); + IComThreadingInfo_Release(threadinginfo2); + + hr = IComThreadingInfo_GetCurrentLogicalThreadId(pComThreadingInfo, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + id = id2 = GUID_NULL; + hr = IComThreadingInfo_GetCurrentLogicalThreadId(pComThreadingInfo, &id); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = CoGetCurrentLogicalThreadId(&id2); + ok(IsEqualGUID(&id, &id2), "got %s, expected %s\n", wine_dbgstr_guid(&id), wine_dbgstr_guid(&id2)); + IComThreadingInfo_Release(pComThreadingInfo); SetEvent(info.stop); @@ -1843,11 +1870,8 @@ static void test_CoGetObjectContext(void) hr = pCoGetObjectContext(&IID_IContextCallback, (void **)&pContextCallback); ok_ole_success(hr, "CoGetObjectContext(ContextCallback)"); - if (hr == S_OK) - { - refs = IContextCallback_Release(pContextCallback); - ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs); - } + refs = IContextCallback_Release(pContextCallback); + ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs); CoUninitialize(); @@ -1870,11 +1894,8 @@ static void test_CoGetObjectContext(void) hr = pCoGetObjectContext(&IID_IContextCallback, (void **)&pContextCallback); ok_ole_success(hr, "CoGetObjectContext(ContextCallback)"); - if (hr == S_OK) - { - refs = IContextCallback_Release(pContextCallback); - ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs); - } + refs = IContextCallback_Release(pContextCallback); + ok(refs == 0, "pContextCallback should have 0 refs instead of %d refs\n", refs); hr = pCoGetObjectContext(&IID_IObjContext, (void **)&pObjContext); ok_ole_success(hr, "CoGetObjectContext"); @@ -1996,7 +2017,7 @@ static void test_CoGetContextToken(void) { HRESULT hr; ULONG refs; - ULONG_PTR token; + ULONG_PTR token, token2; IObjContext *ctx; struct info info; HANDLE thread; @@ -2031,6 +2052,11 @@ static void test_CoGetContextToken(void) hr = pCoGetContextToken(&token); ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + token2 = 0; + hr = pCoGetContextToken(&token2); + ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + ok(token == token2, "got different token\n"); + SetEvent(info.stop); ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); @@ -2052,18 +2078,23 @@ static void test_CoGetContextToken(void) ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); ok(token, "Expected token != 0\n"); + token2 = 0; + hr = pCoGetContextToken(&token2); + ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + ok(token2 == token, "got different token\n"); + refs = IUnknown_AddRef((IUnknown *)token); - todo_wine ok(refs == 1, "Expected 1, got %u\n", refs); + ok(refs == 1, "Expected 1, got %u\n", refs); hr = pCoGetObjectContext(&IID_IObjContext, (void **)&ctx); ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); - todo_wine ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n"); + ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n"); refs = IObjContext_AddRef(ctx); - todo_wine ok(refs == 3, "Expected 3, got %u\n", refs); + ok(refs == 3, "Expected 3, got %u\n", refs); refs = IObjContext_Release(ctx); - todo_wine ok(refs == 2, "Expected 2, got %u\n", refs); + ok(refs == 2, "Expected 2, got %u\n", refs); refs = IUnknown_Release((IUnknown *)token); ok(refs == 1, "Expected 1, got %u\n", refs); @@ -2073,7 +2104,7 @@ static void test_CoGetContextToken(void) hr = pCoGetContextToken(&token); ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); ok(token, "Expected token != 0\n"); - todo_wine ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n"); + ok(ctx == (IObjContext *)token, "Expected interface pointers to be the same\n"); refs = IObjContext_AddRef(ctx); ok(refs == 2, "Expected 1, got %u\n", refs); @@ -2107,12 +2138,11 @@ static void test_TreatAsClass(void) ok (IsEqualGUID(&out,&deadbeef), "expected to get same clsid back\n"); lr = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &clsidkey); - ok(lr == ERROR_SUCCESS, "Couldn't open CLSID key\n"); + ok(!lr, "Couldn't open CLSID key, error %d\n", lr); lr = RegCreateKeyExA(clsidkey, deadbeefA, 0, NULL, 0, KEY_WRITE, NULL, &deadbeefkey, NULL); if (lr) { - win_skip("CoGetTreatAsClass() tests will be skipped (failed to create a test key, error %d)\n", - GetLastError()); + win_skip("CoGetTreatAsClass() tests will be skipped (failed to create a test key, error %d)\n", lr); RegCloseKey(clsidkey); return; } @@ -2197,7 +2227,7 @@ static void test_OleInitialize_InitCounting(void) IUnknown *pUnk; REFCLSID rclsid = &CLSID_InternetZoneManager; - /* 1. OleInitialize fails but OleUnintialize is still called: apartment stays inited */ + /* 1. OleInitialize fails but OleUninitialize is still called: apartment stays initialized */ hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED); ok(hr == S_OK, "CoInitializeEx(COINIT_MULTITHREADED) failed with error 0x%08x\n", hr); @@ -2212,7 +2242,7 @@ static void test_OleInitialize_InitCounting(void) CoUninitialize(); - /* 2. Extra multiple OleUninitialize: apartment stays inited until CoUnitialize */ + /* 2. Extra multiple OleUninitialize: apartment stays initialized until CoUninitialize */ hr = CoInitialize(NULL); ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr); @@ -2373,22 +2403,26 @@ static void test_OleRegGetUserType(void) StringFromGUID2(&CLSID_non_existent, clsidW, sizeof(clsidW)/sizeof(clsidW[0])); ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsidkeyW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &clsidhkey, &disposition); + if (!ret) + { + ret = RegCreateKeyExW(clsidhkey, clsidW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &classkey, NULL); + if (ret) + RegCloseKey(clsidhkey); + } + if (ret == ERROR_ACCESS_DENIED) { - skip("Failed to create test key, skipping some of OleRegGetUserType() tests.\n"); + win_skip("Failed to create test key, skipping some of OleRegGetUserType() tests.\n"); return; } - ok(!ret, "failed to create a key %d, error %d\n", ret, GetLastError()); - - ret = RegCreateKeyExW(clsidhkey, clsidW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &classkey, NULL); - ok(!ret, "failed to create a key %d, error %d\n", ret, GetLastError()); + ok(!ret, "failed to create a key, error %d\n", ret); ret = RegSetValueExW(classkey, NULL, 0, REG_SZ, (const BYTE*)defvalueW, sizeof(defvalueW)); - ok(!ret, "got %d, error %d\n", ret, GetLastError()); + ok(!ret, "got error %d\n", ret); ret = RegCreateKeyExA(classkey, "AuxUserType", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &auxhkey, NULL); - ok(!ret, "got %d, error %d\n", ret, GetLastError()); + ok(!ret, "got error %d\n", ret); /* populate AuxUserType */ for (i = 0; i <= 4; i++) { @@ -2396,10 +2430,10 @@ static void test_OleRegGetUserType(void) sprintf(name, "AuxUserType\\%d", i); ret = RegCreateKeyExA(classkey, name, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL); - ok(!ret, "got %d, error %d\n", ret, GetLastError()); + ok(!ret, "got error %d\n", ret); ret = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE*)auxvalues[i], strlen(auxvalues[i])); - ok(!ret, "got %d, error %d\n", ret, GetLastError()); + ok(!ret, "got error %d\n", ret); RegCloseKey(hkey); } @@ -2902,41 +2936,46 @@ static void test_CoGetApartmentType(void) } hr = pCoGetApartmentType(NULL, NULL); - ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); + ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%08x\n", hr); + type = 0xdeadbeef; hr = pCoGetApartmentType(&type, NULL); - ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); + ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%08x\n", hr); + ok(type == 0xdeadbeef, "Expected 0xdeadbeef, got %u\n", type); + qualifier = 0xdeadbeef; hr = pCoGetApartmentType(NULL, &qualifier); - ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); + ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%08x\n", hr); + ok(qualifier == 0xdeadbeef, "Expected 0xdeadbeef, got %u\n", qualifier); + type = 0xdeadbeef; + qualifier = 0xdeadbeef; hr = pCoGetApartmentType(&type, &qualifier); - ok(hr == CO_E_NOTINITIALIZED, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); + ok(hr == CO_E_NOTINITIALIZED, "CoGetApartmentType succeeded, error: 0x%08x\n", hr); ok(type == APTTYPE_CURRENT, "Expected APTTYPE_CURRENT, got %u\n", type); ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier); + type = 0xdeadbeef; + qualifier = 0xdeadbeef; hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - ok(!hr, "CoInitializeEx failed, error: 0x%08x\n", hr); - + ok(hr == S_OK, "CoInitializeEx failed, error: 0x%08x\n", hr); hr = pCoGetApartmentType(&type, &qualifier); - ok(!hr, "CoGetApartmentType failed, error: 0x%08x\n", hr); + ok(hr == S_OK, "CoGetApartmentType failed, error: 0x%08x\n", hr); ok(type == APTTYPE_MAINSTA, "Expected APTTYPE_MAINSTA, got %u\n", type); ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier); - CoUninitialize(); + type = 0xdeadbeef; + qualifier = 0xdeadbeef; hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED); - ok(!hr, "CoInitializeEx failed, error: 0x%08x\n", hr); - + ok(hr == S_OK, "CoInitializeEx failed, error: 0x%08x\n", hr); hr = pCoGetApartmentType(&type, &qualifier); - ok(!hr, "CoGetApartmentType failed, error: 0x%08x\n", hr); + ok(hr == S_OK, "CoGetApartmentType failed, error: 0x%08x\n", hr); ok(type == APTTYPE_MTA, "Expected APTTYPE_MTA, got %u\n", type); ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier); - CoUninitialize(); } - static HRESULT WINAPI testspy_QI(IMallocSpy *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IMallocSpy) || IsEqualIID(riid, &IID_IUnknown)) @@ -3054,9 +3093,21 @@ static void test_IMallocSpy(void) IMalloc *imalloc; HRESULT hr; + hr = CoRegisterMallocSpy(NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = CoRevokeMallocSpy(); + ok(hr == CO_E_OBJNOTREG, "got 0x%08x\n", hr); + hr = CoRegisterMallocSpy(&testspy); ok(hr == S_OK, "got 0x%08x\n", hr); + hr = CoRegisterMallocSpy(NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = CoRegisterMallocSpy(&testspy); + ok(hr == CO_E_OBJISREG, "got 0x%08x\n", hr); + imalloc = NULL; hr = CoGetMalloc(MEMCTX_TASK, &imalloc); ok(hr == S_OK, "got 0x%08x\n", hr); @@ -3068,6 +3119,404 @@ static void test_IMallocSpy(void) hr = CoRevokeMallocSpy(); ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = CoRevokeMallocSpy(); + ok(hr == CO_E_OBJNOTREG, "got 0x%08x\n", hr); +} + +static void test_CoGetCurrentLogicalThreadId(void) +{ + HRESULT hr; + GUID id; + + hr = CoGetCurrentLogicalThreadId(NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + id = GUID_NULL; + hr = CoGetCurrentLogicalThreadId(&id); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!IsEqualGUID(&id, &GUID_NULL), "got null id\n"); +} + +static HRESULT WINAPI testinitialize_QI(IInitializeSpy *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IInitializeSpy) || IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IInitializeSpy_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI testinitialize_AddRef(IInitializeSpy *iface) +{ + return 2; +} + +static ULONG WINAPI testinitialize_Release(IInitializeSpy *iface) +{ + return 1; +} + +static HRESULT WINAPI testinitialize_PreInitialize(IInitializeSpy *iface, DWORD coinit, DWORD aptrefs) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testinitialize_PostInitialize(IInitializeSpy *iface, HRESULT hr, DWORD coinit, DWORD aptrefs) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testinitialize_PreUninitialize(IInitializeSpy *iface, DWORD aptrefs) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testinitialize_PostUninitialize(IInitializeSpy *iface, DWORD aptrefs) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IInitializeSpyVtbl testinitializevtbl = +{ + testinitialize_QI, + testinitialize_AddRef, + testinitialize_Release, + testinitialize_PreInitialize, + testinitialize_PostInitialize, + testinitialize_PreUninitialize, + testinitialize_PostUninitialize +}; + +static IInitializeSpy testinitialize = { &testinitializevtbl }; + +static void test_IInitializeSpy(void) +{ + ULARGE_INTEGER cookie, cookie1, cookie2; + HRESULT hr; + + hr = CoRegisterInitializeSpy(NULL, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + cookie.QuadPart = 1; + hr = CoRegisterInitializeSpy(NULL, &cookie); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(cookie.QuadPart == 1, "got wrong cookie\n"); + + hr = CoRegisterInitializeSpy(&testinitialize, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + cookie.HighPart = 0; + cookie.LowPart = 1; + hr = CoRegisterInitializeSpy(&testinitialize, &cookie); + ok(hr == S_OK, "got 0x%08x\n", hr); +todo_wine { + ok(cookie.HighPart == GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", cookie.HighPart, + GetCurrentThreadId()); + ok(cookie.LowPart == 0, "got wrong low part 0x%x\n", cookie.LowPart); +} + /* register same instance one more time */ + cookie1.HighPart = 0; + cookie1.LowPart = 0; + hr = CoRegisterInitializeSpy(&testinitialize, &cookie1); +todo_wine { + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(cookie1.HighPart == GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", cookie1.HighPart, + GetCurrentThreadId()); + ok(cookie1.LowPart == 1, "got wrong low part 0x%x\n", cookie1.LowPart); +} + cookie2.HighPart = 0; + cookie2.LowPart = 0; + hr = CoRegisterInitializeSpy(&testinitialize, &cookie2); +todo_wine { + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(cookie2.HighPart == GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", cookie2.HighPart, + GetCurrentThreadId()); + ok(cookie2.LowPart == 2, "got wrong low part 0x%x\n", cookie2.LowPart); +} + hr = CoRevokeInitializeSpy(cookie1); +todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = CoRevokeInitializeSpy(cookie1); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + cookie1.HighPart = 0; + cookie1.LowPart = 0; + hr = CoRegisterInitializeSpy(&testinitialize, &cookie1); +todo_wine { + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(cookie1.HighPart == GetCurrentThreadId(), "got high part 0x%08x, expected 0x%08x\n", cookie1.HighPart, + GetCurrentThreadId()); + ok(cookie1.LowPart == 1, "got wrong low part 0x%x\n", cookie1.LowPart); +} + hr = CoRevokeInitializeSpy(cookie); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = CoRevokeInitializeSpy(cookie1); +todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = CoRevokeInitializeSpy(cookie2); +todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +} + +static HRESULT g_persistfile_qi_ret; +static HRESULT g_persistfile_load_ret; +static HRESULT WINAPI testinstance_QI(IPersistFile *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IUnknown)) { + *obj = iface; + IUnknown_AddRef(iface); + return S_OK; + } + + if (IsEqualIID(riid, &IID_IPersistFile)) { + if (SUCCEEDED(g_persistfile_qi_ret)) { + *obj = iface; + IUnknown_AddRef(iface); + } + else + *obj = NULL; + return g_persistfile_qi_ret; + } + + ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI testinstance_AddRef(IPersistFile *iface) +{ + return 2; +} + +static ULONG WINAPI testinstance_Release(IPersistFile *iface) +{ + return 1; +} + +static HRESULT WINAPI testinstance_GetClassID(IPersistFile *iface, CLSID *clsid) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testinstance_IsDirty(IPersistFile *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testinstance_Load(IPersistFile *iface, LPCOLESTR filename, DWORD mode) +{ + return g_persistfile_load_ret; +} + +static HRESULT WINAPI testinstance_Save(IPersistFile *iface, LPCOLESTR filename, BOOL remember) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI testinstance_SaveCompleted(IPersistFile *iface, LPCOLESTR filename) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testinstance_GetCurFile(IPersistFile *iface, LPOLESTR *filename) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IPersistFileVtbl testpersistfilevtbl = { + testinstance_QI, + testinstance_AddRef, + testinstance_Release, + testinstance_GetClassID, + testinstance_IsDirty, + testinstance_Load, + testinstance_Save, + testinstance_SaveCompleted, + testinstance_GetCurFile +}; + +static IPersistFile testpersistfile = { &testpersistfilevtbl }; + +static HRESULT WINAPI getinstance_cf_QI(IClassFactory *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) { + *obj = iface; + IClassFactory_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI getinstance_cf_AddRef(IClassFactory *iface) +{ + return 2; +} + +static ULONG WINAPI getinstance_cf_Release(IClassFactory *iface) +{ + return 1; +} + +static HRESULT WINAPI getinstance_cf_CreateInstance(IClassFactory *iface, IUnknown *outer, + REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IUnknown)) { + *obj = &testpersistfile; + return S_OK; + } + + ok(0, "unexpected call, riid %s\n", wine_dbgstr_guid(riid)); + *obj = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI getinstance_cf_LockServer(IClassFactory *iface, BOOL lock) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IClassFactoryVtbl getinstance_cf_vtbl = { + getinstance_cf_QI, + getinstance_cf_AddRef, + getinstance_cf_Release, + getinstance_cf_CreateInstance, + getinstance_cf_LockServer +}; + +static IClassFactory getinstance_cf = { &getinstance_cf_vtbl }; + +static void test_CoGetInstanceFromFile(void) +{ + static const WCHAR filenameW[] = {'d','u','m','m','y','p','a','t','h',0}; + CLSID *clsid = (CLSID*)&CLSID_testclsid; + MULTI_QI mqi[2]; + DWORD cookie; + HRESULT hr; + + hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* CLSID is not specified, file does not exist */ + mqi[0].pIID = &IID_IUnknown; + mqi[0].pItf = NULL; + mqi[0].hr = E_NOTIMPL; + hr = CoGetInstanceFromFile(NULL, NULL, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi); +todo_wine + ok(hr == MK_E_CANTOPENFILE, "got 0x%08x\n", hr); + ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf); + ok(mqi[0].hr == E_NOINTERFACE, "got 0x%08x\n", mqi[0].hr); + + /* class is not available */ + mqi[0].pIID = &IID_IUnknown; + mqi[0].pItf = NULL; + mqi[0].hr = E_NOTIMPL; + hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi); + ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr); + ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf); + ok(mqi[0].hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", mqi[0].hr); + + hr = CoRegisterClassObject(clsid, (IUnknown*)&getinstance_cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, + &cookie); + ok(hr == S_OK, "got 0x%08x\n", hr); + + mqi[0].pIID = &IID_IUnknown; + mqi[0].pItf = (void*)0xdeadbeef; + mqi[0].hr = S_OK; + hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi); +todo_wine { + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(mqi[0].pItf == (void*)0xdeadbeef, "got %p\n", mqi[0].pItf); +} + ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr); + + mqi[0].pIID = &IID_IUnknown; + mqi[0].pItf = (void*)0xdeadbeef; + mqi[0].hr = E_NOTIMPL; + hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi); +todo_wine { + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(mqi[0].pItf == (void*)0xdeadbeef, "got %p\n", mqi[0].pItf); + ok(mqi[0].hr == E_NOTIMPL, "got 0x%08x\n", mqi[0].hr); +} + mqi[0].pIID = &IID_IUnknown; + mqi[0].pItf = NULL; + mqi[0].hr = E_NOTIMPL; + hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mqi[0].pItf != NULL, "got %p\n", mqi[0].pItf); + ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr); + + mqi[0].pIID = &IID_IUnknown; + mqi[0].pItf = NULL; + mqi[0].hr = S_OK; + hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mqi[0].pItf != NULL, "got %p\n", mqi[0].pItf); + ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr); + + mqi[0].pIID = &IID_IUnknown; + mqi[0].pItf = NULL; + mqi[0].hr = S_OK; + g_persistfile_qi_ret = S_FALSE; + hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mqi[0].pItf != NULL, "got %p\n", mqi[0].pItf); + ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr); + g_persistfile_qi_ret = S_OK; + + mqi[0].pIID = &IID_IUnknown; + mqi[0].pItf = NULL; + mqi[0].hr = S_OK; + mqi[1].pIID = &IID_IUnknown; + mqi[1].pItf = NULL; + mqi[1].hr = S_OK; + g_persistfile_qi_ret = 0x8000efef; + hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 2, mqi); + ok(hr == 0x8000efef, "got 0x%08x\n", hr); + ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf); + ok(mqi[0].hr == 0x8000efef, "got 0x%08x\n", mqi[0].hr); + ok(mqi[1].pItf == NULL, "got %p\n", mqi[1].pItf); + ok(mqi[1].hr == 0x8000efef, "got 0x%08x\n", mqi[1].hr); + g_persistfile_qi_ret = S_OK; + + mqi[0].pIID = &IID_IUnknown; + mqi[0].pItf = NULL; + mqi[0].hr = S_OK; + mqi[1].pIID = &IID_IUnknown; + mqi[1].pItf = NULL; + mqi[1].hr = S_OK; + g_persistfile_load_ret = 0x8000fefe; + hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 2, mqi); + ok(hr == 0x8000fefe, "got 0x%08x\n", hr); + ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf); + ok(mqi[0].hr == 0x8000fefe, "got 0x%08x\n", mqi[0].hr); + ok(mqi[1].pItf == NULL, "got %p\n", mqi[1].pItf); + ok(mqi[1].hr == 0x8000fefe, "got 0x%08x\n", mqi[1].hr); + g_persistfile_load_ret = S_OK; + + hr = CoRevokeClassObject(cookie); + ok(hr == S_OK, "got 0x%08x\n", hr); + + CoUninitialize(); } static void init_funcs(void) @@ -3138,4 +3587,7 @@ START_TEST(compobj) test_OleRegGetUserType(); test_CoGetApartmentType(); test_IMallocSpy(); + test_CoGetCurrentLogicalThreadId(); + test_IInitializeSpy(); + test_CoGetInstanceFromFile(); } diff --git a/rostests/winetests/ole32/dragdrop.c b/rostests/winetests/ole32/dragdrop.c index b3d712e794f..a2b2dbfe4c1 100644 --- a/rostests/winetests/ole32/dragdrop.c +++ b/rostests/winetests/ole32/dragdrop.c @@ -36,39 +36,233 @@ #include -#define DEFINE_EXPECT(func) \ - static BOOL expect_ ## func = FALSE, called_ ## func = FALSE -#define SET_EXPECT(func) \ - expect_ ## func = TRUE +#define METHOD_LIST \ + METHOD(DO_EnumFormatEtc), \ + METHOD(DO_QueryGetData), \ + METHOD(EnumFMT_Next), \ + METHOD(EnumFMT_Reset), \ + METHOD(EnumFMT_Skip), \ + METHOD(DS_QueryContinueDrag), \ + METHOD(DS_GiveFeedback), \ + METHOD(DT_DragEnter), \ + METHOD(DT_Drop), \ + METHOD(DT_DragLeave), \ + METHOD(DT_DragOver), \ + METHOD(DoDragDrop_effect_in), \ + METHOD(DoDragDrop_ret), \ + METHOD(DoDragDrop_effect_out), \ + METHOD(end_seq) -#define CHECK_EXPECT2(func) \ - do { \ - ok(expect_ ##func, "unexpected call " #func "\n"); \ - called_ ## func = TRUE; \ - }while(0) +#define METHOD(x) x +enum method +{ + METHOD_LIST +}; +#undef METHOD -#define CHECK_EXPECT(func) \ - do { \ - CHECK_EXPECT2(func); \ - expect_ ## func = FALSE; \ - }while(0) +#define METHOD(x) #x +static const char *method_names[] = +{ + METHOD_LIST +}; +#undef METHOD +#undef METHOD_LIST -#define CHECK_CALLED(func) \ - do { \ - ok(called_ ## func, "expected " #func "\n"); \ - expect_ ## func = called_ ## func = FALSE; \ - }while(0) +struct method_call +{ + enum method method; + DWORD expect_param; -DEFINE_EXPECT(DataObject_EnumFormatEtc); -DEFINE_EXPECT(EnumFORMATETC_Next); -DEFINE_EXPECT(EnumFORMATETC_Reset); -DEFINE_EXPECT(DataObject_QueryGetData); -DEFINE_EXPECT(DropSource_QueryContinueDrag); -DEFINE_EXPECT(DropTarget_DragEnter); -DEFINE_EXPECT(DropSource_GiveFeedback); -DEFINE_EXPECT(DropTarget_Drop); -DEFINE_EXPECT(DropTarget_DragLeave); + HRESULT set_ret; + DWORD set_param; + + int called_todo : 1; +}; + +const struct method_call *call_ptr; + +static HRESULT check_expect_(enum method func, DWORD expect_param, DWORD *set_param, const char *file, int line ) +{ + HRESULT hr; + + do + { + todo_wine_if(call_ptr->called_todo) + ok_( file, line )( func == call_ptr->method, "unexpected call %s instead of %s\n", + method_names[func], method_names[call_ptr->method] ); + if (call_ptr->method == func) break; + } while ((++call_ptr)->method != end_seq); + + ok_( file, line )( expect_param == call_ptr->expect_param, "%s: unexpected param %08x expected %08x\n", + method_names[func], expect_param, call_ptr->expect_param ); + if (set_param) *set_param = call_ptr->set_param; + hr = call_ptr->set_ret; + if (call_ptr->method != end_seq) call_ptr++; + return hr; +} + +#define check_expect(func, expect_param, set_param) \ + check_expect_((func), (expect_param), (set_param), __FILE__, __LINE__) + + +struct method_call call_lists[][30] = +{ + { /* First QueryContinueDrag rets DRAGDROP_S_DROP */ + { DoDragDrop_effect_in, 0, 0, DROPEFFECT_COPY, 0 }, + { DO_EnumFormatEtc, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { EnumFMT_Reset, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { DO_QueryGetData, 0, S_OK, 0, 1 }, + + { DS_QueryContinueDrag, 0, DRAGDROP_S_DROP, 0, 0 }, + { DT_DragEnter, DROPEFFECT_COPY, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + { DT_Drop, DROPEFFECT_COPY, 0xbeefbeef, DROPEFFECT_COPY, 0 }, + + { DoDragDrop_ret, 0xbeefbeef, 0, 0, 0, }, + { DoDragDrop_effect_out, DROPEFFECT_COPY, 0, 0, 0 }, + { end_seq, 0, 0, 0, 0 } + }, + { /* As above, but initial effects == 0 */ + { DoDragDrop_effect_in, 0, 0, 0, 0 }, + { DO_EnumFormatEtc, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { EnumFMT_Reset, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { DO_QueryGetData, 0, S_OK, 0, 1 }, + + { DS_QueryContinueDrag, 0, DRAGDROP_S_DROP, 0, 0 }, + { DT_DragEnter, 0, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, 0, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + { DT_DragLeave, 0, 0, 0, 0 }, + + { DoDragDrop_ret, DRAGDROP_S_DROP, 0, 0, 0 }, + { DoDragDrop_effect_out, 0, 0, 0, 0 }, + { end_seq, 0, 0, 0, 0 } + }, + { /* Multiple initial effects */ + { DoDragDrop_effect_in, 0, 0, DROPEFFECT_COPY | DROPEFFECT_MOVE, 0 }, + { DO_EnumFormatEtc, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { EnumFMT_Reset, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { DO_QueryGetData, 0, S_OK, 0, 1 }, + + { DS_QueryContinueDrag, 0, DRAGDROP_S_DROP, 0, 0 }, + { DT_DragEnter, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + { DT_Drop, DROPEFFECT_COPY | DROPEFFECT_MOVE, 0, 0, 0 }, + + { DoDragDrop_ret, DRAGDROP_S_DROP, 0, 0, 0 }, + { DoDragDrop_effect_out, 0, 0, 0, 0 }, + { end_seq, 0, 0, 0, 0 } + }, + { /* First couple of QueryContinueDrag return S_OK followed by a drop */ + { DoDragDrop_effect_in, 0, 0, DROPEFFECT_COPY | DROPEFFECT_MOVE, 0 }, + { DO_EnumFormatEtc, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { EnumFMT_Reset, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { DO_QueryGetData, 0, S_OK, 0, 1 }, + + { DS_QueryContinueDrag, 0, S_OK, 0, 0 }, + { DT_DragEnter, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + { DT_DragOver, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + + { DS_QueryContinueDrag, 0, S_OK, 0, 0 }, + { DT_DragOver, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + + { DS_QueryContinueDrag, 0, DRAGDROP_S_DROP, 0, 0 }, + { DT_Drop, DROPEFFECT_COPY | DROPEFFECT_MOVE, 0, 0, 0 }, + + { DoDragDrop_ret, DRAGDROP_S_DROP, 0, 0, 0 }, + { DoDragDrop_effect_out, 0, 0, 0, 0 }, + { end_seq, 0, 0, 0, 0 } + }, + { /* First QueryContinueDrag cancels */ + { DoDragDrop_effect_in, 0, 0, DROPEFFECT_COPY | DROPEFFECT_MOVE, 0 }, + { DO_EnumFormatEtc, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { EnumFMT_Reset, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { DO_QueryGetData, 0, S_OK, 0, 1 }, + + { DS_QueryContinueDrag, 0, DRAGDROP_S_CANCEL, 0, 0 }, + + { DoDragDrop_ret, DRAGDROP_S_CANCEL, 0, 0, 0 }, + { DoDragDrop_effect_out, 0, 0, 0, 0 }, + { end_seq, 0, 0, 0, 0 } + }, + { /* First couple of QueryContinueDrag return S_OK followed by a cancel */ + { DoDragDrop_effect_in, 0, 0, DROPEFFECT_COPY | DROPEFFECT_MOVE, 0 }, + { DO_EnumFormatEtc, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { EnumFMT_Reset, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { DO_QueryGetData, 0, S_OK, 0, 1 }, + + { DS_QueryContinueDrag, 0, S_OK, 0, 0 }, + { DT_DragEnter, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + { DT_DragOver, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + + { DS_QueryContinueDrag, 0, S_OK, 0, 0 }, + { DT_DragOver, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + + { DS_QueryContinueDrag, 0, DRAGDROP_S_CANCEL, 0, 0 }, + { DT_DragLeave, 0, 0, 0, 0 }, + + { DoDragDrop_ret, DRAGDROP_S_CANCEL, 0, 0, 0 }, + { DoDragDrop_effect_out, 0, 0, 0, 0 }, + { end_seq, 0, 0, 0, 0 } + }, + { /* First couple of QueryContinueDrag return S_OK followed by a E_FAIL */ + { DoDragDrop_effect_in, 0, 0, DROPEFFECT_COPY | DROPEFFECT_MOVE, 0 }, + { DO_EnumFormatEtc, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { EnumFMT_Reset, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_OK, 0, 1 }, + { EnumFMT_Next, 0, S_FALSE, 0, 1 }, + { DO_QueryGetData, 0, S_OK, 0, 1 }, + + { DS_QueryContinueDrag, 0, S_OK, 0, 0 }, + { DT_DragEnter, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + { DT_DragOver, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + + { DS_QueryContinueDrag, 0, S_OK, 0, 0 }, + { DT_DragOver, DROPEFFECT_COPY | DROPEFFECT_MOVE, S_OK, DROPEFFECT_COPY, 0 }, + { DS_GiveFeedback, DROPEFFECT_COPY, DRAGDROP_S_USEDEFAULTCURSORS, 0, 0 }, + + { DS_QueryContinueDrag, 0, E_FAIL, 0, 0 }, + { DT_DragLeave, 0, 0, 0, 0 }, + + { DoDragDrop_ret, E_FAIL, 0, 0, 0 }, + { DoDragDrop_effect_out, 0, 0, 0, 0 }, + { end_seq, 0, 0, 0, 0 } + }, +}; static int droptarget_refs; @@ -107,9 +301,7 @@ static HRESULT WINAPI DropTarget_DragEnter(IDropTarget* iface, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) { - CHECK_EXPECT(DropTarget_DragEnter); - *pdwEffect = DROPEFFECT_COPY; - return S_OK; + return check_expect(DT_DragEnter, *pdwEffect, pdwEffect); } static HRESULT WINAPI DropTarget_DragOver(IDropTarget* iface, @@ -117,23 +309,19 @@ static HRESULT WINAPI DropTarget_DragOver(IDropTarget* iface, POINTL pt, DWORD* pdwEffect) { - ok(0, "unexpected call\n"); - *pdwEffect = DROPEFFECT_COPY; - return S_OK; + return check_expect(DT_DragOver, *pdwEffect, pdwEffect); } static HRESULT WINAPI DropTarget_DragLeave(IDropTarget* iface) { - CHECK_EXPECT(DropTarget_DragLeave); - return E_NOTIMPL; + return check_expect(DT_DragLeave, 0, NULL); } static HRESULT WINAPI DropTarget_Drop(IDropTarget* iface, IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) { - CHECK_EXPECT(DropTarget_Drop); - return 0xbeefbeef; + return check_expect(DT_Drop, *pdwEffect, pdwEffect); } static const IDropTargetVtbl DropTarget_VTbl = @@ -176,16 +364,14 @@ static HRESULT WINAPI DropSource_QueryContinueDrag( BOOL fEscapePressed, DWORD grfKeyState) { - CHECK_EXPECT(DropSource_QueryContinueDrag); - return DRAGDROP_S_DROP; + return check_expect(DS_QueryContinueDrag, 0, NULL); } static HRESULT WINAPI DropSource_GiveFeedback( IDropSource *iface, DWORD dwEffect) { - CHECK_EXPECT(DropSource_GiveFeedback); - return DRAGDROP_S_USEDEFAULTCURSORS; + return check_expect(DS_GiveFeedback, dwEffect, NULL); } static const IDropSourceVtbl dropsource_vtbl = { @@ -215,37 +401,28 @@ static ULONG WINAPI EnumFORMATETC_Release(IEnumFORMATETC *iface) return 1; } -static BOOL formats_enumerated; static HRESULT WINAPI EnumFORMATETC_Next(IEnumFORMATETC *iface, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) { static FORMATETC format = { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - - CHECK_EXPECT2(EnumFORMATETC_Next); + HRESULT hr = check_expect(EnumFMT_Next, 0, NULL); ok(celt == 1, "celt = %d\n", celt); ok(rgelt != NULL, "rgelt == NULL\n"); ok(pceltFetched == NULL, "pceltFetched != NULL\n"); - if(formats_enumerated) - return S_FALSE; - *rgelt = format; - formats_enumerated = TRUE; - return S_OK; + return hr; } static HRESULT WINAPI EnumFORMATETC_Skip(IEnumFORMATETC *iface, ULONG celt) { - ok(0, "unexpected call\n"); - return E_NOTIMPL; + return check_expect(EnumFMT_Skip, 0, NULL); } static HRESULT WINAPI EnumFORMATETC_Reset(IEnumFORMATETC *iface) { - CHECK_EXPECT(EnumFORMATETC_Reset); - formats_enumerated = FALSE; - return S_OK; + return check_expect(EnumFMT_Reset, 0, NULL); } static HRESULT WINAPI EnumFORMATETC_Clone(IEnumFORMATETC *iface, @@ -316,8 +493,7 @@ static HRESULT WINAPI DataObject_QueryGetData( IDataObject *iface, FORMATETC *pformatetc) { - CHECK_EXPECT(DataObject_QueryGetData); - return S_OK; + return check_expect(DO_QueryGetData, 0, NULL); } static HRESULT WINAPI DataObject_GetCanonicalFormatEtc( @@ -344,10 +520,9 @@ static HRESULT WINAPI DataObject_EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc) { - CHECK_EXPECT(DataObject_EnumFormatEtc); + HRESULT hr = check_expect(DO_EnumFormatEtc, 0, NULL); *ppenumFormatEtc = &EnumFORMATETC; - formats_enumerated = FALSE; - return S_OK; + return hr; } static HRESULT WINAPI DataObject_DAdvise( @@ -492,6 +667,7 @@ static void test_DoDragDrop(void) HRESULT hr; HWND hwnd; RECT rect; + int seq; hwnd = CreateWindowExA(WS_EX_TOPMOST, "WineOleTestClass", "Test", 0, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, @@ -529,43 +705,19 @@ static void test_DoDragDrop(void) ShowWindow(hwnd, SW_SHOW); GetWindowRect(hwnd, &rect); ok(SetCursorPos(rect.left+50, rect.top+50), "SetCursorPos failed\n"); - SET_EXPECT(DataObject_EnumFormatEtc); - SET_EXPECT(EnumFORMATETC_Next); - SET_EXPECT(EnumFORMATETC_Reset); - SET_EXPECT(DataObject_QueryGetData); - SET_EXPECT(DropSource_QueryContinueDrag); - SET_EXPECT(DropTarget_DragEnter); - SET_EXPECT(DropSource_GiveFeedback); - SET_EXPECT(DropTarget_Drop); - hr = DoDragDrop(&DataObject, &DropSource, DROPEFFECT_COPY, &effect); - ok(hr == 0xbeefbeef, "got 0x%08x\n", hr); - todo_wine CHECK_CALLED(DataObject_EnumFormatEtc); - todo_wine CHECK_CALLED(EnumFORMATETC_Next); - todo_wine CHECK_CALLED(EnumFORMATETC_Reset); - todo_wine CHECK_CALLED(DataObject_QueryGetData); - CHECK_CALLED(DropSource_QueryContinueDrag); - CHECK_CALLED(DropTarget_DragEnter); - CHECK_CALLED(DropSource_GiveFeedback); - CHECK_CALLED(DropTarget_Drop); - SET_EXPECT(DataObject_EnumFormatEtc); - SET_EXPECT(EnumFORMATETC_Next); - SET_EXPECT(EnumFORMATETC_Reset); - SET_EXPECT(DataObject_QueryGetData); - SET_EXPECT(DropSource_QueryContinueDrag); - SET_EXPECT(DropTarget_DragEnter); - SET_EXPECT(DropSource_GiveFeedback); - SET_EXPECT(DropTarget_DragLeave); - hr = DoDragDrop(&DataObject, &DropSource, 0, &effect); - ok(hr == DRAGDROP_S_DROP, "got 0x%08x\n", hr); - todo_wine CHECK_CALLED(DataObject_EnumFormatEtc); - todo_wine CHECK_CALLED(EnumFORMATETC_Next); - todo_wine CHECK_CALLED(EnumFORMATETC_Reset); - todo_wine CHECK_CALLED(DataObject_QueryGetData); - CHECK_CALLED(DropSource_QueryContinueDrag); - CHECK_CALLED(DropTarget_DragEnter); - CHECK_CALLED(DropSource_GiveFeedback); - CHECK_CALLED(DropTarget_DragLeave); + for (seq = 0; seq < sizeof(call_lists) / sizeof(call_lists[0]); seq++) + { + DWORD effect_in; + trace("%d\n", seq); + call_ptr = call_lists[seq]; + effect_in = call_ptr->set_param; + call_ptr++; + + hr = DoDragDrop(&DataObject, &DropSource, effect_in, &effect); + check_expect(DoDragDrop_ret, hr, NULL); + check_expect(DoDragDrop_effect_out, effect, NULL); + } OleUninitialize(); diff --git a/rostests/winetests/ole32/moniker.c b/rostests/winetests/ole32/moniker.c index 7d0055b4403..464ba62dc10 100644 --- a/rostests/winetests/ole32/moniker.c +++ b/rostests/winetests/ole32/moniker.c @@ -1586,11 +1586,11 @@ static void test_item_moniker(void) IBindCtx *bindctx; IMoniker *inverse; IUnknown *unknown; - static const WCHAR wszDelimeter[] = {'!',0}; + static const WCHAR wszDelimiter[] = {'!',0}; static const WCHAR wszObjectName[] = {'T','e','s','t',0}; static const WCHAR expected_display_name[] = { '!','T','e','s','t',0 }; - hr = CreateItemMoniker(wszDelimeter, wszObjectName, &moniker); + hr = CreateItemMoniker(wszDelimiter, wszObjectName, &moniker); ok_ole_success(hr, CreateItemMoniker); test_moniker("item moniker", moniker, @@ -1715,15 +1715,15 @@ static void test_generic_composite_moniker(void) FILETIME filetime; IMoniker *inverse; IUnknown *unknown; - static const WCHAR wszDelimeter1[] = {'!',0}; + static const WCHAR wszDelimiter1[] = {'!',0}; static const WCHAR wszObjectName1[] = {'T','e','s','t',0}; - static const WCHAR wszDelimeter2[] = {'#',0}; + static const WCHAR wszDelimiter2[] = {'#',0}; static const WCHAR wszObjectName2[] = {'W','i','n','e',0}; static const WCHAR expected_display_name[] = { '!','T','e','s','t','#','W','i','n','e',0 }; - hr = CreateItemMoniker(wszDelimeter1, wszObjectName1, &moniker1); + hr = CreateItemMoniker(wszDelimiter1, wszObjectName1, &moniker1); ok_ole_success(hr, CreateItemMoniker); - hr = CreateItemMoniker(wszDelimeter2, wszObjectName2, &moniker2); + hr = CreateItemMoniker(wszDelimiter2, wszObjectName2, &moniker2); ok_ole_success(hr, CreateItemMoniker); hr = CreateGenericComposite(moniker1, moniker2, &moniker); ok_ole_success(hr, CreateGenericComposite); diff --git a/rostests/winetests/ole32/ole2.c b/rostests/winetests/ole32/ole2.c index 7753946b7dd..0a730f6c573 100644 --- a/rostests/winetests/ole32/ole2.c +++ b/rostests/winetests/ole32/ole2.c @@ -39,6 +39,11 @@ #include +#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 ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) #define DEFINE_EXPECT(func) \ @@ -158,12 +163,7 @@ typedef struct PresentationDataHeader while (expected_method_list->flags & TEST_OPTIONAL && \ strcmp(expected_method_list->method, method_name) != 0) \ expected_method_list++; \ - 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 \ + 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); \ @@ -1512,13 +1512,11 @@ static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void static ULONG WINAPI Unknown_AddRef(IUnknown *iface) { - ok(0, "unexpected AddRef\n"); return 2; } static ULONG WINAPI Unknown_Release(IUnknown *iface) { - ok(0, "unexpected Release\n"); return 1; } @@ -1535,7 +1533,9 @@ static void test_data_cache(void) { HRESULT hr; IOleCache2 *pOleCache; + IOleCache *olecache; IStorage *pStorage; + IUnknown *unk; IPersistStorage *pPS; IViewObject *pViewObject; IOleCacheControl *pOleCacheControl; @@ -1605,12 +1605,34 @@ static void test_data_cache(void) /* requested is not IUnknown */ hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IOleCache2, (void**)&pOleCache); -todo_wine ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); - hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IUnknown, (void**)&pOleCache); + 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); +todo_wine { + 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); /* Test with new data */ diff --git a/rostests/winetests/ole32/stg_prop.c b/rostests/winetests/ole32/stg_prop.c index ba323fe5164..318159d9ac4 100644 --- a/rostests/winetests/ole32/stg_prop.c +++ b/rostests/winetests/ole32/stg_prop.c @@ -42,6 +42,8 @@ DEFINE_GUID(FMTID_UserDefinedProperties,0xD5CDD505,0x2E9C,0x101B,0x93,0x97,0x08, static HRESULT (WINAPI *pFmtIdToPropStgName)(const FMTID *, LPOLESTR); static HRESULT (WINAPI *pPropStgNameToFmtId)(const LPOLESTR, FMTID *); static HRESULT (WINAPI *pStgCreatePropSetStg)(IStorage *, DWORD, IPropertySetStorage **); +static HRESULT (WINAPI *pStgCreatePropStg)(IUnknown *, REFFMTID, const CLSID *, DWORD, DWORD, IPropertyStorage **); +static HRESULT (WINAPI *pStgOpenPropStg)(IUnknown *, REFFMTID, DWORD, DWORD, IPropertyStorage **); static void init_function_pointers(void) { @@ -49,20 +51,25 @@ static void init_function_pointers(void) pFmtIdToPropStgName = (void*)GetProcAddress(hmod, "FmtIdToPropStgName"); pPropStgNameToFmtId = (void*)GetProcAddress(hmod, "PropStgNameToFmtId"); pStgCreatePropSetStg = (void*)GetProcAddress(hmod, "StgCreatePropSetStg"); + pStgCreatePropStg = (void*)GetProcAddress(hmod, "StgCreatePropStg"); + pStgOpenPropStg = (void*)GetProcAddress(hmod, "StgOpenPropStg"); } + /* FIXME: this creates an ANSI storage, try to find conditions under which * Unicode translation fails */ -static void testProps(void) +static void testPropsHelper(IPropertySetStorage **propSetStorage) { static const WCHAR szDot[] = { '.',0 }; static const WCHAR szPrefix[] = { 's','t','g',0 }; + static const WCHAR szSummaryInfo[] = { 5,'S','u','m','m','a','r','y', + 'I','n','f','o','r','m','a','t','i','o','n',0 }; static WCHAR propName[] = { 'p','r','o','p',0 }; static char val[] = "l33t auth0r"; WCHAR filename[MAX_PATH]; HRESULT hr; IStorage *storage = NULL; - IPropertySetStorage *propSetStorage = NULL; + IStream *stream = NULL; IPropertyStorage *propertyStorage = NULL; PROPSPEC spec; PROPVARIANT var; @@ -71,6 +78,11 @@ static void testProps(void) GUID anyOldGuid = { 0x12345678,0xdead,0xbeef, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 } }; + if(propSetStorage) + trace("Testing property storage with a set...\n"); + else + trace("Testing property storage without a set...\n"); + if(!GetTempFileNameW(szDot, szPrefix, 0, filename)) return; @@ -80,20 +92,40 @@ static void testProps(void) STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &storage); ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); - if(!pStgCreatePropSetStg) + if(propSetStorage) { - IStorage_Release(storage); - DeleteFileW(filename); - return; - } - hr = pStgCreatePropSetStg(storage, 0, &propSetStorage); - ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr); + if(!pStgCreatePropSetStg) + { + IStorage_Release(storage); + DeleteFileW(filename); + return; + } + hr = pStgCreatePropSetStg(storage, 0, propSetStorage); + ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr); - hr = IPropertySetStorage_Create(propSetStorage, - &FMTID_SummaryInformation, NULL, PROPSETFLAG_ANSI, - STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, - &propertyStorage); - ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr); + hr = IPropertySetStorage_Create(*propSetStorage, + &FMTID_SummaryInformation, NULL, PROPSETFLAG_ANSI, + STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, + &propertyStorage); + ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr); + } + else + { + hr = IStorage_CreateStream(storage, szSummaryInfo, + STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stream); + ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr); + + if(!pStgCreatePropStg) + { + IStorage_Release(storage); + IUnknown_Release(stream); + DeleteFileW(filename); + return; + } + hr = pStgCreatePropStg((IUnknown *)stream, &FMTID_SummaryInformation, + NULL, PROPSETFLAG_ANSI, 0, &propertyStorage); + ok(hr == S_OK, "StgCreatePropStg failed: 0x%08x\n", hr); + } hr = IPropertyStorage_WriteMultiple(propertyStorage, 0, NULL, NULL, 0); ok(hr == S_OK, "WriteMultiple with 0 args failed: 0x%08x\n", hr); @@ -261,23 +293,41 @@ static void testProps(void) */ IPropertyStorage_Release(propertyStorage); - propertyStorage = NULL; - IPropertySetStorage_Release(propSetStorage); - propSetStorage = NULL; + if(propSetStorage) IPropertySetStorage_Release(*propSetStorage); IStorage_Release(storage); - storage = NULL; + if(stream) IUnknown_Release(stream); /* now open it again */ hr = StgOpenStorage(filename, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &storage); ok(hr == S_OK, "StgOpenStorage failed: 0x%08x\n", hr); - hr = pStgCreatePropSetStg(storage, 0, &propSetStorage); - ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr); + if(propSetStorage) + { + hr = pStgCreatePropSetStg(storage, 0, propSetStorage); + ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr); - hr = IPropertySetStorage_Open(propSetStorage, &FMTID_SummaryInformation, - STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &propertyStorage); - ok(hr == S_OK, "IPropertySetStorage_Open failed: 0x%08x\n", hr); + hr = IPropertySetStorage_Open(*propSetStorage, &FMTID_SummaryInformation, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &propertyStorage); + ok(hr == S_OK, "IPropertySetStorage_Open failed: 0x%08x\n", hr); + } + else + { + hr = IStorage_OpenStream(storage, szSummaryInfo, + 0, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stream); + ok(hr == S_OK, "IStorage_OpenStream failed: 0x%08x\n", hr); + + if(!pStgOpenPropStg) + { + IStorage_Release(storage); + IUnknown_Release(stream); + DeleteFileW(filename); + return; + } + hr = pStgOpenPropStg((IUnknown *)stream, &FMTID_SummaryInformation, + PROPSETFLAG_DEFAULT, 0, &propertyStorage); + ok(hr == S_OK, "StgOpenPropStg failed: 0x%08x\n", hr); + } /* check properties again */ spec.ulKind = PRSPEC_LPWSTR; @@ -297,8 +347,9 @@ static void testProps(void) PropVariantClear(&var); IPropertyStorage_Release(propertyStorage); - IPropertySetStorage_Release(propSetStorage); + if(propSetStorage) IPropertySetStorage_Release(*propSetStorage); IStorage_Release(storage); + if(stream) IUnknown_Release(stream); DeleteFileW(filename); @@ -307,20 +358,27 @@ static void testProps(void) STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, &storage); ok(hr == S_OK, "StgCreateDocfile failed: 0x%08x\n", hr); - if(!pStgCreatePropSetStg) + if(propSetStorage) { - IStorage_Release(storage); - DeleteFileW(filename); - return; - } - hr = pStgCreatePropSetStg(storage, 0, &propSetStorage); - ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr); + hr = pStgCreatePropSetStg(storage, 0, propSetStorage); + ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr); - hr = IPropertySetStorage_Create(propSetStorage, - &anyOldGuid, NULL, PROPSETFLAG_ANSI, - STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, - &propertyStorage); - ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr); + hr = IPropertySetStorage_Create(*propSetStorage, + &anyOldGuid, NULL, PROPSETFLAG_ANSI, + STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, + &propertyStorage); + ok(hr == S_OK, "IPropertySetStorage_Create failed: 0x%08x\n", hr); + } + else + { + hr = IStorage_CreateStream(storage, szSummaryInfo, + STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stream); + ok(hr == S_OK, "IStorage_CreateStream failed: 0x%08x\n", hr); + + hr = pStgCreatePropStg((IUnknown *)stream, &anyOldGuid, NULL, + PROPSETFLAG_DEFAULT, 0, &propertyStorage); + ok(hr == S_OK, "StgCreatePropStg failed: 0x%08x\n", hr); + } spec.ulKind = PRSPEC_PROPID; U(spec).propid = PID_FIRST_USABLE; @@ -333,21 +391,34 @@ static void testProps(void) ok(hr == S_OK, "Commit failed: 0x%08x\n", hr); IPropertyStorage_Release(propertyStorage); - IPropertySetStorage_Release(propSetStorage); + if(propSetStorage) IPropertySetStorage_Release(*propSetStorage); IStorage_Release(storage); - propertyStorage = NULL; + if(stream) IUnknown_Release(stream); /* now open it again */ hr = StgOpenStorage(filename, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &storage); ok(hr == S_OK, "StgOpenStorage failed: 0x%08x\n", hr); - hr = pStgCreatePropSetStg(storage, 0, &propSetStorage); - ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr); + if(propSetStorage) + { + hr = pStgCreatePropSetStg(storage, 0, propSetStorage); + ok(hr == S_OK, "StgCreatePropSetStg failed: 0x%08x\n", hr); - hr = IPropertySetStorage_Open(propSetStorage, &anyOldGuid, - STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &propertyStorage); - ok(hr == S_OK, "IPropertySetStorage_Open failed: 0x%08x\n", hr); + hr = IPropertySetStorage_Open(*propSetStorage, &anyOldGuid, + STGM_READWRITE | STGM_SHARE_EXCLUSIVE, &propertyStorage); + ok(hr == S_OK, "IPropertySetStorage_Open failed: 0x%08x\n", hr); + } + else + { + hr = IStorage_OpenStream(storage, szSummaryInfo, + 0, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stream); + ok(hr == S_OK, "IStorage_OpenStream failed: 0x%08x\n", hr); + + hr = pStgOpenPropStg((IUnknown *)stream, &anyOldGuid, + PROPSETFLAG_DEFAULT, 0, &propertyStorage); + ok(hr == S_OK, "StgOpenPropStg failed: 0x%08x\n", hr); + } spec.ulKind = PRSPEC_PROPID; U(spec).propid = PID_FIRST_USABLE; @@ -359,12 +430,21 @@ static void testProps(void) var.vt, U(var).lVal); IPropertyStorage_Release(propertyStorage); - IPropertySetStorage_Release(propSetStorage); + if(propSetStorage) IPropertySetStorage_Release(*propSetStorage); IStorage_Release(storage); + if(stream) IUnknown_Release(stream); DeleteFileW(filename); } +static void testProps(void) +{ + IPropertySetStorage *propSetStorage = NULL; + + testPropsHelper(&propSetStorage); + testPropsHelper(NULL); +} + static void testCodepage(void) { static const WCHAR szDot[] = { '.',0 };