>From 7366c500094f47f3bd06acbdecc430aac0536def Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Wed, 14 Mar 2012 09:21:05 +0300
Subject: [PATCH 1/4] Implement getValue() for MXAttributes

---
 dlls/msxml3/mxwriter.c        |   18 ++++++++++++++----
 dlls/msxml3/tests/saxreader.c |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c
index f749eb5..b28bd19 100644
--- a/dlls/msxml3/mxwriter.c
+++ b/dlls/msxml3/mxwriter.c
@@ -1819,12 +1819,22 @@ static HRESULT WINAPI SAXAttributes_getTypeFromQName(ISAXAttributes *iface, cons
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int nIndex, const WCHAR ** pValue,
-    int * nValue)
+static HRESULT WINAPI SAXAttributes_getValue(ISAXAttributes *iface, int index, const WCHAR **value,
+    int *len)
 {
     mxattributes *This = impl_from_ISAXAttributes( iface );
-    FIXME("(%p)->(%d %p %p): stub\n", This, nIndex, pValue, nValue);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%d %p %p)\n", This, index, value, len);
+
+    if (index >= This->length) return E_INVALIDARG;
+
+    if ((!value || !len) && (This->class_version == MSXML_DEFAULT || This->class_version == MSXML3))
+       return E_POINTER;
+
+    *value = This->attr[index].value;
+    *len = SysStringLen(This->attr[index].value);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI SAXAttributes_getValueFromName(ISAXAttributes *iface, const WCHAR * pUri,
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index 8b0a3c4..95c7787 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -3298,6 +3298,7 @@ static void test_mxattr_addAttribute(void)
     {
         ISAXAttributes *saxattr;
         IMXAttributes *mxattr;
+        const WCHAR *value;
         HRESULT hr;
         int len;
 
@@ -3328,10 +3329,46 @@ static void test_mxattr_addAttribute(void)
         EXPECT_HR(hr, S_OK);
         ok(len == 0, "got %d\n", len);
 
+        hr = ISAXAttributes_getValue(saxattr, 0, &value, &len);
+        EXPECT_HR(hr, E_INVALIDARG);
+
+        hr = ISAXAttributes_getValue(saxattr, 0, NULL, &len);
+        EXPECT_HR(hr, E_INVALIDARG);
+
+        hr = ISAXAttributes_getValue(saxattr, 0, &value, NULL);
+        EXPECT_HR(hr, E_INVALIDARG);
+
+        hr = ISAXAttributes_getValue(saxattr, 0, NULL, NULL);
+        EXPECT_HR(hr, E_INVALIDARG);
+
         hr = IMXAttributes_addAttribute(mxattr, _bstr_(table->uri), _bstr_(table->local),
             _bstr_(table->qname), _bstr_(table->type), _bstr_(table->value));
         ok(hr == table->hr, "%d: got 0x%08x, expected 0x%08x\n", i, hr, table->hr);
 
+        if (hr == S_OK)
+        {
+            /* SAXAttributes40 and SAXAttributes60 both crash on this test */
+            if (IsEqualGUID(table->clsid, &CLSID_SAXAttributes) ||
+                IsEqualGUID(table->clsid, &CLSID_SAXAttributes30))
+            {
+               hr = ISAXAttributes_getValue(saxattr, 0, NULL, &len);
+               EXPECT_HR(hr, E_POINTER);
+
+               hr = ISAXAttributes_getValue(saxattr, 0, &value, NULL);
+               EXPECT_HR(hr, E_POINTER);
+
+               hr = ISAXAttributes_getValue(saxattr, 0, NULL, NULL);
+               EXPECT_HR(hr, E_POINTER);
+            }
+
+            len = -1;
+            hr = ISAXAttributes_getValue(saxattr, 0, &value, &len);
+            EXPECT_HR(hr, S_OK);
+            ok(!lstrcmpW(_bstr_(table->value), value), "%d: got %s, expected %s\n", i, wine_dbgstr_w(value),
+                table->value);
+            ok(lstrlenW(value) == len, "%d: got wrong value length %d\n", i, len);
+        }
+
         len = -1;
         hr = ISAXAttributes_getLength(saxattr, &len);
         EXPECT_HR(hr, S_OK);
-- 
1.5.6.5


