Author: akhaldi Date: Fri Mar 4 09:30:16 2016 New Revision: 70902
URL: http://svn.reactos.org/svn/reactos?rev=70902&view=rev Log: [OLE32_WINETEST] Sync with Wine Staging 1.9.4. CORE-10912
Modified: trunk/rostests/winetests/ole32/clipboard.c trunk/rostests/winetests/ole32/compobj.c trunk/rostests/winetests/ole32/hglobalstream.c trunk/rostests/winetests/ole32/ole2.c trunk/rostests/winetests/ole32/propvariant.c trunk/rostests/winetests/ole32/storage32.c
Modified: trunk/rostests/winetests/ole32/clipboard.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/clipboard.... ============================================================================== --- trunk/rostests/winetests/ole32/clipboard.c [iso-8859-1] (original) +++ trunk/rostests/winetests/ole32/clipboard.c [iso-8859-1] Fri Mar 4 09:30:16 2016 @@ -459,6 +459,17 @@
*lplpdataobj = (LPDATAOBJECT)obj; return S_OK; +} + +static void test_get_clipboard_unitialized(void) +{ + HRESULT hr; + IDataObject *pDObj; + + pDObj = (IDataObject *)0xdeadbeef; + hr = OleGetClipboard(&pDObj); + todo_wine ok(hr == S_OK, "OleGetClipboard() got 0x%08x instead of 0x%08x\n", hr, S_OK); + if (pDObj && pDObj != (IDataObject *)0xdeadbeef) IDataObject_Release(pDObj); }
static void test_get_clipboard(void) @@ -1545,11 +1556,65 @@
}
+static DWORD CALLBACK test_data_obj(void *arg) +{ + IDataObject *data_obj = arg; + + IDataObject_Release(data_obj); + return 0; +} + +static void test_multithreaded_clipboard(void) +{ + IDataObject *data_obj; + HANDLE thread; + HRESULT hr; + DWORD ret; + + OleInitialize(NULL); + + hr = OleGetClipboard(&data_obj); + ok(hr == S_OK, "OleGetClipboard returned %x\n", hr); + + thread = CreateThread(NULL, 0, test_data_obj, data_obj, 0, NULL); + ok(thread != NULL, "CreateThread failed (%d)\n", GetLastError()); + ret = WaitForSingleObject(thread, 5000); + ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret); + + hr = OleGetClipboard(&data_obj); + ok(hr == S_OK, "OleGetClipboard returned %x\n", hr); + IDataObject_Release(data_obj); + + OleUninitialize(); +} + +static void test_get_clipboard_locked(void) +{ + HRESULT hr; + IDataObject *pDObj; + + OleInitialize(NULL); + + pDObj = (IDataObject *)0xdeadbeef; + /* lock clipboard */ + OpenClipboard(NULL); + hr = OleGetClipboard(&pDObj); + todo_wine ok(hr == CLIPBRD_E_CANT_OPEN, "OleGetClipboard() got 0x%08x instead of 0x%08x\n", hr, CLIPBRD_E_CANT_OPEN); + todo_wine ok(pDObj == NULL, "OleGetClipboard() got 0x%p instead of NULL\n",pDObj); + if (pDObj) IDataObject_Release(pDObj); + CloseClipboard(); + + OleUninitialize(); +} + START_TEST(clipboard) { + test_get_clipboard_unitialized(); test_set_clipboard(); test_consumer_refs(); test_flushed_getdata(); test_nonole_clipboard(); test_getdatahere(); -} + test_multithreaded_clipboard(); + test_get_clipboard_locked(); +}
Modified: trunk/rostests/winetests/ole32/compobj.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/compobj.c?... ============================================================================== --- trunk/rostests/winetests/ole32/compobj.c [iso-8859-1] (original) +++ trunk/rostests/winetests/ole32/compobj.c [iso-8859-1] Fri Mar 4 09:30:16 2016 @@ -79,6 +79,7 @@ static HRESULT (WINAPI * pCoGetTreatAsClass)(REFCLSID clsidOld, LPCLSID pClsidNew); static HRESULT (WINAPI * pCoTreatAsClass)(REFCLSID clsidOld, REFCLSID pClsidNew); static HRESULT (WINAPI * pCoGetContextToken)(ULONG_PTR *token); +static HRESULT (WINAPI * pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier); static LONG (WINAPI * pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD); static LONG (WINAPI * pRegOverridePredefKey)(HKEY key, HKEY override);
@@ -280,12 +281,12 @@ " progid="ProgId.ProgId"" " miscStatusIcon="recomposeonresize"" " />" -" <comClass clsid="{0be35203-8f91-11ce-9de3-00aa004bb851}"" +" <comClass description="CustomFont Description" clsid="{0be35203-8f91-11ce-9de3-00aa004bb851}"" " progid="CustomFont"" " miscStatusIcon="recomposeonresize"" " miscStatusContent="insideout"" " />" -" <comClass clsid="{0be35203-8f91-11ce-9de3-00aa004bb852}"" +" <comClass description="StdFont Description" clsid="{0be35203-8f91-11ce-9de3-00aa004bb852}"" " progid="StdFont"" " />" " <comClass clsid="{62222222-1234-1234-1234-56789abcdef0}" >" @@ -2190,6 +2191,73 @@ OleUninitialize(); }
+static void test_OleInitialize_InitCounting(void) +{ + HRESULT hr; + IUnknown *pUnk; + REFCLSID rclsid = &CLSID_InternetZoneManager; + + /* 1. OleInitialize fails but OleUnintialize is still called: apartment stays inited */ + hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED); + ok(hr == S_OK, "CoInitializeEx(COINIT_MULTITHREADED) failed with error 0x%08x\n", hr); + + hr = OleInitialize(NULL); + ok(hr == RPC_E_CHANGED_MODE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", RPC_E_CHANGED_MODE, hr); + OleUninitialize(); + + pUnk = (IUnknown *)0xdeadbeef; + hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk); + ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr); + if (pUnk) IUnknown_Release(pUnk); + + CoUninitialize(); + + /* 2. Extra multiple OleUninitialize: apartment stays inited until CoUnitialize */ + hr = CoInitialize(NULL); + ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr); + + hr = OleInitialize(NULL); + ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr); + OleUninitialize(); + OleUninitialize(); + OleUninitialize(); + + pUnk = (IUnknown *)0xdeadbeef; + hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk); + ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr); + if (pUnk) IUnknown_Release(pUnk); + + CoUninitialize(); + + pUnk = (IUnknown *)0xdeadbeef; + hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk); + ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr); + if (pUnk) IUnknown_Release(pUnk); + + /* 3. CoUninitialize does not formally deinit Ole */ + hr = CoInitialize(NULL); + ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr); + + hr = OleInitialize(NULL); + ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr); + + CoUninitialize(); + CoUninitialize(); + + pUnk = (IUnknown *)0xdeadbeef; + hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk); + ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr); + /* COM is not initialized anymore */ + if (pUnk) IUnknown_Release(pUnk); + + hr = OleInitialize(NULL); + ok(hr == S_FALSE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_FALSE, hr); + /* ... but native OleInit returns S_FALSE as if Ole is considered initialized */ + + OleUninitialize(); + +} + static void test_OleRegGetMiscStatus(void) { ULONG_PTR cookie; @@ -2232,6 +2300,159 @@ pDeactivateActCtx(0, cookie); pReleaseActCtx(handle); } +} + +static void test_OleRegGetUserType(void) +{ + static const WCHAR stdfont_usertypeW[] = {'S','t','a','n','d','a','r','d',' ','F','o','n','t',0}; + static const WCHAR stdfont2_usertypeW[] = {'C','L','S','I','D','_','S','t','d','F','o','n','t',0}; + static const WCHAR clsidkeyW[] = {'C','L','S','I','D',0}; + static const WCHAR defvalueW[] = {'D','e','f','a','u','l','t',' ','N','a','m','e',0}; + static const WCHAR auxvalue0W[] = {'A','u','x',' ','N','a','m','e',' ','0',0}; + static const WCHAR auxvalue2W[] = {'A','u','x',' ','N','a','m','e',' ','2',0}; + static const WCHAR auxvalue3W[] = {'A','u','x',' ','N','a','m','e',' ','3',0}; + static const WCHAR auxvalue4W[] = {'A','u','x',' ','N','a','m','e',' ','4',0}; + + static const char auxvalues[][16] = { + "Aux Name 0", + "Aux Name 1", + "Aux Name 2", + "Aux Name 3", + "Aux Name 4" + }; + + HKEY clsidhkey, hkey, auxhkey, classkey; + DWORD form, ret, disposition; + WCHAR clsidW[39]; + ULONG_PTR cookie; + HANDLE handle; + HRESULT hr; + WCHAR *str; + int i; + + for (form = 0; form <= USERCLASSTYPE_APPNAME+1; form++) { + hr = OleRegGetUserType(&CLSID_Testclass, form, NULL); + ok(hr == E_INVALIDARG, "form %u: got 0x%08x\n", form, hr); + + str = (void*)0xdeadbeef; + hr = OleRegGetUserType(&CLSID_Testclass, form, &str); + ok(hr == REGDB_E_CLASSNOTREG, "form %u: got 0x%08x\n", form, hr); + ok(str == NULL, "form %u: got %p\n", form, str); + + /* same string returned for StdFont for all form types */ + str = NULL; + hr = OleRegGetUserType(&CLSID_StdFont, form, &str); + ok(hr == S_OK, "form %u: got 0x%08x\n", form, hr); + ok(!lstrcmpW(str, stdfont_usertypeW) || !lstrcmpW(str, stdfont2_usertypeW) /* winxp */, + "form %u, got %s\n", form, wine_dbgstr_w(str)); + CoTaskMemFree(str); + } + + if ((handle = activate_context(actctx_manifest, &cookie))) + { + for (form = 0; form <= USERCLASSTYPE_APPNAME+1; form++) { + str = (void*)0xdeadbeef; + hr = OleRegGetUserType(&CLSID_Testclass, form, &str); + ok(hr == REGDB_E_CLASSNOTREG, "form %u: got 0x%08x\n", form, hr); + ok(str == NULL, "form %u: got %s\n", form, wine_dbgstr_w(str)); + + /* same string returned for StdFont for all form types */ + str = NULL; + hr = OleRegGetUserType(&CLSID_StdFont, form, &str); + ok(hr == S_OK, "form %u: got 0x%08x\n", form, hr); + ok(!lstrcmpW(str, stdfont_usertypeW) || !lstrcmpW(str, stdfont2_usertypeW) /* winxp */, + "form %u, got %s\n", form, wine_dbgstr_w(str)); + CoTaskMemFree(str); + } + + pDeactivateActCtx(0, cookie); + pReleaseActCtx(handle); + } + + /* test using registered CLSID */ + 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 == ERROR_ACCESS_DENIED) + { + 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()); + + ret = RegSetValueExW(classkey, NULL, 0, REG_SZ, (const BYTE*)defvalueW, sizeof(defvalueW)); + ok(!ret, "got %d, error %d\n", ret, GetLastError()); + + ret = RegCreateKeyExA(classkey, "AuxUserType", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &auxhkey, NULL); + ok(!ret, "got %d, error %d\n", ret, GetLastError()); + + /* populate AuxUserType */ + for (i = 0; i <= 4; i++) { + char name[16]; + + 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()); + + ret = RegSetValueExA(hkey, NULL, 0, REG_SZ, (const BYTE*)auxvalues[i], strlen(auxvalues[i])); + ok(!ret, "got %d, error %d\n", ret, GetLastError()); + RegCloseKey(hkey); + } + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, 0, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, auxvalue0W), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_FULL, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, defvalueW), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_SHORT, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, auxvalue2W), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, auxvalue3W), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME+1, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, auxvalue4W), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + str = NULL; + hr = OleRegGetUserType(&CLSID_non_existent, USERCLASSTYPE_APPNAME+2, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, defvalueW), "got %s\n", wine_dbgstr_w(str)); + CoTaskMemFree(str); + + /* registry cleanup */ + for (i = 0; i <= 4; i++) + { + char name[2]; + sprintf(name, "%d", i); + RegDeleteKeyA(auxhkey, name); + } + RegCloseKey(auxhkey); + RegDeleteKeyA(classkey, "AuxUserType"); + RegCloseKey(classkey); + RegDeleteKeyW(clsidhkey, clsidW); + RegCloseKey(clsidhkey); + if (disposition == REG_CREATED_NEW_KEY) + RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID"); }
static void test_CoCreateGuid(void) @@ -2628,6 +2849,93 @@ CoUninitialize(); }
+static void test_CoGetMalloc(void) +{ + IMalloc *imalloc; + HRESULT hr; + +if (0) /* crashes on native */ + hr = CoGetMalloc(0, NULL); + + imalloc = (void*)0xdeadbeef; + hr = CoGetMalloc(0, &imalloc); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(imalloc == NULL, "got %p\n", imalloc); + + imalloc = (void*)0xdeadbeef; + hr = CoGetMalloc(MEMCTX_SHARED, &imalloc); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(imalloc == NULL, "got %p\n", imalloc); + + imalloc = (void*)0xdeadbeef; + hr = CoGetMalloc(MEMCTX_MACSYSTEM, &imalloc); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(imalloc == NULL, "got %p\n", imalloc); + + imalloc = (void*)0xdeadbeef; + hr = CoGetMalloc(MEMCTX_UNKNOWN, &imalloc); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(imalloc == NULL, "got %p\n", imalloc); + + imalloc = (void*)0xdeadbeef; + hr = CoGetMalloc(MEMCTX_SAME, &imalloc); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(imalloc == NULL, "got %p\n", imalloc); + + imalloc = NULL; + hr = CoGetMalloc(MEMCTX_TASK, &imalloc); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(imalloc != NULL, "got %p\n", imalloc); + IMalloc_Release(imalloc); +} + +static void test_CoGetApartmentType(void) +{ + APTTYPEQUALIFIER qualifier; + APTTYPE type; + HRESULT hr; + + if (!pCoGetApartmentType) + { + win_skip("CoGetApartmentType not present\n"); + return; + } + + hr = pCoGetApartmentType(NULL, NULL); + ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); + + hr = pCoGetApartmentType(&type, NULL); + ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); + + hr = pCoGetApartmentType(NULL, &qualifier); + ok(hr == E_INVALIDARG, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); + + hr = pCoGetApartmentType(&type, &qualifier); + ok(hr == CO_E_NOTINITIALIZED, "CoGetApartmentType succeeded, error: 0x%0x\n", hr); + ok(type == APTTYPE_CURRENT, "Expected APTTYPE_CURRENT, got %u\n", type); + ok(qualifier == APTTYPEQUALIFIER_NONE, "Expected APTTYPEQUALIFIER_NONE, got %u\n", qualifier); + + hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + ok(!hr, "CoInitializeEx failed, error: 0x%08x\n", hr); + + hr = pCoGetApartmentType(&type, &qualifier); + ok(!hr, "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(); + + hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED); + ok(!hr, "CoInitializeEx failed, error: 0x%08x\n", hr); + + hr = pCoGetApartmentType(&type, &qualifier); + ok(!hr, "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 void init_funcs(void) { HMODULE hOle32 = GetModuleHandleA("ole32"); @@ -2639,6 +2947,7 @@ pCoGetTreatAsClass = (void*)GetProcAddress(hOle32,"CoGetTreatAsClass"); pCoTreatAsClass = (void*)GetProcAddress(hOle32,"CoTreatAsClass"); pCoGetContextToken = (void*)GetProcAddress(hOle32, "CoGetContextToken"); + pCoGetApartmentType = (void*)GetProcAddress(hOle32, "CoGetApartmentType"); pRegDeleteKeyExA = (void*)GetProcAddress(hAdvapi32, "RegDeleteKeyExA"); pRegOverridePredefKey = (void*)GetProcAddress(hAdvapi32, "RegOverridePredefKey"); pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx"); @@ -2687,7 +2996,11 @@ test_CoGetContextToken(); test_TreatAsClass(); test_CoInitializeEx(); + test_OleInitialize_InitCounting(); test_OleRegGetMiscStatus(); test_CoCreateGuid(); test_CoWaitForMultipleHandles(); -} + test_CoGetMalloc(); + test_OleRegGetUserType(); + test_CoGetApartmentType(); +}
Modified: trunk/rostests/winetests/ole32/hglobalstream.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/hglobalstr... ============================================================================== --- trunk/rostests/winetests/ole32/hglobalstream.c [iso-8859-1] (original) +++ trunk/rostests/winetests/ole32/hglobalstream.c [iso-8859-1] Fri Mar 4 09:30:16 2016 @@ -2,6 +2,7 @@ * Stream on HGLOBAL Tests * * Copyright 2006 Robert Shearman (for CodeWeavers) + * Copyright 2016 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -513,10 +514,239 @@ IStream_Release(pStream); }
+static void stream_info(IStream *stream, HGLOBAL *hmem, int *size, int *pos) +{ + HRESULT hr; + STATSTG stat; + LARGE_INTEGER offset; + ULARGE_INTEGER newpos; + + *hmem = 0; + *size = *pos = -1; + + hr = GetHGlobalFromStream(stream, hmem); + ok(hr == S_OK, "unexpected %#x\n", hr); + + memset(&stat, 0x55, sizeof(stat)); + hr = IStream_Stat(stream, &stat, STATFLAG_DEFAULT); + ok(hr == S_OK, "unexpected %#x\n", hr); + ok(stat.type == STGTY_STREAM, "unexpected %#x\n", stat.type); + ok(!stat.pwcsName, "unexpected %p\n", stat.pwcsName); + ok(IsEqualIID(&stat.clsid, &GUID_NULL), "unexpected %s\n", wine_dbgstr_guid(&stat.clsid)); + ok(!stat.cbSize.HighPart, "unexpected %#x\n", stat.cbSize.HighPart); + *size = stat.cbSize.LowPart; + + offset.QuadPart = 0; + hr = IStream_Seek(stream, offset, STREAM_SEEK_CUR, &newpos); + ok(hr == S_OK, "unexpected %#x\n", hr); + ok(!newpos.HighPart, "unexpected %#x\n", newpos.HighPart); + *pos = newpos.LowPart; +} + +static void test_IStream_Clone(void) +{ + static const char hello[] = "Hello World!"; + char buf[32]; + HRESULT hr; + IStream *stream, *clone; + HGLOBAL orig_hmem, hmem, hmem_clone; + ULARGE_INTEGER newsize; + LARGE_INTEGER offset; + int size, pos, ret; + + /* test simple case for Clone */ + orig_hmem = GlobalAlloc(GMEM_MOVEABLE, 0); + ok(orig_hmem != 0, "unexpected %p\n", orig_hmem); + hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = GetHGlobalFromStream(stream, NULL); + ok(hr == E_INVALIDARG, "unexpected %#x\n", hr); + + hr = GetHGlobalFromStream(NULL, &hmem); + ok(hr == E_INVALIDARG, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem == orig_hmem, "handles should match\n"); + ok(size == 0, "unexpected %d\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + hr = IStream_Clone(stream, &clone); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IStream_Write(stream, hello, sizeof(hello), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem != 0, "unexpected %p\n", hmem); + ok(size == 13, "unexpected %d\n", size); + ok(pos == 13, "unexpected %d\n", pos); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); + ok(size == 13, "unexpected %d\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + buf[0] = 0; + hr = IStream_Read(clone, buf, sizeof(buf), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + ok(!strcmp(buf, hello), "wrong stream contents\n"); + + newsize.QuadPart = 0x8000; + hr = IStream_SetSize(stream, newsize); + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem != 0, "unexpected %p\n", hmem); + ok(hmem == orig_hmem, "unexpected %p\n", hmem); + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 13, "unexpected %d\n", pos); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 13, "unexpected %d\n", pos); + + IStream_Release(clone); + IStream_Release(stream); + + /* exploit GMEM_FIXED forced move for the same base streams */ + orig_hmem = GlobalAlloc(GMEM_FIXED, 1); + ok(orig_hmem != 0, "unexpected %p\n", orig_hmem); + hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IStream_Clone(stream, &clone); + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem != 0, "unexpected %p\n", hmem); + ok(size == 1, "unexpected %d\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); + ok(size == 1, "unexpected %d\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + newsize.QuadPart = 0x8000; + hr = IStream_SetSize(stream, newsize); + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem != 0, "unexpected %p\n", hmem); + ok(hmem != orig_hmem, "unexpected %p\n", hmem); + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + IStream_Release(stream); + IStream_Release(clone); + + /* exploit GMEM_FIXED forced move for different base streams */ + orig_hmem = GlobalAlloc(GMEM_FIXED, 1); + ok(orig_hmem != 0, "unexpected %p\n", orig_hmem); + hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &stream); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = CreateStreamOnHGlobal(orig_hmem, TRUE, &clone); + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem != 0, "unexpected %p\n", hmem); + ok(size == 1, "unexpected %d\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); + ok(size == 1, "unexpected %d\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + newsize.QuadPart = 0x8000; + hr = IStream_SetSize(stream, newsize); + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem != 0, "unexpected %p\n", hmem); + ok(hmem != orig_hmem, "unexpected %p\n", hmem); + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone != hmem, "handles should not match\n"); + ok(size == 1, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + IStream_Release(stream); + /* releasing clone leads to test termination under windows + IStream_Release(clone); + */ + + /* test Release for a being cloned stream */ + hr = CreateStreamOnHGlobal(0, TRUE, &stream); + ok(hr == S_OK, "unexpected %#x\n", hr); + + hr = IStream_Clone(stream, &clone); + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(stream, &hmem, &size, &pos); + ok(hmem != 0, "unexpected %p\n", hmem); + ok(size == 0, "unexpected %d\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); + ok(size == 0, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + ret = IStream_Release(stream); + ok(ret == 0, "unexpected %d\n", ret); + + newsize.QuadPart = 0x8000; + hr = IStream_SetSize(clone, newsize); + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 0, "unexpected %d\n", pos); + + hr = IStream_Write(clone, hello, sizeof(hello), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 13, "unexpected %d\n", pos); + + offset.QuadPart = 0; + hr = IStream_Seek(clone, offset, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + + buf[0] = 0; + hr = IStream_Read(clone, buf, sizeof(buf), NULL); + ok(hr == S_OK, "unexpected %#x\n", hr); + ok(!strcmp(buf, hello), "wrong stream contents\n"); + + stream_info(clone, &hmem_clone, &size, &pos); + ok(hmem_clone == hmem, "handles should match\n"); + ok(size == 0x8000, "unexpected %#x\n", size); + ok(pos == 32, "unexpected %d\n", pos); + + ret = IStream_Release(clone); + ok(ret == 0, "unexpected %d\n", ret); +} + START_TEST(hglobalstream) { HRESULT hr; IStream *pStream; + + test_IStream_Clone();
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream); ok_ole_success(hr, "CreateStreamOnHGlobal");
Modified: trunk/rostests/winetests/ole32/ole2.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/ole2.c?rev... ============================================================================== --- trunk/rostests/winetests/ole32/ole2.c [iso-8859-1] (original) +++ trunk/rostests/winetests/ole32/ole2.c [iso-8859-1] Fri Mar 4 09:30:16 2016 @@ -113,7 +113,7 @@
static BOOL g_showRunnable = TRUE; static BOOL g_isRunning = TRUE; -static BOOL g_failGetMiscStatus; +static HRESULT g_GetMiscStatusFailsWith = S_OK; static HRESULT g_QIFailsWith;
static UINT cf_test_1, cf_test_2, cf_test_3; @@ -423,12 +423,15 @@ static HRESULT WINAPI OleObject_GetMiscStatus ( IOleObject *iface, - DWORD dwAspect, + DWORD aspect, DWORD *pdwStatus ) { CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus"); - if(!g_failGetMiscStatus) + + ok(aspect == DVASPECT_CONTENT, "got aspect %d\n", aspect); + + if (g_GetMiscStatusFailsWith == S_OK) { *pdwStatus = OLEMISC_RECOMPOSEONRESIZE; return S_OK; @@ -436,7 +439,7 @@ else { *pdwStatus = 0x1234; - return E_FAIL; + return g_GetMiscStatusFailsWith; } }
@@ -483,7 +486,7 @@ static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv) { trace("OleObjectPersistStg_QueryInterface\n"); - return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv); + return IOleObject_QueryInterface(&OleObject, riid, ppv); }
static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface) @@ -581,7 +584,7 @@
static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv) { - return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv); + return IOleObject_QueryInterface(&OleObject, riid, ppv); }
static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface) @@ -707,7 +710,7 @@
static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv) { - return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv); + return IOleObject_QueryInterface(&OleObject, riid, ppv); }
static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock) @@ -728,7 +731,7 @@
static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv) { - return IUnknown_QueryInterface((IUnknown *)&OleObject, riid, ppv); + return IOleObject_QueryInterface(&OleObject, riid, ppv); }
static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface) @@ -917,6 +920,30 @@ { "OleObjectCache_Release", 0 }, { "OleObject_Release", 0 }, { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, + { NULL, 0 } + }; + static const struct expected_method methods_olerender_draw_with_site[] = + { + { "OleObject_QueryInterface", 0 }, + { "OleObject_AddRef", 0 }, + { "OleObject_QueryInterface", 0 }, + { "OleObject_AddRef", 0 }, + { "OleObject_GetMiscStatus", 0 }, + { "OleObject_QueryInterface", 0 }, + { "OleObjectPersistStg_AddRef", 0 }, + { "OleObjectPersistStg_InitNew", 0 }, + { "OleObjectPersistStg_Release", 0 }, + { "OleObject_SetClientSite", 0 }, + { "OleObject_Release", 0 }, + { "OleObject_QueryInterface", 0 }, + { "OleObjectRunnable_AddRef", 0 }, + { "OleObjectRunnable_Run", 0 }, + { "OleObjectRunnable_Release", 0 }, + { "OleObject_QueryInterface", 0 }, + { "OleObjectCache_AddRef", 0 }, + { "OleObjectCache_Cache", 0 }, + { "OleObjectCache_Release", 0 }, + { "OleObject_Release", 0 }, { NULL, 0 } }; static const struct expected_method methods_olerender_format[] = @@ -1021,6 +1048,23 @@ IOleObject_Release(pObject); CHECK_NO_EXTRA_METHODS();
+ expected_method_list = methods_olerender_draw_with_site; + trace("OleCreate with OLERENDER_DRAW, with site:\n"); + hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject); + ok_ole_success(hr, "OleCreate"); + IOleObject_Release(pObject); + CHECK_NO_EXTRA_METHODS(); + + /* GetMiscStatus fails */ + g_GetMiscStatusFailsWith = 0x8fafefaf; + expected_method_list = methods_olerender_draw_with_site; + trace("OleCreate with OLERENDER_DRAW, with site:\n"); + hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject); + ok_ole_success(hr, "OleCreate"); + IOleObject_Release(pObject); + CHECK_NO_EXTRA_METHODS(); + g_GetMiscStatusFailsWith = S_OK; + formatetc.cfFormat = CF_TEXT; formatetc.ptd = NULL; formatetc.dwAspect = DVASPECT_CONTENT; @@ -1094,7 +1138,7 @@
/* Test once with IOleObject_GetMiscStatus failing */ expected_method_list = methods_oleload; - g_failGetMiscStatus = TRUE; + g_GetMiscStatusFailsWith = E_FAIL; trace("OleLoad:\n"); hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject); ok(hr == S_OK || @@ -1110,9 +1154,9 @@ IOleObject_Release(pObject); CHECK_NO_EXTRA_METHODS(); } + g_GetMiscStatusFailsWith = S_OK;
/* 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); @@ -1453,6 +1497,39 @@ };
static IDataObject DataObject = { &DataObjectVtbl }; + +static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface; + if (*ppv) + { + IUnknown_AddRef((IUnknown *)*ppv); + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI Unknown_AddRef(IUnknown *iface) +{ + ok(0, "unexpected AddRef\n"); + return 2; +} + +static ULONG WINAPI Unknown_Release(IUnknown *iface) +{ + ok(0, "unexpected Release\n"); + return 1; +} + +static const IUnknownVtbl UnknownVtbl = +{ + Unknown_QueryInterface, + Unknown_AddRef, + Unknown_Release +}; + +static IUnknown unknown = { &UnknownVtbl };
static void test_data_cache(void) { @@ -1523,6 +1600,17 @@
hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage); ok_ole_success(hr, "StgCreateDocfile"); + + /* aggregation */ + + /* requested is not IUnknown */ + hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IOleCache2, (void**)&pOleCache); +todo_wine + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IUnknown, (void**)&pOleCache); + ok(hr == S_OK, "got 0x%08x\n", hr); + IOleCache2_Release(pOleCache);
/* Test with new data */
@@ -1870,13 +1958,13 @@ CLSID cls; SIZEL sz;
- hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void *)&unk ); + hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk ); ok( SUCCEEDED(hr), "got %08x\n", hr ); - hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void *)&persist ); + hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void **)&persist ); ok( SUCCEEDED(hr), "got %08x\n", hr ); - hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void *)&data ); + hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void **)&data ); ok( SUCCEEDED(hr), "got %08x\n", hr ); - hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void *)&view ); + hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view ); ok( SUCCEEDED(hr), "got %08x\n", hr );
stg = create_storage( num ); @@ -2172,34 +2260,6 @@ g_showRunnable = TRUE; }
-static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) -{ - *ppv = NULL; - if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface; - if (*ppv) - { - IUnknown_AddRef((IUnknown *)*ppv); - return S_OK; - } - return E_NOINTERFACE; -} - -static ULONG WINAPI Unknown_AddRef(IUnknown *iface) -{ - return 2; -} - -static ULONG WINAPI Unknown_Release(IUnknown *iface) -{ - return 1; -} - -static const IUnknownVtbl UnknownVtbl = -{ - Unknown_QueryInterface, - Unknown_AddRef, - Unknown_Release -};
static HRESULT WINAPI OleRun_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv) { @@ -2272,7 +2332,6 @@ OleRun_SetContainedObject };
-static IUnknown unknown = { &UnknownVtbl }; static IRunnableObject testrunnable = { &oleruntestvtbl };
static void test_OleRun(void) @@ -2291,7 +2350,7 @@ { HRESULT hr;
- hr = OleLockRunning((LPUNKNOWN)&unknown, TRUE, FALSE); + hr = OleLockRunning(&unknown, TRUE, FALSE); ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr); }
Modified: trunk/rostests/winetests/ole32/propvariant.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/propvarian... ============================================================================== --- trunk/rostests/winetests/ole32/propvariant.c [iso-8859-1] (original) +++ trunk/rostests/winetests/ole32/propvariant.c [iso-8859-1] Fri Mar 4 09:30:16 2016 @@ -364,18 +364,12 @@ struct _PMemoryAllocator_vtable *vt; } PMemoryAllocator;
-#ifdef __i386__ -#define __thiscall_wrapper __stdcall -#else -#define __thiscall_wrapper __cdecl -#endif - -static void * __thiscall_wrapper PMemoryAllocator_Allocate(PMemoryAllocator *_this, ULONG cbSize) +static void * WINAPI PMemoryAllocator_Allocate(PMemoryAllocator *_this, ULONG cbSize) { return CoTaskMemAlloc(cbSize); }
-static void __thiscall_wrapper PMemoryAllocator_Free(PMemoryAllocator *_this, void *pv) +static void WINAPI PMemoryAllocator_Free(PMemoryAllocator *_this, void *pv) { CoTaskMemFree(pv); }
Modified: trunk/rostests/winetests/ole32/storage32.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/ole32/storage32.... ============================================================================== --- trunk/rostests/winetests/ole32/storage32.c [iso-8859-1] (original) +++ trunk/rostests/winetests/ole32/storage32.c [iso-8859-1] Fri Mar 4 09:30:16 2016 @@ -1180,7 +1180,7 @@ { IStorage *stg = NULL; HRESULT r; - CLSID temp_cls; + CLSID temp_cls, cls2;
DeleteFileA(filenameA);
@@ -1191,6 +1191,12 @@
r = ReadClassStg( NULL, NULL ); ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r); + + memset(&temp_cls, 0xcc, sizeof(temp_cls)); + memset(&cls2, 0xcc, sizeof(cls2)); + r = ReadClassStg( NULL, &temp_cls ); + ok(r == E_INVALIDARG, "got 0x%08x\n", r); + ok(IsEqualCLSID(&temp_cls, &cls2), "got wrong clsid\n");
r = ReadClassStg( stg, NULL ); ok(r == E_INVALIDARG, "ReadClassStg should return E_INVALIDARG instead of 0x%08X\n", r); @@ -1961,7 +1967,7 @@
static void test_ReadClassStm(void) { - CLSID clsid; + CLSID clsid, clsid2; HRESULT hr; IStream *pStream; static const LARGE_INTEGER llZero; @@ -1976,6 +1982,12 @@
hr = ReadClassStm(pStream, NULL); ok(hr == E_INVALIDARG, "ReadClassStm should have returned E_INVALIDARG instead of 0x%08x\n", hr); + + memset(&clsid, 0xcc, sizeof(clsid)); + memset(&clsid2, 0xcc, sizeof(clsid2)); + hr = ReadClassStm(NULL, &clsid); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(IsEqualCLSID(&clsid, &clsid2), "got wrong clsid\n");
/* test not rewound stream */ hr = ReadClassStm(pStream, &clsid);