[OLE32_WINETEST] Sync with Wine Staging 2.2. CORE-12823
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 5 Mar 2017 21:03:59 +0000 (21:03 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 5 Mar 2017 21:03:59 +0000 (21:03 +0000)
svn path=/trunk/; revision=74095

rostests/winetests/ole32/clipboard.c
rostests/winetests/ole32/compobj.c
rostests/winetests/ole32/marshal.c
rostests/winetests/ole32/propvariant.c

index 167fa99..386f568 100644 (file)
@@ -198,7 +198,7 @@ static HRESULT EnumFormatImpl_Create(FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFO
     ret->fmtetc_cnt = fmtetc_cnt;
     ret->fmtetc = HeapAlloc(GetProcessHeap(), 0, fmtetc_cnt*sizeof(FORMATETC));
     memcpy(ret->fmtetc, fmtetc, fmtetc_cnt*sizeof(FORMATETC));
-    *lplpformatetc = (LPENUMFORMATETC)ret;
+    *lplpformatetc = &ret->IEnumFORMATETC_iface;
     return S_OK;
 }
 
@@ -401,7 +401,7 @@ static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
     obj->fmtetc = HeapAlloc(GetProcessHeap(), 0, obj->fmtetc_cnt*sizeof(FORMATETC));
     InitFormatEtc(obj->fmtetc[0], CF_TEXT, TYMED_HGLOBAL);
 
-    *lplpdataobj = (LPDATAOBJECT)obj;
+    *lplpdataobj = &obj->IDataObject_iface;
     return S_OK;
 }
 
@@ -457,7 +457,7 @@ static HRESULT DataObjectImpl_CreateComplex(LPDATAOBJECT *lplpdataobj)
     InitFormatEtc(obj->fmtetc[7], cf_another, 0xfffff);
     obj->fmtetc[7].dwAspect = DVASPECT_ICON;
 
-    *lplpdataobj = (LPDATAOBJECT)obj;
+    *lplpdataobj = &obj->IDataObject_iface;
     return S_OK;
 }
 
@@ -618,9 +618,7 @@ static void test_enum_fmtetc(IDataObject *src)
     if(src)
     {
         hr = IEnumFORMATETC_Next(src_enum, 1, &src_fmt, NULL);
-        ok(hr == S_FALSE ||
-           broken(hr == S_OK && count == 5), /* win9x and winme don't enumerate duplicated cf's */
-           "%d: got %08x\n", count, hr);
+        ok(hr == S_FALSE, "%d: got %08x\n", count, hr);
         IEnumFORMATETC_Release(src_enum);
     }
 
@@ -801,8 +799,7 @@ static void test_cf_dataobject(IDataObject *data)
             ok(DataObjectImpl_GetDataHere_calls == 1, "got %d\n", DataObjectImpl_GetDataHere_calls);
             ptr = GlobalLock(h);
             size = GlobalSize(h);
