From: Alexandre Abgrall aabgrall98@gmail.com
It must be the number of elements returned in 'var', as specified here: https://docs.microsoft.com/en-us/windows/win32/api/oaidl/nf-oaidl-ienumvaria...
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=40430 Signed-off-by: Alexandre Abgrall aabgrall98@gmail.com Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/msxml3/selection.c | 2 +- dlls/msxml3/tests/domdoc.c | 104 +++++++++++++++++++++++++++++++------ 2 files changed, 90 insertions(+), 16 deletions(-)
diff --git a/dlls/msxml3/selection.c b/dlls/msxml3/selection.c index 31be4d8f10..3698d036d4 100644 --- a/dlls/msxml3/selection.c +++ b/dlls/msxml3/selection.c @@ -519,7 +519,7 @@ static HRESULT WINAPI enumvariant_Next( ret_count++; }
- if (fetched) (*fetched)++; + if (fetched) *fetched = ret_count;
/* we need to advance one step more for some reason */ if (ret_count) diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 7f3b42d840..8c605573ad 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -9976,9 +9976,9 @@ static void test_selection(void) IXMLDOMNode *node; IDispatch *disp; VARIANT_BOOL b; + VARIANT v[3]; HRESULT hr; DISPID did; - VARIANT v; BSTR name; ULONG ret; LONG len; @@ -10148,33 +10148,32 @@ static void test_selection(void) EXPECT_HR(hr, S_OK);
/* no-op if zero count */ - V_VT(&v) = VT_I2; - hr = IEnumVARIANT_Next(enum1, 0, &v, NULL); + V_VT(&v[0]) = VT_I2; + hr = IEnumVARIANT_Next(enum1, 0, &v[0], NULL); EXPECT_HR(hr, S_OK); - ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v)); + ok(V_VT(&v[0]) == VT_I2, "got var type %d\n", V_VT(&v[0]));
/* positive count, null array pointer */ hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL); EXPECT_HR(hr, E_INVALIDARG);
- ret = 1; hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret); EXPECT_HR(hr, E_INVALIDARG); ok(ret == 0, "got %d\n", ret);
- V_VT(&v) = VT_I2; - hr = IEnumVARIANT_Next(enum1, 1, &v, NULL); + V_VT(&v[0]) = VT_I2; + hr = IEnumVARIANT_Next(enum1, 1, &v[0], NULL); EXPECT_HR(hr, S_OK); - ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v)); + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0]));
- hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); EXPECT_HR(hr, S_OK); hr = IXMLDOMNode_get_nodeName(node, &name); EXPECT_HR(hr, S_OK); ok(!lstrcmpW(name, L"a"), "got node name %s\n", wine_dbgstr_w(name)); SysFreeString(name); IXMLDOMNode_Release(node); - VariantClear(&v); + VariantClear(&v[0]);
/* list cursor is updated */ hr = IXMLDOMSelection_nextNode(selection, &node); @@ -10185,18 +10184,18 @@ static void test_selection(void) IXMLDOMNode_Release(node); SysFreeString(name);
- V_VT(&v) = VT_I2; - hr = IEnumVARIANT_Next(enum1, 1, &v, NULL); + V_VT(&v[0]) = VT_I2; + hr = IEnumVARIANT_Next(enum1, 1, &v[0], NULL); EXPECT_HR(hr, S_OK); - ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v)); - hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node); + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0])); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); EXPECT_HR(hr, S_OK); hr = IXMLDOMNode_get_nodeName(node, &name); EXPECT_HR(hr, S_OK); ok(!lstrcmpW(name, L"b"), "got node name %s\n", wine_dbgstr_w(name)); SysFreeString(name); IXMLDOMNode_Release(node); - VariantClear(&v); + VariantClear(&v[0]); IEnumVARIANT_Release(enum1);
hr = IXMLDOMSelection_nextNode(selection, &node); @@ -10207,6 +10206,81 @@ static void test_selection(void) IXMLDOMNode_Release(node); SysFreeString(name);
+ /* getting multiple elements */ + enum1 = NULL; + hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1); + EXPECT_HR(hr, S_OK); + ok(enum1 != NULL, "got %p\n", enum1); + + V_VT(&v[1]) = VT_EMPTY; + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enum1, 2, v, &ret); + EXPECT_HR(hr, S_OK); + ok(ret == 2, "got %d, expected 2\n", ret); + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0])); + ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1])); + + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &name); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(name, L"a"), "got node name %s\n", wine_dbgstr_w(name)); + SysFreeString(name); + IXMLDOMNode_Release(node); + + hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &name); + ok(!lstrcmpW(name, L"b"), "got node name %s\n", wine_dbgstr_w(name)); + SysFreeString(name); + IXMLDOMNode_Release(node); + + VariantClear(&v[1]); + VariantClear(&v[0]); + + /* IEnumVARIANT_Next makes the IXMLDOMSelection cursor advance one step more */ + hr = IXMLDOMSelection_nextNode(selection, &node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &name); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(name, L"d"), "got node name %s\n", wine_dbgstr_w(name)); + SysFreeString(name); + IXMLDOMNode_Release(node); + + /* The IEnumVARIANT cursor is still at position '2', */ + /* therefore attempting to fetch 4 elements yields 'c' and 'd' */ + V_VT(&v[2]) = VT_NULL; + V_VT(&v[1]) = VT_EMPTY; + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enum1, 4, &v[0], &ret); + EXPECT_HR(hr, S_FALSE); + ok(ret == 2, "got %d, expected 2\n", ret); + + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0])); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &name); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(name, L"c"), "got node name %s\n", wine_dbgstr_w(name)); + SysFreeString(name); + IXMLDOMNode_Release(node); + + ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1])); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &name); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(name, L"d"), "got node name %s\n", wine_dbgstr_w(name)); + SysFreeString(name); + IXMLDOMNode_Release(node); + + ok(V_VT(&v[2]) == VT_EMPTY, "got var type %d, expected %d (VT_EMPTY)\n", V_VT(&v[2]), VT_EMPTY); + + VariantClear(&v[1]); + VariantClear(&v[0]); + + IEnumVARIANT_Release(enum1); + IXMLDOMSelection_Release(selection); IXMLDOMNodeList_Release(list); IXMLDOMDocument_Release(doc);
Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/msxml3/tests/domdoc.c | 239 ++++++++++++++++++++++++++++++------- 1 file changed, 193 insertions(+), 46 deletions(-)
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 8c605573ad..53fd2927c1 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -3584,8 +3584,9 @@ static void test_get_childNodes(void) IXMLDOMNode *node, *node2; IXMLDOMElement *element; IUnknown *unk1, *unk2; + ULONG fetched; + VARIANT v[2]; HRESULT hr; - VARIANT v; BSTR str; LONG len;
@@ -3670,18 +3671,57 @@ static void test_get_childNodes(void) SysFreeString(str); IXMLDOMNode_Release(node);
- V_VT(&v) = VT_EMPTY; - hr = IEnumVARIANT_Next(enum1, 1, &v, NULL); + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enum1, 1, &v[0], NULL); EXPECT_HR(hr, S_OK); - ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v)); - hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node); + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0])); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); EXPECT_HR(hr, S_OK); hr = IXMLDOMNode_get_nodeName(node, &str); EXPECT_HR(hr, S_OK); ok(!lstrcmpW(str, L"bs"), "got node name %s\n", wine_dbgstr_w(str)); SysFreeString(str); IXMLDOMNode_Release(node); - VariantClear(&v); + VariantClear(&v[0]); + + V_VT(&v[1]) = VT_EMPTY; + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enum1, 2, v, &fetched); + EXPECT_HR(hr, S_OK); + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0])); + ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1])); + ok(fetched == 2, "got %d, expected 2\n", fetched); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, L"pr"), "got node name %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, L"empty"), "got node name %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + VariantClear(&v[1]); + VariantClear(&v[0]); + + V_VT(&v[1]) = VT_NULL; + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enum1, 2, v, &fetched); + EXPECT_HR(hr, S_FALSE); + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0])); + ok(V_VT(&v[1]) == VT_EMPTY, "got var type %d\n", V_VT(&v[1])); + ok(fetched == 1, "got %d, expected 1\n", fetched); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, L"fo"), "got node name %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + VariantClear(&v[0]);
hr = IXMLDOMNodeList_nextNode(node_list, &node); EXPECT_HR(hr, S_OK); @@ -11989,8 +12029,9 @@ static void test_get_namespaces(void) IUnknown *unk1, *unk2; IXMLDOMNode *node; VARIANT_BOOL b; + ULONG fetched; + VARIANT v[2]; HRESULT hr; - VARIANT v; LONG len; BSTR s;
@@ -12053,9 +12094,9 @@ static void test_get_namespaces(void) hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b); EXPECT_HR(hr, S_OK);
- V_VT(&v) = VT_DISPATCH; - V_DISPATCH(&v) = (IDispatch*)doc2; - hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v); + V_VT(&v[0]) = VT_DISPATCH; + V_DISPATCH(&v[0]) = (IDispatch*)doc2; + hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v[0]); EXPECT_HR(hr, E_FAIL);
hr = IXMLDOMSchemaCollection_get_namespaceURI(collection, 0, &s); @@ -12092,28 +12133,54 @@ static void test_get_namespaces(void) hr = IXMLDOMSchemaCollection_QueryInterface(collection, &IID_IEnumVARIANT, (void**)&enum2); EXPECT_HR(hr, E_NOINTERFACE);
- V_VT(&v) = VT_EMPTY; - hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enumv, 1, &v[0], NULL); EXPECT_HR(hr, S_OK); - ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); - ok(!lstrcmpW(V_BSTR(&v), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); - VariantClear(&v); + ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0])); + ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0]))); + VariantClear(&v[0]);
- V_VT(&v) = VT_EMPTY; - hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enumv, 1, &v[0], &fetched); EXPECT_HR(hr, S_OK); - ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); - ok(!lstrcmpW(V_BSTR(&v), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); - VariantClear(&v); + ok(fetched == 1, "got %d, expected 1\n", fetched); + ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0])); + ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0]))); + VariantClear(&v[0]);
- V_VT(&v) = VT_NULL; - hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); + V_VT(&v[0]) = VT_NULL; + hr = IEnumVARIANT_Next(enumv, 1, &v[0], &fetched); EXPECT_HR(hr, S_FALSE); - ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v)); + ok(fetched == 0, "got %d, expected 0\n", fetched); + ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0]));
IEnumVARIANT_Release(enumv); - IXMLDOMSchemaCollection_Release(collection);
+ enumv = (void*)0xdeadbeef; + hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv); + EXPECT_HR(hr, S_OK); + ok(enumv != NULL, "got %p\n", enumv); + + V_VT(&v[1]) = VT_EMPTY; + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enumv, 2, v, &fetched); + EXPECT_HR(hr, S_OK); + ok(fetched == 2, "got %d, expected 2\n", fetched); + ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0])); + ok(V_VT(&v[1]) == VT_BSTR, "got %d\n", V_VT(&v[1])); + ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0]))); + ok(!lstrcmpW(V_BSTR(&v[1]), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[1]))); + VariantClear(&v[1]); + VariantClear(&v[0]); + + V_VT(&v[0]) = VT_NULL; + hr = IEnumVARIANT_Next(enumv, 1, v, &fetched); + EXPECT_HR(hr, S_FALSE); + ok(fetched == 0, "got %d, expected 0\n", fetched); + ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0])); + + IEnumVARIANT_Release(enumv); + IXMLDOMSchemaCollection_Release(collection); IXMLDOMDocument2_Release(doc);
/* now with CLSID_DOMDocument60 */ @@ -12171,9 +12238,9 @@ static void test_get_namespaces(void) hr = IXMLDOMDocument2_loadXML(doc2, _bstr_(xsd_schema1_xml), &b); EXPECT_HR(hr, S_OK);
- V_VT(&v) = VT_DISPATCH; - V_DISPATCH(&v) = (IDispatch*)doc2; - hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v); + V_VT(&v[0]) = VT_DISPATCH; + V_DISPATCH(&v[0]) = (IDispatch*)doc2; + hr = IXMLDOMSchemaCollection_add(collection, _bstr_(xsd_schema1_uri), v[0]); EXPECT_HR(hr, E_FAIL); IXMLDOMDocument2_Release(doc2);
@@ -12198,24 +12265,49 @@ static void test_get_namespaces(void) EXPECT_HR(hr, S_OK); ok(enumv != NULL, "got %p\n", enumv);
- V_VT(&v) = VT_EMPTY; - hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enumv, 1, &v[0], NULL); EXPECT_HR(hr, S_OK); - ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); - ok(!lstrcmpW(V_BSTR(&v), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); - VariantClear(&v); + ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0])); + ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0]))); + VariantClear(&v[0]);
- V_VT(&v) = VT_EMPTY; - hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enumv, 1, &v[0], NULL); EXPECT_HR(hr, S_OK); - ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); - ok(!lstrcmpW(V_BSTR(&v), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); - VariantClear(&v); + ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0])); + ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0]))); + VariantClear(&v[0]);
- V_VT(&v) = VT_NULL; - hr = IEnumVARIANT_Next(enumv, 1, &v, NULL); + V_VT(&v[0]) = VT_NULL; + hr = IEnumVARIANT_Next(enumv, 1, &v[0], NULL); EXPECT_HR(hr, S_FALSE); - ok(V_VT(&v) == VT_EMPTY, "got %d\n", V_VT(&v)); + ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0])); + + IEnumVARIANT_Release(enumv); + + enumv = (void*)0xdeadbeef; + hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv); + EXPECT_HR(hr, S_OK); + ok(enumv != NULL, "got %p\n", enumv); + + V_VT(&v[1]) = VT_EMPTY; + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enumv, 2, v, &fetched); + EXPECT_HR(hr, S_OK); + ok(fetched == 2, "got %d, expected 2\n", fetched); + ok(V_VT(&v[0]) == VT_BSTR, "got %d\n", V_VT(&v[0])); + ok(V_VT(&v[1]) == VT_BSTR, "got %d\n", V_VT(&v[1])); + ok(!lstrcmpW(V_BSTR(&v[0]), L"http://blah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0]))); + ok(!lstrcmpW(V_BSTR(&v[1]), L"http://blahblah.org"), "got %s\n", wine_dbgstr_w(V_BSTR(&v[0]))); + VariantClear(&v[1]); + VariantClear(&v[0]); + + V_VT(&v[0]) = VT_NULL; + hr = IEnumVARIANT_Next(enumv, 1, v, &fetched); + EXPECT_HR(hr, S_FALSE); + ok(fetched == 0, "got %d, expected 0\n", fetched); + ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0]));
IEnumVARIANT_Release(enumv); IXMLDOMSchemaCollection_Release(collection); @@ -12561,8 +12653,9 @@ static void test_namedmap_newenum(void) IXMLDOMElement *elem; IXMLDOMNode *node; VARIANT_BOOL b; + ULONG fetched; + VARIANT v[3]; HRESULT hr; - VARIANT v; BSTR str;
doc = create_document(&IID_IXMLDOMDocument); @@ -12634,18 +12727,18 @@ static void test_namedmap_newenum(void) SysFreeString(str); IXMLDOMNode_Release(node);
- V_VT(&v) = VT_EMPTY; - hr = IEnumVARIANT_Next(enum2, 1, &v, NULL); + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enum2, 1, &v[0], NULL); EXPECT_HR(hr, S_OK); - ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v)); - hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node); + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0])); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); EXPECT_HR(hr, S_OK); hr = IXMLDOMNode_get_nodeName(node, &str); EXPECT_HR(hr, S_OK); ok(!lstrcmpW(str, L"attr1"), "got node name %s\n", wine_dbgstr_w(str)); SysFreeString(str); IXMLDOMNode_Release(node); - VariantClear(&v); + VariantClear(&v[0]);
hr = IXMLDOMNamedNodeMap_nextNode(map, &node); EXPECT_HR(hr, S_OK); @@ -12654,8 +12747,62 @@ static void test_namedmap_newenum(void) ok(!lstrcmpW(str, L"attr2"), "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); IXMLDOMNode_Release(node); + IEnumVARIANT_Release(enum2);
+ hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum2); + EXPECT_HR(hr, S_OK); + + V_VT(&v[1]) = VT_EMPTY; + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enum2, 2, v, &fetched); + EXPECT_HR(hr, S_OK); + ok(fetched == 2, "got %d, expected 2\n", fetched); + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0])); + ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1])); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, L"attr1"), "got node name %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, L"attr2"), "got node name %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + VariantClear(&v[1]); + VariantClear(&v[0]); + + V_VT(&v[2]) = VT_NULL; + V_VT(&v[1]) = VT_EMPTY; + V_VT(&v[0]) = VT_EMPTY; + hr = IEnumVARIANT_Next(enum2, 3, v, &fetched); + EXPECT_HR(hr, S_FALSE); + ok(fetched == 2, "got %d, expected 2\n", fetched); + ok(V_VT(&v[0]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[0])); + ok(V_VT(&v[1]) == VT_DISPATCH, "got var type %d\n", V_VT(&v[1])); + ok(V_VT(&v[2]) == VT_EMPTY, "got var type %d\n", V_VT(&v[2])); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[0]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, L"attr3"), "got node name %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + hr = IDispatch_QueryInterface(V_DISPATCH(&v[1]), &IID_IXMLDOMNode, (void**)&node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, L"attr4"), "got node name %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + VariantClear(&v[1]); + VariantClear(&v[0]); IEnumVARIANT_Release(enum2); + IXMLDOMNamedNodeMap_Release(map); IXMLDOMDocument_Release(doc); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=78624
Your paranoid android.
=== debiant (32 bit French report) ===
Report validation errors: msxml3:domdoc crashed (c0000005)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/msxml3/selection.c | 6 ++++-- dlls/msxml3/tests/domdoc.c | 22 +++++----------------- 2 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/dlls/msxml3/selection.c b/dlls/msxml3/selection.c index 3698d036d4..ede80627d7 100644 --- a/dlls/msxml3/selection.c +++ b/dlls/msxml3/selection.c @@ -543,8 +543,10 @@ static HRESULT WINAPI enumvariant_Skip( static HRESULT WINAPI enumvariant_Reset(IEnumVARIANT *iface) { enumvariant *This = impl_from_IEnumVARIANT( iface ); - FIXME("(%p): stub\n", This); - return E_NOTIMPL; + + TRACE("%p\n", This); + This->pos = 0; + return S_OK; }
static HRESULT WINAPI enumvariant_Clone( diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 53fd2927c1..1ff9643d96 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -10236,7 +10236,6 @@ static void test_selection(void) SysFreeString(name); IXMLDOMNode_Release(node); VariantClear(&v[0]); - IEnumVARIANT_Release(enum1);
hr = IXMLDOMSelection_nextNode(selection, &node); EXPECT_HR(hr, S_OK); @@ -10246,12 +10245,10 @@ static void test_selection(void) IXMLDOMNode_Release(node); SysFreeString(name);
- /* getting multiple elements */ - enum1 = NULL; - hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1); + hr = IEnumVARIANT_Reset(enum1); EXPECT_HR(hr, S_OK); - ok(enum1 != NULL, "got %p\n", enum1);
+ /* getting multiple elements */ V_VT(&v[1]) = VT_EMPTY; V_VT(&v[0]) = VT_EMPTY; hr = IEnumVARIANT_Next(enum1, 2, v, &ret); @@ -12154,12 +12151,8 @@ static void test_get_namespaces(void) ok(fetched == 0, "got %d, expected 0\n", fetched); ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0]));
- IEnumVARIANT_Release(enumv); - - enumv = (void*)0xdeadbeef; - hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv); + hr = IEnumVARIANT_Reset(enumv); EXPECT_HR(hr, S_OK); - ok(enumv != NULL, "got %p\n", enumv);
V_VT(&v[1]) = VT_EMPTY; V_VT(&v[0]) = VT_EMPTY; @@ -12284,12 +12277,8 @@ static void test_get_namespaces(void) EXPECT_HR(hr, S_FALSE); ok(V_VT(&v[0]) == VT_EMPTY, "got %d\n", V_VT(&v[0]));
- IEnumVARIANT_Release(enumv); - - enumv = (void*)0xdeadbeef; - hr = IXMLDOMSchemaCollection_get__newEnum(collection, (IUnknown**)&enumv); + hr = IEnumVARIANT_Reset(enumv); EXPECT_HR(hr, S_OK); - ok(enumv != NULL, "got %p\n", enumv);
V_VT(&v[1]) = VT_EMPTY; V_VT(&v[0]) = VT_EMPTY; @@ -12747,9 +12736,8 @@ static void test_namedmap_newenum(void) ok(!lstrcmpW(str, L"attr2"), "got %s\n", wine_dbgstr_w(str)); SysFreeString(str); IXMLDOMNode_Release(node); - IEnumVARIANT_Release(enum2);
- hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum2); + hr = IEnumVARIANT_Reset(enum2); EXPECT_HR(hr, S_OK);
V_VT(&v[1]) = VT_EMPTY;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=78625
Your paranoid android.
=== debiant (32 bit French report) ===
Report validation errors: msxml3:domdoc crashed (c0000005)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/msxml3/tests/xmldoc.c | 51 +++++++++++++++++++++++++++++++------- dlls/msxml3/xmlelem.c | 24 ++++++++++-------- 2 files changed, 56 insertions(+), 19 deletions(-)
diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c index 693af19571..8854e0e2fa 100644 --- a/dlls/msxml3/tests/xmldoc.c +++ b/dlls/msxml3/tests/xmldoc.c @@ -656,7 +656,7 @@ static void test_xmlelem_collection(void) WCHAR path[MAX_PATH]; LONG length, type; ULONG num_vars; - VARIANT var, dummy, vIndex, vName; + VARIANT var[3], dummy, vIndex, vName; BSTR url, str; static const CHAR szBankXML[] = "bank.xml"; static const WCHAR szNumber[] = {'N','U','M','B','E','R',0}; @@ -738,16 +738,16 @@ static void test_xmlelem_collection(void) IUnknown_Release(unk);
/* <Number>1234</Number> */ - hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars); + hr = IEnumVARIANT_Next(enumVar, 1, &var[0], &num_vars); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); - ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var)); + ok(V_VT(&var[0]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[0])); ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
- hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child); + hr = IDispatch_QueryInterface(V_DISPATCH(&var[0]), &IID_IXMLElement, (LPVOID *)&child); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(child != NULL, "Expected non-NULL child\n");
- VariantClear(&var); + VariantClear(&var[0]);
hr = IXMLElement_get_type(child, &type); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); @@ -760,11 +760,13 @@ static void test_xmlelem_collection(void) IXMLElement_Release(child);
/* <Name>Captain Ahab</Name> */ - hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars); + hr = IEnumVARIANT_Next(enumVar, 1, &var[0], &num_vars); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); - ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var)); + ok(V_VT(&var[0]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[0])); ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
+ VariantClear(&var[0]); + /* try advance further, no children left */ V_VT(&dummy) = VT_I4; hr = IEnumVARIANT_Next(enumVar, 1, &dummy, &num_vars); @@ -777,11 +779,42 @@ static void test_xmlelem_collection(void) ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr); ok(V_VT(&dummy) == VT_EMPTY, "Expected 0, got %d\n", V_VT(&dummy));
- hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child); + hr = IEnumVARIANT_Reset(enumVar); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + + /* retrieve multiple elements */ + hr = IEnumVARIANT_Next(enumVar, 2, var, &num_vars); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(V_VT(&var[0]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[0])); + ok(V_VT(&var[1]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[1])); + ok(num_vars == 2, "Expected 2, got %d\n", num_vars); + + V_VT(&dummy) = VT_I4; + hr = IEnumVARIANT_Next(enumVar, 1, &dummy, &num_vars); + ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr); + ok(V_VT(&dummy) == VT_EMPTY, "Expected 0, got %d\n", V_VT(&dummy)); + ok(num_vars == 0, "Expected 0, got %d\n", num_vars); + + hr = IEnumVARIANT_Reset(enumVar); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + + VariantClear(&var[1]); + VariantClear(&var[0]); + + /* request more elements than available */ + hr = IEnumVARIANT_Next(enumVar, 3, var, &num_vars); + ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr); + ok(V_VT(&var[0]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[0])); + ok(V_VT(&var[1]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[1])); + ok(V_VT(&var[2]) == VT_EMPTY, "Expected 0, got %d\n", V_VT(&var[2])); + ok(num_vars == 2, "Expected 2, got %d\n", num_vars); + + hr = IDispatch_QueryInterface(V_DISPATCH(&var[1]), &IID_IXMLElement, (LPVOID *)&child); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(child != NULL, "Expected non-NULL child\n");
- VariantClear(&var); + VariantClear(&var[1]); + VariantClear(&var[0]);
hr = IXMLElement_get_type(child, &type); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); diff --git a/dlls/msxml3/xmlelem.c b/dlls/msxml3/xmlelem.c index 96b2007ce3..3addcbd19b 100644 --- a/dlls/msxml3/xmlelem.c +++ b/dlls/msxml3/xmlelem.c @@ -753,28 +753,32 @@ static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next( IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *fetched) { xmlelem_collection *This = impl_from_IEnumVARIANT(iface); - xmlNodePtr ptr = This->current; + HRESULT hr;
TRACE("(%p)->(%d %p %p)\n", This, celt, rgVar, fetched);
if (!rgVar) return E_INVALIDARG;
- /* FIXME: handle celt */ - if (fetched) - *fetched = 1; + if (fetched) *fetched = 0;
- if (This->current) - This->current = This->current->next; - else + if (!This->current) { V_VT(rgVar) = VT_EMPTY; - if (fetched) *fetched = 0; return S_FALSE; }
- V_VT(rgVar) = VT_DISPATCH; - return XMLElement_create(ptr, (LPVOID *)&V_DISPATCH(rgVar), FALSE); + while (celt > 0 && This->current) + { + V_VT(rgVar) = VT_DISPATCH; + hr = XMLElement_create(This->current, (void **)&V_DISPATCH(rgVar), FALSE); + if (FAILED(hr)) return hr; + This->current = This->current->next; + if (--celt && This->current) ++rgVar; + if (fetched) ++*fetched; + } + + return celt == 0 ? S_OK : S_FALSE; }
static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip(
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com