[HLINK_WINETEST] Sync with Wine Staging 4.0. CORE-15682
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 26 Jan 2019 12:07:24 +0000 (13:07 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 26 Jan 2019 12:07:24 +0000 (13:07 +0100)
modules/rostests/winetests/hlink/hlink.c

index 265dea3..ccbbd88 100644 (file)
@@ -81,9 +81,16 @@ DEFINE_EXPECT(HT_GetFriendlyName);
 
 DEFINE_EXPECT(HLF_UpdateHlink);
 
+DEFINE_EXPECT(BindStatusCallback_GetBindInfo);
+DEFINE_EXPECT(BindStatusCallback_OnObjectAvailable);
+DEFINE_EXPECT(BindStatusCallback_OnStartBinding);
+DEFINE_EXPECT(BindStatusCallback_OnStopBinding);
+
 DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
 DEFINE_GUID(IID_IHlinkHistory,0x79eac9c8,0xbaf9,0x11ce,0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b);
 
+static IHlinkTarget HlinkTarget;
+
 static const WCHAR winehq_urlW[] =
         {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',
          '/','t','e','s','t','s','/','h','e','l','l','o','.','h','t','m','l',0};
@@ -120,7 +127,7 @@ static void test_HlinkIsShortcut(void)
         {NULL,  E_INVALIDARG}
     };
 
-    for(i=0; i<sizeof(shortcut_test)/sizeof(shortcut_test[0]); i++) {
+    for (i=0; i < ARRAY_SIZE(shortcut_test); i++) {
         hres = HlinkIsShortcut(shortcut_test[i].file);
         ok(hres == shortcut_test[i].hres, "[%d] HlinkIsShortcut returned %08x, expected %08x\n",
            i, hres, shortcut_test[i].hres);
@@ -651,7 +658,7 @@ static void test_HlinkParseDisplayName(void)
 
     hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon);
     ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
-    ok(eaten == sizeof(winehq_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+    ok(eaten == ARRAY_SIZE(winehq_urlW)-1, "eaten=%d\n", eaten);
     ok(mon != NULL, "mon == NULL\n");
 
     hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
@@ -667,7 +674,7 @@ static void test_HlinkParseDisplayName(void)
 
     hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon);
     ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
-    ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+    ok(eaten == ARRAY_SIZE(clsid_nameW)-1, "eaten=%d\n", eaten);
     ok(mon != NULL, "mon == NULL\n");
 
     hres = IMoniker_IsSystemMoniker(mon, &issys);
@@ -678,7 +685,7 @@ static void test_HlinkParseDisplayName(void)
 
     hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon);
     ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
-    ok(eaten == sizeof(invalid_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+    ok(eaten == ARRAY_SIZE(invalid_urlW)-1, "eaten=%d\n", eaten);
     ok(mon != NULL, "mon == NULL\n");
 
     hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
@@ -694,7 +701,7 @@ static void test_HlinkParseDisplayName(void)
 
     hres = HlinkParseDisplayName(bctx, file_urlW, FALSE, &eaten, &mon);
     ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres);
-    ok(eaten == sizeof(file_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten);
+    ok(eaten == ARRAY_SIZE(file_urlW)-1, "eaten=%d\n", eaten);
     ok(mon != NULL, "mon == NULL\n");
 
     hres = IMoniker_GetDisplayName(mon, bctx, 0, &name);
@@ -757,21 +764,25 @@ static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *ifa
     return E_NOINTERFACE;
 }
 
+static LONG bind_callback_refs = 1;
+
 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
 {
-    return 2;
+    return ++bind_callback_refs;
 }
 
 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
 {
-    return 1;
+    return --bind_callback_refs;
 }
 
-static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
-        IBinding *pib)
+static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface,
+        DWORD reserved, IBinding *binding)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    CHECK_EXPECT(BindStatusCallback_OnStartBinding);
+
+    ok(!binding, "binding = %p\n", binding);
+    return S_OK;
 }
 
 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
@@ -793,15 +804,20 @@ static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface,
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
+static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hr, const WCHAR *error)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    CHECK_EXPECT(BindStatusCallback_OnStopBinding);
+
+    ok(hr == S_OK, "got hr %#x\n", hr);
+    ok(!error, "got error %s\n", wine_dbgstr_w(error));
+
+    return 0xdeadbeef;
 }
 