-            ok(size == strlen(cmpl_stm_data) ||
-               broken(size > strlen(cmpl_stm_data)), /* win9x, winme */
+            ok(size == strlen(cmpl_stm_data),
                "expected %d got %d\n", lstrlenA(cmpl_stm_data), size);
             ok(!memcmp(ptr, cmpl_stm_data, strlen(cmpl_stm_data)), "mismatch\n");
             GlobalUnlock(h);
@@ -818,8 +815,7 @@ static void test_cf_dataobject(IDataObject *data)
             ok(DataObjectImpl_GetDataHere_calls == 0, "got %d\n", DataObjectImpl_GetDataHere_calls);
             ptr = GlobalLock(h);
             size = GlobalSize(h);
-            ok(size == strlen(cmpl_text_data) + 1 ||
-               broken(size > strlen(cmpl_text_data) + 1), /* win9x, winme */
+            ok(size == strlen(cmpl_text_data) + 1,
                "expected %d got %d\n", lstrlenA(cmpl_text_data) + 1, size);
             ok(!memcmp(ptr, cmpl_text_data, strlen(cmpl_text_data) + 1), "mismatch\n");
             GlobalUnlock(h);
@@ -836,6 +832,7 @@ static void test_set_clipboard(void)
     ULONG ref;
     LPDATAOBJECT data1, data2, data_cmpl;
     HGLOBAL hblob, h;
+    void *ptr;
 
     cf_stream = RegisterClipboardFormatA("stream format");
     cf_storage = RegisterClipboardFormatA("storage format");
@@ -861,10 +858,7 @@ static void test_set_clipboard(void)
 
     CoInitialize(NULL);
     hr = OleSetClipboard(data1);
-    ok(hr == CO_E_NOTINITIALIZED ||
-       hr == CLIPBRD_E_CANT_SET, /* win9x */
-       "OleSetClipboard should have failed with "
-       "CO_E_NOTINITIALIZED or CLIPBRD_E_CANT_SET instead of 0x%08x\n", hr);
+    ok(hr == CO_E_NOTINITIALIZED, "OleSetClipboard failed with 0x%08x\n", hr);
     CoUninitialize();
 
     hr = OleInitialize(NULL);
@@ -896,14 +890,18 @@ static void test_set_clipboard(void)
     /* put a format directly onto the clipboard to show
        OleFlushClipboard doesn't empty the clipboard */
     hblob = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE|GMEM_ZEROINIT, 10);
-    OpenClipboard(NULL);
+    ptr = GlobalLock( hblob );
+    ok( ptr && ptr != hblob, "got fixed block %p / %p\n", ptr, hblob );
+    GlobalUnlock( hblob );
+    ok( OpenClipboard(NULL), "OpenClipboard failed\n" );
     h = SetClipboardData(cf_onemore, hblob);
     ok(h == hblob, "got %p\n", h);
     h = GetClipboardData(cf_onemore);
-    ok(h == hblob ||
-       broken(h != NULL), /* win9x */
-       "got %p\n", h);
-    CloseClipboard();
+    ok(h == hblob, "got %p / %p\n", h, hblob);
+    ptr = GlobalLock( h );
+    ok( ptr && ptr != h, "got fixed block %p / %p\n", ptr, h );
+    GlobalUnlock( hblob );
+    ok( CloseClipboard(), "CloseClipboard failed\n" );
 
     hr = OleFlushClipboard();
     ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr);
@@ -915,12 +913,13 @@ static void test_set_clipboard(void)
     ok(hr == S_FALSE, "expect S_FALSE, hr = 0x%08x\n", hr);
 
     /* format should survive the flush */
-    OpenClipboard(NULL);
+    ok( OpenClipboard(NULL), "OpenClipboard failed\n" );
     h = GetClipboardData(cf_onemore);
-    ok(h == hblob ||
-       broken(h != NULL), /* win9x */
-       "got %p\n", h);
-    CloseClipboard();
+    ok(h == hblob, "got %p\n", h);
+    ptr = GlobalLock( h );
+    ok( ptr && ptr != h, "got fixed block %p / %p\n", ptr, h );
+    GlobalUnlock( hblob );
+    ok( CloseClipboard(), "CloseClipboard failed\n" );
 
     test_cf_dataobject(NULL);
 
@@ -952,6 +951,104 @@ static void test_set_clipboard(void)
     OleUninitialize();
 }
 
