From: Nikolay Sivov Subject: [v2 PATCH] urlmon/uri: Implement IsEqual for external implementations. Message-Id: <20180918094409.28005-1-nsivov@codeweavers.com> Date: Tue, 18 Sep 2018 12:44:09 +0300 Signed-off-by: Nikolay Sivov --- v2: now with urlmon tests. dlls/opcservices/tests/opcservices.c | 3 +- dlls/urlmon/tests/uri.c | 240 +++++++++++++++++++++++++++ dlls/urlmon/uri.c | 18 +- 3 files changed, 257 insertions(+), 4 deletions(-) diff --git a/dlls/opcservices/tests/opcservices.c b/dlls/opcservices/tests/opcservices.c index 936e2c751d..cfd11491ee 100644 --- a/dlls/opcservices/tests/opcservices.c +++ b/dlls/opcservices/tests/opcservices.c @@ -531,10 +531,9 @@ static void test_rel_part_uri(void) ok(SUCCEEDED(hr), "Failed to get source uri, hr %#x.\n", hr); ok(source_uri != source_uri2, "Unexpected instance.\n"); hr = IOpcUri_IsEqual(source_uri, (IUri *)source_uri2, &ret); - todo_wine { ok(SUCCEEDED(hr), "IsEqual failed, hr %#x.\n", hr); ok(ret, "Expected equal uris.\n"); - } + hr = IOpcUri_QueryInterface(source_uri, &IID_IOpcPartUri, (void **)&unk); ok(hr == (is_root ? E_NOINTERFACE : S_OK), "Unexpected hr %#x, %s.\n", hr, rel_part_uri_tests[i].uri); if (unk) diff --git a/dlls/urlmon/tests/uri.c b/dlls/urlmon/tests/uri.c index 7580a1302d..2af3a29458 100644 --- a/dlls/urlmon/tests/uri.c +++ b/dlls/urlmon/tests/uri.c @@ -8515,7 +8515,225 @@ static void test_IUri_HasProperty(void) { } } +struct custom_uri { + IUri IUri_iface; + IUri *uri; +}; + +static inline struct custom_uri* impl_from_IUri(IUri *iface) +{ + return CONTAINING_RECORD(iface, struct custom_uri, IUri_iface); +} + +static HRESULT WINAPI custom_uri_QueryInterface(IUri *iface, REFIID iid, void **out) +{ + if (IsEqualIID(iid, &IID_IUri) || IsEqualIID(iid, &IID_IUnknown)) + { + *out = iface; + IUri_AddRef(iface); + return S_OK; + } + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI custom_uri_AddRef(IUri *iface) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_AddRef(uri->uri); +} + +static ULONG WINAPI custom_uri_Release(IUri *iface) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_Release(uri->uri); +} + +static HRESULT WINAPI custom_uri_GetPropertyBSTR(IUri *iface, Uri_PROPERTY property, BSTR *value, DWORD flags) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetPropertyBSTR(uri->uri, property, value, flags); +} + +static HRESULT WINAPI custom_uri_GetPropertyLength(IUri *iface, Uri_PROPERTY property, DWORD *length, DWORD flags) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetPropertyLength(uri->uri, property, length, flags); +} + +static HRESULT WINAPI custom_uri_GetPropertyDWORD(IUri *iface, Uri_PROPERTY property, DWORD *value, DWORD flags) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetPropertyDWORD(uri->uri, property, value, flags); +} + +static HRESULT WINAPI custom_uri_HasProperty(IUri *iface, Uri_PROPERTY property, BOOL *has_property) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_HasProperty(uri->uri, property, has_property); +} + +static HRESULT WINAPI custom_uri_GetAbsoluteUri(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetAuthority(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetDisplayUri(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetDomain(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetExtension(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetFragment(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetHost(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetPassword(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetPath(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetPathAndQuery(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetQuery(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetRawUri(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetAbsoluteUri(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetSchemeName(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetSchemeName(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetUserInfo(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetUserInfo(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetUserName(IUri *iface, BSTR *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetUserName(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetHostType(IUri *iface, DWORD *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetHostType(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetPort(IUri *iface, DWORD *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetPort(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetScheme(IUri *iface, DWORD *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetScheme(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetZone(IUri *iface, DWORD *value) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetZone(uri->uri, value); +} + +static HRESULT WINAPI custom_uri_GetProperties(IUri *iface, DWORD *flags) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_GetProperties(uri->uri, flags); +} + +static HRESULT WINAPI custom_uri_IsEqual(IUri *iface, IUri *pUri, BOOL *is_equal) +{ + struct custom_uri *uri = impl_from_IUri(iface); + return IUri_IsEqual(uri->uri, pUri, is_equal); +} + +static const IUriVtbl custom_uri_vtbl = +{ + custom_uri_QueryInterface, + custom_uri_AddRef, + custom_uri_Release, + custom_uri_GetPropertyBSTR, + custom_uri_GetPropertyLength, + custom_uri_GetPropertyDWORD, + custom_uri_HasProperty, + custom_uri_GetAbsoluteUri, + custom_uri_GetAuthority, + custom_uri_GetDisplayUri, + custom_uri_GetDomain, + custom_uri_GetExtension, + custom_uri_GetFragment, + custom_uri_GetHost, + custom_uri_GetPassword, + custom_uri_GetPath, + custom_uri_GetPathAndQuery, + custom_uri_GetQuery, + custom_uri_GetRawUri, + custom_uri_GetSchemeName, + custom_uri_GetUserInfo, + custom_uri_GetUserName, + custom_uri_GetHostType, + custom_uri_GetPort, + custom_uri_GetScheme, + custom_uri_GetZone, + custom_uri_GetProperties, + custom_uri_IsEqual, +}; + static void test_IUri_IsEqual(void) { + struct custom_uri custom_uri; IUri *uriA, *uriB; BOOL equal; HRESULT hres; @@ -8537,9 +8755,21 @@ static void test_IUri_IsEqual(void) { hres = IUri_IsEqual(uriA, uriB, NULL); ok(hres == E_POINTER, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hres, E_POINTER); + equal = FALSE; + hres = IUri_IsEqual(uriA, uriA, &equal); + ok(hres == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hres, S_OK); + ok(equal, "Error: Expected equal URIs.\n"); + + equal = FALSE; + hres = IUri_IsEqual(uriA, uriB, &equal); + ok(hres == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hres, S_OK); + ok(equal, "Error: Expected equal URIs.\n"); + IUri_Release(uriA); IUri_Release(uriB); + custom_uri.IUri_iface.lpVtbl = &custom_uri_vtbl; + for(i = 0; i < ARRAY_SIZE(equality_tests); ++i) { uri_equality test = equality_tests[i]; LPWSTR uriA_W, uriB_W; @@ -8561,6 +8791,16 @@ static void test_IUri_IsEqual(void) { ok(hres == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n", hres, S_OK, i); ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i); } + + custom_uri.uri = uriB; + + equal = -1; + hres = IUri_IsEqual(uriA, &custom_uri.IUri_iface, &equal); + todo_wine_if(test.todo) { + ok(hres == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n", hres, S_OK, i); + ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i); + } + if(uriA) IUri_Release(uriA); if(uriB) IUri_Release(uriB); diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c index 92978dc53f..20a7c1a5f3 100644 --- a/dlls/urlmon/uri.c +++ b/dlls/urlmon/uri.c @@ -5017,8 +5017,22 @@ static HRESULT WINAPI Uri_IsEqual(IUri *iface, IUri *pUri, BOOL *pfEqual) /* Try to convert it to a Uri (allows for a more simple comparison). */ if(!(other = get_uri_obj(pUri))) { - FIXME("(%p)->(%p %p) No support for unknown IUri's yet.\n", iface, pUri, pfEqual); - return E_NOTIMPL; + IUri *other_uri; + HRESULT hr; + BSTR raw; + + hr = IUri_GetRawUri(pUri, &raw); + if (FAILED(hr)) + return hr; + + hr = CreateUri(raw, Uri_CREATE_ALLOW_RELATIVE, 0, &other_uri); + SysFreeString(raw); + if (FAILED(hr)) + return hr; + + hr = Uri_IsEqual(iface, other_uri, pfEqual); + IUri_Release(other_uri); + return hr; } TRACE("comparing to %s\n", debugstr_w(other->canon_uri)); -- 2.18.0