From: Gabriel Ivăncescu gabrielopcode@gmail.com
Native ignores any cNames > 1 and doesn't even fill the dispids for them. Note that it was already wrong; the multiple dispids are supposed to correspond to the member's argument names, not extra dispids.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 13 ++-- dlls/mshtml/htmlwindow.c | 12 ++-- dlls/mshtml/tests/dom.c | 101 +++++++++++++++++++++++++++++ dlls/mshtml/tests/xmlhttprequest.c | 31 +++++++++ 4 files changed, 142 insertions(+), 15 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index d8aaf819f58..c70deb67209 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1636,19 +1636,16 @@ static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, LCID lcid, DISPID *rgDispId) { DispatchEx *This = impl_from_IDispatchEx(iface); - UINT i; - HRESULT hres; + HRESULT hres = S_OK;
TRACE("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
- for(i=0; i < cNames; i++) { - hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i); - if(FAILED(hres)) - return hres; - } + /* Native ignores all cNames > 1, and doesn't even fill them */ + if(cNames) + hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[0], 0, rgDispId);
- return S_OK; + return hres; }
static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 7014a4cd4b4..c2475afd1f6 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3476,19 +3476,17 @@ static HRESULT WINAPI WindowDispEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid LCID lcid, DISPID *rgDispId) { HTMLWindow *This = impl_from_IDispatchEx(iface); - UINT i; - HRESULT hres; + HRESULT hres = S_OK;
WARN("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
- for(i=0; i < cNames; i++) { + /* Native ignores all cNames > 1, and doesn't even fill them */ + if(cNames) { /* We shouldn't use script's IDispatchEx here, so we shouldn't use GetDispID */ - hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i); - if(FAILED(hres)) - return hres; + hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[0], 0, rgDispId); }
- return S_OK; + return hres; }
static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index bb69e3504ea..58a4f127399 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -27,6 +27,7 @@ #include "ole2.h" #include "mshtml.h" #include "mshtmcid.h" +#include "mshtmdid.h" #include "mshtmhst.h" #include "docobj.h" #include "hlink.h" @@ -5301,6 +5302,98 @@ static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const WCHAR SysFreeString(tmp); }
+static void test_doc_GetIDsOfNames(IHTMLDocument2 *doc) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + bstr[0] = SysAllocString(L"createStyleSheet"); + bstr[1] = SysAllocString(L"bstrHref"); + bstr[2] = SysAllocString(L"lIndex"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLDOCUMENT2_CREATESTYLESHEET, "createStyleSheet dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "bstrHref dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "lIndex dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); +} + +static void test_window_GetIDsOfNames(IHTMLWindow2 *window) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + bstr[0] = SysAllocString(L"showHelp"); + bstr[1] = SysAllocString(L"helpURL"); + bstr[2] = SysAllocString(L"helpArg"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLWindow2_GetIDsOfNames(window, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLWINDOW2_SHOWHELP, "showHelp dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "helpURL dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "helpArg dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); +} + +static void test_elem_GetIDsOfNames(IHTMLElement *elem) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + /* IE9+ use something like js proxies even on native and have different dispids */ + if(compat_mode >= COMPAT_IE9) + return; + + bstr[0] = SysAllocString(L"insertAdjacentText"); + bstr[1] = SysAllocString(L"where"); + bstr[2] = SysAllocString(L"text"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLElement_GetIDsOfNames(elem, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLELEMENT_INSERTADJACENTTEXT, "insertAdjacentText dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "where dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "text dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); +} + +static void test_attr_GetIDsOfNames(IHTMLDOMAttribute *attr) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + bstr[0] = SysAllocString(L"insertBefore"); + bstr[1] = SysAllocString(L"newChild"); + bstr[2] = SysAllocString(L"refChild"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLDOMAttribute_GetIDsOfNames(attr, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLDOMATTRIBUTE2_INSERTBEFORE, "insertBefore dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "newChild dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "refChild dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); +} + static void test_elem_bounding_client_rect(IUnknown *unk) { IHTMLRectCollection *rects; @@ -5475,6 +5568,7 @@ static IHTMLElement *get_elem_by_id(IHTMLDocument2 *doc, const WCHAR *id, BOOL e elem = get_elem_iface((IUnknown*)disp); IDispatch_Release(disp);
+ test_elem_GetIDsOfNames(elem); return elem; }
@@ -5495,6 +5589,8 @@ static IHTMLElement *get_doc_elem_by_id(IHTMLDocument2 *doc, const WCHAR *id)
IHTMLDocument3_Release(doc3);
+ if(elem) + test_elem_GetIDsOfNames(elem); return elem; }
@@ -6867,6 +6963,8 @@ static void test_doc_elem(IHTMLDocument2 *doc) HRESULT hres; BSTR bstr;
+ test_doc_GetIDsOfNames(doc); + hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3); ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08lx\n", hres);
@@ -6888,6 +6986,7 @@ static void test_doc_elem(IHTMLDocument2 *doc) owner_doc = get_owner_doc((IUnknown*)elem); ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n"); IHTMLDocument2_Release(owner_doc); + test_doc_GetIDsOfNames(doc_node);
owner_doc = get_owner_doc((IUnknown*)doc_node); ok(!owner_doc, "owner_doc = %p\n", owner_doc); @@ -7171,6 +7270,7 @@ static void test_window(IHTMLDocument2 *doc) win_skip("IID_ITravelLogClient not supported\n");
test_disp((IUnknown*)window, &DIID_DispHTMLWindow2, &CLSID_HTMLWindow2, L"[object]"); + test_window_GetIDsOfNames(window);
hres = IHTMLWindow2_get_document(window, &doc2); ok(hres == S_OK, "get_document failed: %08lx\n", hres); @@ -9809,6 +9909,7 @@ static void test_attr(IHTMLDocument2 *doc, IHTMLElement *elem) test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode); test_attr_specified(attr, VARIANT_TRUE); test_attr_parent(attr); + test_attr_GetIDsOfNames(attr);
attr2 = get_elem_attr_node((IUnknown*)elem, L"id", TRUE); ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n"); diff --git a/dlls/mshtml/tests/xmlhttprequest.c b/dlls/mshtml/tests/xmlhttprequest.c index 6aef9f5a35d..a3ec54ffef6 100644 --- a/dlls/mshtml/tests/xmlhttprequest.c +++ b/dlls/mshtml/tests/xmlhttprequest.c @@ -25,6 +25,7 @@ #include "winbase.h" #include "ole2.h" #include "mshtml.h" +#include "mshtmdid.h" #include "objsafe.h" #include "wine/test.h"
@@ -402,6 +403,35 @@ static void create_xmlhttprequest(IHTMLDocument2 *doc) ok(xhr != NULL, "xhr == NULL\n"); }
+static void test_GetIDsOfNames(IHTMLDocument2 *doc) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + create_xmlhttprequest(doc); + if(!xhr) + return; + + bstr[0] = SysAllocString(L"open"); + bstr[1] = SysAllocString(L"bstrMethod"); + bstr[2] = SysAllocString(L"varAsync"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLXMLHttpRequest_GetIDsOfNames(xhr, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLXMLHTTPREQUEST_OPEN, "open dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "bstrMethod dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "varAsync dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); + + IHTMLXMLHttpRequest_Release(xhr); + xhr = NULL; +} + static void test_header(const struct HEADER_TYPE expect[], int num) { int i; @@ -1100,6 +1130,7 @@ START_TEST(xmlhttprequest) content_type = SysAllocString(L"Content-Type"); doc = create_doc_from_url(start_url); if(doc) { + test_GetIDsOfNames(doc); test_sync_xhr(doc, xml_url, expect_response_text); test_sync_xhr(doc, large_page_url, NULL); test_async_xhr(doc, xml_url, expect_response_text);