+static LPDATAOBJECT clip_data;
+static HWND next_wnd;
+static UINT wm_drawclipboard;
+
+static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+    LRESULT ret;
+
+    switch (msg)
+    {
+    case WM_DRAWCLIPBOARD:
+        wm_drawclipboard++;
+        if (clip_data)
+        {
+            /* if this is the WM_DRAWCLIPBOARD of a previous change, the data isn't current yet */
+            /* this demonstrates an issue in Qt where it will free the data while it's being set */
+            HRESULT hr = OleIsCurrentClipboard( clip_data );
+            ok( hr == (wm_drawclipboard > 1) ? S_OK : S_FALSE,
+                "OleIsCurrentClipboard returned %x\n", hr );
+        }
+        break;
+    case WM_CHANGECBCHAIN:
+        if (next_wnd == (HWND)wp) next_wnd = (HWND)lp;
+        else if (next_wnd) SendMessageA( next_wnd, msg, wp, lp );
+        break;
+    case WM_USER:
+        ret = wm_drawclipboard;
+        wm_drawclipboard = 0;
+        return ret;
+    }
+
+    return DefWindowProcA(hwnd, msg, wp, lp);
+}
+
+static DWORD CALLBACK set_clipboard_thread(void *arg)
+{
+    OpenClipboard( GetDesktopWindow() );
+    EmptyClipboard();
+    SetClipboardData( CF_WAVE, 0 );
+    CloseClipboard();
+    return 0;
+}
+
+/* test that WM_DRAWCLIPBOARD can be delivered for a previous change during OleSetClipboard */
+static void test_set_clipboard_DRAWCLIPBOARD(void)
+{
+    LPDATAOBJECT data;
+    HRESULT hr;
+    WNDCLASSA cls;
+    HWND viewer;
+    int ret;
+    HANDLE thread;
+
+    hr = DataObjectImpl_CreateText("data", &data);
+    ok(hr == S_OK, "Failed to create data object: 0x%08x\n", hr);
+
+    memset(&cls, 0, sizeof(cls));
+    cls.lpfnWndProc = clipboard_wnd_proc;
+    cls.hInstance = GetModuleHandleA(NULL);
+    cls.lpszClassName = "clipboard_test";
+    RegisterClassA(&cls);
+
+    viewer = CreateWindowA("clipboard_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0);
+    ok(viewer != NULL, "CreateWindow failed: %d\n", GetLastError());
+    next_wnd = SetClipboardViewer( viewer );
+
+    ret = SendMessageA( viewer, WM_USER, 0, 0 );
+    ok( ret == 1, "%u WM_DRAWCLIPBOARD received\n", ret );
+
+    hr = OleInitialize(NULL);
+    ok(hr == S_OK, "OleInitialize failed with error 0x%08x\n", hr);
+
+    ret = SendMessageA( viewer, WM_USER, 0, 0 );
+    ok( !ret, "%u WM_DRAWCLIPBOARD received\n", ret );
+
+    thread = CreateThread(NULL, 0, set_clipboard_thread, NULL, 0, NULL);
+    ok(thread != NULL, "CreateThread failed (%d)\n", GetLastError());
+    ret = WaitForSingleObject(thread, 5000);
+    ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret);
+
+    clip_data = data;
+    hr = OleSetClipboard(data);
+    ok(hr == S_OK, "failed to set clipboard to data, hr = 0x%08x\n", hr);
+
+    ret = SendMessageA( viewer, WM_USER, 0, 0 );
+    ok( ret == 2, "%u WM_DRAWCLIPBOARD received\n", ret );
+
+    clip_data = NULL;
+    hr = OleFlushClipboard();
+    ok(hr == S_OK, "failed to flush clipboard, hr = 0x%08x\n", hr);
+    ret = IDataObject_Release(data);
+    ok(ret == 0, "got %d\n", ret);
+
+    OleUninitialize();
+    ChangeClipboardChain( viewer, next_wnd );
+    DestroyWindow( viewer );
+}
+
 static inline ULONG count_refs(IDataObject *d)
 {
     IDataObject_AddRef(d);
@@ -987,9 +1084,7 @@ static void test_consumer_refs(void)
     hr = OleGetClipboard(&get2);
     ok(hr == S_OK, "got %08x\n", hr);
 
-    ok(get1 == get2 ||
-       broken(get1 != get2), /* win9x, winme & nt4 */
-       "data objects differ\n");
+    ok(get1 == get2, "data objects differ\n");
     refs = IDataObject_Release(get2);
     ok(refs == (get1 == get2 ? 1 : 0), "got %d\n", refs);
 
@@ -1345,17 +1440,14 @@ static void test_nonole_clipboard(void)
     hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
     ok(hr == S_OK, "got %08x\n", hr); /* User32 adds some synthesised formats */
 
-    todo_wine ok(fmt.cfFormat == CF_LOCALE, "cf %04x\n", fmt.cfFormat);
-    if(fmt.cfFormat == CF_LOCALE)
-    {
-        ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
-        ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
-        ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
-        ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
+    ok(fmt.cfFormat == CF_LOCALE, "cf %04x\n", fmt.cfFormat);
+    ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
+    ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
+    ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
+    todo_wine ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
 
-        hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
-        ok(hr == S_OK, "got %08x\n", hr);
-    }
+    hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
+    ok(hr == S_OK, "got %08x\n", hr);
 
     ok(fmt.cfFormat == CF_OEMTEXT, "cf %04x\n", fmt.cfFormat);
     ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
@@ -1365,19 +1457,14 @@ static void test_nonole_clipboard(void)
 
     hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
     ok(hr == S_OK, "got %08x\n", hr);
-    ok(fmt.cfFormat == CF_UNICODETEXT ||
-       broken(fmt.cfFormat == CF_METAFILEPICT), /* win9x and winme don't have CF_UNICODETEXT */
-       "cf %04x\n", fmt.cfFormat);
-    if(fmt.cfFormat == CF_UNICODETEXT)
-    {
-        ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
-        ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
-        ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
-        ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
+    ok(fmt.cfFormat == CF_UNICODETEXT, "cf %04x\n", fmt.cfFormat);
+    ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
+    ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
+    ok(fmt.lindex == -1, "lindex %d\n", fmt.lindex);
+    ok(fmt.tymed == (TYMED_ISTREAM | TYMED_HGLOBAL), "tymed %x\n", fmt.tymed);
 
-        hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
-        ok(hr == S_OK, "got %08x\n", hr);
-    }
+    hr = IEnumFORMATETC_Next(enum_fmt, 1, &fmt, NULL);
+    ok(hr == S_OK, "got %08x\n", hr);
     ok(fmt.cfFormat == CF_METAFILEPICT, "cf %04x\n", fmt.cfFormat);
     ok(fmt.ptd == NULL, "ptd %p\n", fmt.ptd);
     ok(fmt.dwAspect == DVASPECT_CONTENT, "aspect %x\n", fmt.dwAspect);
@@ -1611,6 +1698,7 @@ START_TEST(clipboard)
 {
     test_get_clipboard_uninitialized();
     test_set_clipboard();
+    test_set_clipboard_DRAWCLIPBOARD();
     test_consumer_refs();
     test_flushed_getdata();
     test_nonole_clipboard();
index f43bcdd..cc230ee 100644 (file)
@@ -626,6 +626,26 @@ static DWORD CALLBACK ole_initialize_thread(LPVOID pv)
     return hr;
 }
 
+#define test_apt_type(t, q, t_t, t_q) _test_apt_type(t, q, t_t, t_q, __LINE__)
+static void _test_apt_type(APTTYPE expected_type, APTTYPEQUALIFIER expected_qualifier, BOOL todo_type,
+        BOOL todo_qualifier, int line)
+{
+    APTTYPEQUALIFIER qualifier = ~0u;
+    APTTYPE type = ~0u;
+    HRESULT hr;
+
+    if (!pCoGetApartmentType)
+        return;
+
+    hr = pCoGetApartmentType(&type, &qualifier);
+    ok_(__FILE__, line)(hr == S_OK || hr == CO_E_NOTINITIALIZED, "Unexpected return code: 0x%08x\n", hr);
+todo_wine_if(todo_type)
+    ok_(__FILE__, line)(type == expected_type, "Wrong apartment type %d, expected %d\n", type, expected_type);
+todo_wine_if(todo_qualifier)
+    ok_(__FILE__, line)(qualifier == expected_qualifier, "Wrong apartment qualifier %d, expected %d\n", qualifier,
+        expected_qualifier);
+}
+
 static void test_CoCreateInstance(void)
 {
     HRESULT hr;
@@ -670,6 +690,8 @@ static void test_CoCreateInstance(void)
     /* show that COM doesn't have to be initialized for multi-threaded apartments if another
        thread has already done so */
 
+    test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
+
     info.wait = CreateEventA(NULL, TRUE, FALSE, NULL);
     ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
 
@@ -681,6 +703,8 @@ static void test_CoCreateInstance(void)
 
     ok( !WaitForSingleObject(info.wait, 10000 ), "wait timed out\n" );
 
+    test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE);
+
     pUnk = (IUnknown *)0xdeadbeef;
     hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
     ok(hr == S_OK, "CoCreateInstance should have returned S_OK instead of 0x%08x\n", hr);
@@ -696,6 +720,8 @@ static void test_CoCreateInstance(void)
     CloseHandle(thread);
     CloseHandle(info.wait);
     CloseHandle(info.stop);
+
+    test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
 }
 
 static void test_CoGetClassObject(void)