-static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
+static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *bind_flags, BINDINFO *bind_info)
 {
-    ok(0, "unexpected call\n");
+    CHECK_EXPECT(BindStatusCallback_GetBindInfo);
+
     return E_NOTIMPL;
 }
 
@@ -812,10 +828,14 @@ static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *if
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
+static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID iid, IUnknown *out)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    CHECK_EXPECT(BindStatusCallback_OnObjectAvailable);
+
+    ok(IsEqualGUID(iid, &IID_IUnknown), "iid = %s\n", wine_dbgstr_guid(iid));
+    ok(out == (IUnknown *)&HlinkTarget, "out = %p\n", out);
+
+    return 0xdeadbeef;
 }
 
 static IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
@@ -853,14 +873,16 @@ static HRESULT WINAPI HlinkBrowseContext_QueryInterface(
     return E_NOINTERFACE;
 }
 
+static LONG browse_ctx_refs = 1;
+
 static ULONG WINAPI HlinkBrowseContext_AddRef(IHlinkBrowseContext *iface)
 {
-    return 2;
+    return ++browse_ctx_refs;
 }
 
 static ULONG WINAPI HlinkBrowseContext_Release(IHlinkBrowseContext *iface)
 {
-    return 1;
+    return --browse_ctx_refs;
 }
 
 static HRESULT WINAPI HlinkBrowseContext_Register(IHlinkBrowseContext *iface,
@@ -1125,9 +1147,16 @@ static HRESULT WINAPI Moniker_GetSizeMax(IMoniker *iface, ULARGE_INTEGER *pcbSiz
     return E_NOTIMPL;
 }
 
+static BOOL async_bind;
+static IBindStatusCallback *async_bind_callback;
+
 static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft,
         REFIID riid, void **ppv)
 {
+    static WCHAR bscb_holderW[] = {'_','B','S','C','B','_','H','o','l','d','e','r','_',0};
+    IUnknown *bind_callback_holder;
+    HRESULT hr;
+
     CHECK_EXPECT(BindToObject);
 
     ok(pbc != _bctx, "pbc != _bctx\n");
@@ -1136,6 +1165,17 @@ static HRESULT WINAPI Moniker_BindToObject(IMoniker *iface, IBindCtx *pbc, IMoni
     ok(ppv != NULL, "ppv == NULL\n");
     ok(*ppv == NULL, "*ppv = %p\n", *ppv);
 
+    if (async_bind)
+    {
+        hr = IBindCtx_GetObjectParam(pbc, bscb_holderW, &bind_callback_holder);
+        ok(hr == S_OK, "Failed to get IBindStatusCallback holder, hr %#x.\n", hr);
+        hr = IUnknown_QueryInterface(bind_callback_holder, &IID_IBindStatusCallback,
+                (void **)&async_bind_callback);
+        ok(hr == S_OK, "Failed to get IBindStatusCallback interface, hr %#x.\n", hr);
+        IUnknown_Release(bind_callback_holder);
+        return MK_S_ASYNCHRONOUS;
+    }
+
     *ppv = &HlinkTarget;
     return S_OK;
 }
@@ -2188,6 +2228,8 @@ static void test_StdHlink(void)
 
 static void test_Hlink_Navigate(void)
 {
+    BINDINFO bind_info = {sizeof(BINDINFO)};
+    DWORD bind_flags;
     IHlink *hlink;
     IBindCtx *pbc;
     HRESULT hres;
@@ -2301,6 +2343,179 @@ if (0) {    /* these currently open a browser window on wine */
     else
         skip("interactive IHlink_Navigate tests\n");
 
+    /* test binding callback */
+    SET_EXPECT(IsSystemMoniker);
+    SET_EXPECT(GetDisplayName);
+    SET_EXPECT(BindStatusCallback_GetBindInfo);
+    SET_EXPECT(HBC_GetObject);
+    SET_EXPECT(Reduce);
+    SET_EXPECT(BindToObject);
+    SET_EXPECT(BindStatusCallback_OnStartBinding);
+    SET_EXPECT(BindStatusCallback_OnObjectAvailable);
+    SET_EXPECT(HT_QueryInterface_IHlinkTarget);
+    SET_EXPECT(HT_GetBrowseContext);
+    SET_EXPECT(HT_SetBrowseContext);
+    SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
+    SET_EXPECT(HT_Navigate);
+    SET_EXPECT(HT_GetFriendlyName);
+    SET_EXPECT(BindStatusCallback_OnStopBinding);
+    hres = IHlink_Navigate(hlink, 0, pbc, &BindStatusCallback, &HlinkBrowseContext);
+    ok(hres == S_OK, "Navigate failed: %#x\n", hres);
+    CHECK_CALLED(IsSystemMoniker);
+    CHECK_CALLED(GetDisplayName);
+    CHECK_CALLED(HBC_GetObject);
+todo_wine
+    CHECK_CALLED(BindStatusCallback_GetBindInfo);
+todo_wine
+    CHECK_CALLED(Reduce);
+    CHECK_CALLED(BindToObject);
+todo_wine {
+    CHECK_CALLED(BindStatusCallback_OnStartBinding);
+    CHECK_CALLED(BindStatusCallback_OnObjectAvailable);
+}
+    CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
+todo_wine
+    CHECK_CALLED(HT_GetBrowseContext);
+    CHECK_CALLED(HT_SetBrowseContext);
+todo_wine
+    CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
+    CHECK_CALLED(HT_Navigate);
+todo_wine
+    CHECK_CALLED(HT_GetFriendlyName);
+todo_wine
+    CHECK_CALLED(BindStatusCallback_OnStopBinding);
+
+    ok(bind_callback_refs == 1, "Got unexpected refcount %d.\n", bind_callback_refs);
+    ok(browse_ctx_refs == 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
+
+    /* test asynchronous binding */
+    async_bind = TRUE;
+    SET_EXPECT(IsSystemMoniker);
+    SET_EXPECT(GetDisplayName);
+    SET_EXPECT(HBC_GetObject);
+    SET_EXPECT(Reduce);
+    SET_EXPECT(BindToObject);
+    hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
+    ok(hres == MK_S_ASYNCHRONOUS, "Navigate failed: %#x\n", hres);
+    CHECK_CALLED(IsSystemMoniker);
+    CHECK_CALLED(GetDisplayName);
+    CHECK_CALLED(HBC_GetObject);
+todo_wine
+    CHECK_CALLED(Reduce);
+    CHECK_CALLED(BindToObject);
+
+    ok(browse_ctx_refs > 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
+
+    hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
+    ok(hres == E_UNEXPECTED, "Got hr %#x.\n", hres);
+
+    hres = IBindStatusCallback_GetBindInfo(async_bind_callback, &bind_flags, &bind_info);
+    ok(hres == S_OK, "Got hr %#x.\n", hres);
+
+    hres = IBindStatusCallback_OnStartBinding(async_bind_callback, 0, NULL);
+    ok(hres == S_OK, "Got hr %#x.\n", hres);
+
+    SET_EXPECT(HT_QueryInterface_IHlinkTarget);
+    SET_EXPECT(HT_GetBrowseContext);
+    SET_EXPECT(HT_SetBrowseContext);
+    SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
+    SET_EXPECT(HT_Navigate);
+    SET_EXPECT(HT_GetFriendlyName);
+    hres = IBindStatusCallback_OnObjectAvailable(async_bind_callback, &IID_IUnknown,
+            (IUnknown *)&HlinkTarget);
+    ok(hres == S_OK, "Got hr %#x.\n", hres);
+    CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
+todo_wine
+    CHECK_CALLED(HT_GetBrowseContext);
+    CHECK_CALLED(HT_SetBrowseContext);
+todo_wine
+    CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
+    CHECK_CALLED(HT_Navigate);
+todo_wine
+    CHECK_CALLED(HT_GetFriendlyName);
+
+    hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
+    ok(hres == E_UNEXPECTED, "Got hr %#x.\n", hres);
+
+    ok(browse_ctx_refs > 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
+
+    hres = IBindStatusCallback_OnStopBinding(async_bind_callback, S_OK, NULL);
+    ok(hres == S_OK, "Got hr %#x.\n", hres);
+
+    ok(browse_ctx_refs == 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
+
+    IBindStatusCallback_Release(async_bind_callback);
+
+    SET_EXPECT(IsSystemMoniker);
+    SET_EXPECT(GetDisplayName);
+    SET_EXPECT(BindStatusCallback_GetBindInfo);
+    SET_EXPECT(HBC_GetObject);
+    SET_EXPECT(Reduce);
+    SET_EXPECT(BindToObject);
+    hres = IHlink_Navigate(hlink, 0, pbc, &BindStatusCallback, &HlinkBrowseContext);
+    ok(hres == MK_S_ASYNCHRONOUS, "Navigate failed: %#x\n", hres);
+    CHECK_CALLED(IsSystemMoniker);
+    CHECK_CALLED(GetDisplayName);
+todo_wine
+    CHECK_CALLED(BindStatusCallback_GetBindInfo);
+    CHECK_CALLED(HBC_GetObject);
+todo_wine
+    CHECK_CALLED(Reduce);
+    CHECK_CALLED(BindToObject);
+
+    ok(bind_callback_refs > 1, "Got unexpected refcount %d.\n", bind_callback_refs);
+    ok(browse_ctx_refs > 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
+
+    hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
+    ok(hres == E_UNEXPECTED, "Got hr %#x.\n", hres);
+
+    SET_EXPECT(BindStatusCallback_GetBindInfo);
+    hres = IBindStatusCallback_GetBindInfo(async_bind_callback, &bind_flags, &bind_info);
+    ok(hres == E_NOTIMPL, "Got hr %#x.\n", hres);
+    CHECK_CALLED(BindStatusCallback_GetBindInfo);
+
+    SET_EXPECT(BindStatusCallback_OnStartBinding);
+    hres = IBindStatusCallback_OnStartBinding(async_bind_callback, 0, NULL);
+    ok(hres == S_OK, "Got hr %#x.\n", hres);
+    CHECK_CALLED(BindStatusCallback_OnStartBinding);
+
+    SET_EXPECT(BindStatusCallback_OnObjectAvailable);
+    SET_EXPECT(HT_QueryInterface_IHlinkTarget);
+    SET_EXPECT(HT_GetBrowseContext);
+    SET_EXPECT(HT_SetBrowseContext);
+    SET_EXPECT(HBC_QueryInterface_IHlinkHistory);
+    SET_EXPECT(HT_Navigate);
+    SET_EXPECT(HT_GetFriendlyName);
+    hres = IBindStatusCallback_OnObjectAvailable(async_bind_callback, &IID_IUnknown,
+            (IUnknown *)&HlinkTarget);
+    ok(hres == S_OK, "Got hr %#x.\n", hres);
+    CHECK_CALLED(BindStatusCallback_OnObjectAvailable);
+    CHECK_CALLED(HT_QueryInterface_IHlinkTarget);
+todo_wine
+    CHECK_CALLED(HT_GetBrowseContext);
+    CHECK_CALLED(HT_SetBrowseContext);
+todo_wine
+    CHECK_CALLED(HBC_QueryInterface_IHlinkHistory);
+    CHECK_CALLED(HT_Navigate);
+todo_wine
+    CHECK_CALLED(HT_GetFriendlyName);
+
+    hres = IHlink_Navigate(hlink, 0, pbc, NULL, &HlinkBrowseContext);
+    ok(hres == E_UNEXPECTED, "Got hr %#x.\n", hres);
+
+    ok(bind_callback_refs > 1, "Got unexpected refcount %d.\n", bind_callback_refs);
+    ok(browse_ctx_refs > 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
+
+    SET_EXPECT(BindStatusCallback_OnStopBinding);
+    hres = IBindStatusCallback_OnStopBinding(async_bind_callback, S_OK, NULL);
+    ok(hres == S_OK, "Got hr %#x.\n", hres);
+    CHECK_CALLED(BindStatusCallback_OnStopBinding);
+
+    ok(bind_callback_refs == 1, "Got unexpected refcount %d.\n", bind_callback_refs);
+    ok(browse_ctx_refs == 1, "Got unexpected refcount %d.\n", browse_ctx_refs);
+
+    IBindStatusCallback_Release(async_bind_callback);
+
     IHlink_Release(hlink);
     IBindCtx_Release(pbc);
     _bctx = NULL;