@@ -722,6 +748,8 @@ static void test_CoGetClassObject(void)
     /* show that COM doesn't have to be initialized for multi-threaded apartments if another
        thread has already done so */
 
+    test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
+
     info.wait = CreateEventA(NULL, TRUE, FALSE, NULL);
     ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
 
@@ -733,6 +761,8 @@ static void test_CoGetClassObject(void)
 
     ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" );
 
+    test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE);
+
     pUnk = (IUnknown *)0xdeadbeef;
     hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
     if(hr == REGDB_E_CLASSNOTREG)
@@ -754,6 +784,8 @@ static void test_CoGetClassObject(void)
     CloseHandle(info.wait);
     CloseHandle(info.stop);
 
+    test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
+
     if (!pRegOverridePredefKey)
     {
         win_skip("RegOverridePredefKey not available\n");
@@ -1807,6 +1839,8 @@ static void test_CoGetObjectContext(void)
     /* show that COM doesn't have to be initialized for multi-threaded apartments if another
        thread has already done so */
 
+    test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
+
     info.wait = CreateEventA(NULL, TRUE, FALSE, NULL);
     ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
 
@@ -1818,6 +1852,8 @@ static void test_CoGetObjectContext(void)
 
     ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" );
 
+    test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE);
+
     pComThreadingInfo = NULL;
     hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
     ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
@@ -1851,8 +1887,12 @@ static void test_CoGetObjectContext(void)
     CloseHandle(info.wait);
     CloseHandle(info.stop);
 
+    test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
+
     pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
 
+    test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
+
     hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
     ok_ole_success(hr, "CoGetObjectContext");
 
@@ -2037,6 +2077,8 @@ static void test_CoGetContextToken(void)
     /* show that COM doesn't have to be initialized for multi-threaded apartments if another
        thread has already done so */
 
+    test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
+
     info.wait = CreateEventA(NULL, TRUE, FALSE, NULL);
     ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
 
@@ -2048,6 +2090,8 @@ static void test_CoGetContextToken(void)
 
     ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" );
 
+    test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE);
+
     token = 0;
     hr = pCoGetContextToken(&token);
     ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
@@ -2068,8 +2112,12 @@ static void test_CoGetContextToken(void)
     CloseHandle(info.wait);
     CloseHandle(info.stop);
 
+    test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
+
     CoInitialize(NULL);
 
+    test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE, FALSE, FALSE);
+
     hr = pCoGetContextToken(NULL);
     ok(hr == E_POINTER, "Expected E_POINTER, got 0x%08x\n", hr);
 
@@ -2888,10 +2936,8 @@ static void test_CoGetMalloc(void)
     IMalloc *imalloc;
     HRESULT hr;
 
-if (0) /* crashes on native */
-{
-    hr = CoGetMalloc(0, NULL);
-}
+    if (0) /* crashes on native */
+        hr = CoGetMalloc(0, NULL);
 
     imalloc = (void*)0xdeadbeef;
     hr = CoGetMalloc(0, &imalloc);
index 2279fd5..020b678 100644 (file)
@@ -3467,6 +3467,19 @@ static ULONG WINAPI TestChannelHook_Release(IChannelHook *iface)
     return 1;
 }
 
+static BOOL new_hook_struct;
+static int method, server_tid;
+static GUID causality;
+
+struct new_hook_info
+{
+    IID iid;
+    GUID causality;
+    DWORD server_pid;
+    DWORD server_tid;
+    WORD method;
+};
+
 static void WINAPI TestChannelHook_ClientGetSize(
     IChannelHook *iface,
     REFGUID uExtent,
@@ -3474,12 +3487,36 @@ static void WINAPI TestChannelHook_ClientGetSize(
     ULONG  *pDataSize )
 {
     SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
-    trace("TestChannelHook_ClientGetBuffer\n");
-    trace("\t%s method %d\n", debugstr_iid(riid), info->iMethod);
-    trace("\tcid: %s\n", debugstr_iid(&info->uCausality));
-    ok(info->cbSize == sizeof(*info), "info->cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
-    ok(info->dwServerPid == GetCurrentProcessId(), "info->dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
-    ok(!info->pObject, "info->pObject should be NULL\n");
+    trace("TestChannelHook_ClientGetSize\n");
+    trace("\t%s\n", debugstr_iid(riid));
+    if (info->cbSize != sizeof(*info))
+        new_hook_struct = TRUE;
+
+    if (!new_hook_struct)
+    {
+        ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
+        ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
+        ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
+        ok(!info->pObject, "pObject should be NULL\n");
+        if (method == 3)
+            causality = info->uCausality;
+        else
+            ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
+    }
+    else
+    {
+        struct new_hook_info *new_info = (struct new_hook_info *)riid;
+        ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
+           GetCurrentProcessId());
+        ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
+           server_tid);
+        ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
+        if (method == 3)
+            causality = new_info->causality;
+        else
+            ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
+    }
+
     ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
 
     *pDataSize = 1;
@@ -3494,9 +3531,26 @@ static void WINAPI TestChannelHook_ClientFillBuffer(
 {
     SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
     trace("TestChannelHook_ClientFillBuffer\n");
-    ok(info->cbSize == sizeof(*info), "info->cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
-    ok(info->dwServerPid == GetCurrentProcessId(), "info->dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
-    ok(!info->pObject, "info->pObject should be NULL\n");
+
+    if (!new_hook_struct)
+    {
+        ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
+        ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
+        ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
+        ok(!info->pObject, "pObject should be NULL\n");
+        ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
+    }
+    else
+    {
+        struct new_hook_info *new_info = (struct new_hook_info *)riid;
+        ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
+           GetCurrentProcessId());
+        ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
+           server_tid);
+        ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
+        ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
+    }
+
     ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
 
     *(unsigned char *)pDataBuffer = 0xcc;
@@ -3514,11 +3568,28 @@ static void WINAPI TestChannelHook_ClientNotify(
 {
     SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
     trace("TestChannelHook_ClientNotify hrFault = 0x%08x\n", hrFault);
-    ok(info->cbSize == sizeof(*info), "info->cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
-    ok(info->dwServerPid == GetCurrentProcessId(), "info->dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
-    todo_wine {
-    ok(info->pObject != NULL, "info->pObject shouldn't be NULL\n");
+
+    if (!new_hook_struct)
+    {
+        ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
+        ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
+        ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
+        todo_wine {
+            ok(info->pObject != NULL, "pObject shouldn't be NULL\n");
+        }
+        ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
+    }
+    else
+    {
+        struct new_hook_info *new_info = (struct new_hook_info *)riid;
+        ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
+           GetCurrentProcessId());
+        ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
+           server_tid);
+        ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
+        ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
     }
+
     ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
 }
 
@@ -3532,9 +3603,26 @@ static void WINAPI TestChannelHook_ServerNotify(
 {
     SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
     trace("TestChannelHook_ServerNotify\n");
-    ok(info->cbSize == sizeof(*info), "info->cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
-    ok(info->dwServerPid == GetCurrentProcessId(), "info->dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
-    ok(info->pObject != NULL, "info->pObject shouldn't be NULL\n");
+
+    if (!new_hook_struct)
+    {
+        ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
+        ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
+        ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
+        ok(info->pObject != NULL, "pObject shouldn't be NULL\n");
+        ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
+    }
+    else
+    {
+        struct new_hook_info *new_info = (struct new_hook_info *)riid;
+        ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
+           GetCurrentProcessId());
+        ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
+           server_tid);
+        ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
+        ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
+    }
+
     ok(cbDataSize == 1, "cbDataSize should have been 1 instead of %d\n", cbDataSize);
     ok(*(unsigned char *)pDataBuffer == 0xcc, "pDataBuffer should have contained 0xcc instead of 0x%x\n", *(unsigned char *)pDataBuffer);
     ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
@@ -3549,10 +3637,26 @@ static void WINAPI TestChannelHook_ServerGetSize(
 {
     SChannelHookCallInfo *info = (SChannelHookCallInfo *)riid;
     trace("TestChannelHook_ServerGetSize\n");
-    trace("\t%s method %d\n", debugstr_iid(riid), info->iMethod);
-    ok(info->cbSize == sizeof(*info), "info->cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
-    ok(info->dwServerPid == GetCurrentProcessId(), "info->dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
-    ok(info->pObject != NULL, "info->pObject shouldn't be NULL\n");
+    trace("\t%s\n", debugstr_iid(riid));
+    if (!new_hook_struct)
+    {
+        ok(info->cbSize == sizeof(*info), "cbSize was %d instead of %d\n", info->cbSize, (int)sizeof(*info));
+        ok(info->dwServerPid == GetCurrentProcessId(), "dwServerPid was 0x%x instead of 0x%x\n", info->dwServerPid, GetCurrentProcessId());
+        ok(info->iMethod == method, "iMethod was %d should be %d\n", info->iMethod, method);
+        ok(info->pObject != NULL, "pObject shouldn't be NULL\n");
+        ok(IsEqualGUID(&info->uCausality, &causality), "causality wasn't correct\n");
+    }
+    else
+    {
+        struct new_hook_info *new_info = (struct new_hook_info *)riid;
+        ok(new_info->server_pid == GetCurrentProcessId(), "server pid was 0x%x instead of 0x%x\n", new_info->server_pid,
+           GetCurrentProcessId());
+        ok(new_info->server_tid == server_tid, "server tid was 0x%x instead of 0x%x\n", new_info->server_tid,
+           server_tid);
+        ok(new_info->method == method, "method was %d instead of %d\n", new_info->method, method);
+        ok(IsEqualGUID(&new_info->causality, &causality), "causality wasn't correct\n");
+    }
+
     ok(IsEqualGUID(uExtent, &EXTENTID_WineTest), "uExtent wasn't correct\n");
     if (hrFault != S_OK)
         trace("\thrFault = 0x%08x\n", hrFault);
@@ -3607,6 +3711,7 @@ static void test_channel_hook(void)
     hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
     ok_ole_success(hr, CreateStreamOnHGlobal);
     tid = start_host_object2(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &MessageFilter, &thread);
+    server_tid = tid;
 
     ok_more_than_one_lock();
 
@@ -3617,8 +3722,11 @@ static void test_channel_hook(void)
 
     ok_more_than_one_lock();
 
+    method = 3;
     hr = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (LPVOID*)&proxy);
     ok_ole_success(hr, IClassFactory_CreateInstance);
+
+    method = 5;
     IUnknown_Release(proxy);
 
     IClassFactory_Release(cf);
index f426a5a..26a5a91 100644 (file)
@@ -176,16 +176,7 @@ static void expect(HRESULT hr, VARTYPE vt, BOOL copy, int line)
     }
     else if(flags == PROP_V0)
         ok(hr == S_OK, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr);
-    else if(flags & PROP_TODO)
-    {
-        todo_wine
-        {
-        if(hr != S_OK)
-            win_skip("%s (%s): unsupported\n", wine_vtypes[idx], modifier);
-        else ok(hr == S_OK, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr);
-        }
-    }
-    else
+    else todo_wine_if(flags & PROP_TODO)
     {
         if(hr != S_OK)
             win_skip("%s (%s): unsupported\n", wine_vtypes[idx], modifier);