>From 71e8763ac7e0920dc83c4537b31ac73ff44cb78e Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Thu, 8 Mar 2012 23:11:45 +0300
Subject: [PATCH 1/2] Stub support for IMXAttributes

---
 dlls/msxml3/factory.c         |   14 +++-
 dlls/msxml3/msxml_private.h   |    1 +
 dlls/msxml3/mxwriter.c        |  236 +++++++++++++++++++++++++++++++++++++++++
 dlls/msxml3/tests/saxreader.c |   42 +++++++-
 4 files changed, 291 insertions(+), 2 deletions(-)

diff --git a/dlls/msxml3/factory.c b/dlls/msxml3/factory.c
index e3b910a..256bbbd 100644
--- a/dlls/msxml3/factory.c
+++ b/dlls/msxml3/factory.c
@@ -86,7 +86,12 @@ static const struct clsid_version_t clsid_versions_table[] =
     { &CLSID_SAXXMLReader,   MSXML_DEFAULT },
     { &CLSID_SAXXMLReader30, MSXML3 },
     { &CLSID_SAXXMLReader40, MSXML4 },
-    { &CLSID_SAXXMLReader60, MSXML6 }
+    { &CLSID_SAXXMLReader60, MSXML6 },
+
+    { &CLSID_SAXAttributes,   MSXML_DEFAULT },
+    { &CLSID_SAXAttributes30, MSXML3 },
+    { &CLSID_SAXAttributes40, MSXML4 },
+    { &CLSID_SAXAttributes60, MSXML6 }
 };
 
 static MSXML_VERSION get_msxml_version(const GUID *clsid)
@@ -347,6 +352,13 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
     {
         return DOMClassFactory_Create(rclsid, riid, ppv, MXWriter_create);
     }
+    else if( IsEqualCLSID( rclsid, &CLSID_SAXAttributes) ||
+             IsEqualCLSID( rclsid, &CLSID_SAXAttributes30 ) ||
+             IsEqualCLSID( rclsid, &CLSID_SAXAttributes40 ) ||
+             IsEqualCLSID( rclsid, &CLSID_SAXAttributes60 ))
+    {
+        return DOMClassFactory_Create(rclsid, riid, ppv, SAXAttributes_create);
+    }
     else if( IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager ) ||
              IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager40 ) ||
              IsEqualCLSID( rclsid, &CLSID_MXNamespaceManager60 ) )
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index e51501b..27c4d7f 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -453,6 +453,7 @@ extern HRESULT DOMDocument_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HID
 extern HRESULT SchemaCache_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN;
 extern HRESULT XMLDocument_create(IUnknown*, void**) DECLSPEC_HIDDEN;
 extern HRESULT SAXXMLReader_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN;
+extern HRESULT SAXAttributes_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN;
 extern HRESULT XMLHTTPRequest_create(IUnknown*, void **) DECLSPEC_HIDDEN;
 extern HRESULT XSLTemplate_create(IUnknown*, void**) DECLSPEC_HIDDEN;
 extern HRESULT MXWriter_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN;
diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c
index 55159e1..dabd3d6 100644
--- a/dlls/msxml3/mxwriter.c
+++ b/dlls/msxml3/mxwriter.c
@@ -118,6 +118,18 @@ typedef struct
     output_buffer *buffer;
 } mxwriter;
 
+typedef struct
+{
+    DispatchEx dispex;
+    IMXAttributes IMXAttributes_iface;
+    LONG ref;
+} mxattributes;
+
+static inline mxattributes *impl_from_IMXAttributes( IMXAttributes *iface )
+{
+    return CONTAINING_RECORD(iface, mxattributes, IMXAttributes_iface);
+}
+
 static xml_encoding parse_encoding_name(const WCHAR *encoding)
 {
     static const WCHAR utf8W[]  = {'U','T','F','-','8',0};
@@ -1436,3 +1448,227 @@ HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *outer, void **ppObj)
 
     return S_OK;
 }
+
+static HRESULT WINAPI MXAttributes_QueryInterface(IMXAttributes *iface, REFIID riid, void **ppObj)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppObj);
+
+    *ppObj = NULL;
+
+    if ( IsEqualGUID( riid, &IID_IUnknown )  ||
+         IsEqualGUID( riid, &IID_IDispatch ) ||
+         IsEqualGUID( riid, &IID_IMXAttributes ))
+    {
+        *ppObj = iface;
+    }
+    else if (dispex_query_interface(&This->dispex, riid, ppObj))
+    {
+        return *ppObj ? S_OK : E_NOINTERFACE;
+    }
+    else
+    {
+        FIXME("interface %s not implemented\n", debugstr_guid(riid));
+        return E_NOINTERFACE;
+    }
+
+    IMXAttributes_AddRef( iface );
+
+    return S_OK;
+}
+
+static ULONG WINAPI MXAttributes_AddRef(IMXAttributes *iface)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    ULONG ref = InterlockedIncrement( &This->ref );
+    TRACE("(%p)->(%d)\n", This, ref );
+    return ref;
+}
+
+static ULONG WINAPI MXAttributes_Release(IMXAttributes *iface)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    LONG ref = InterlockedDecrement( &This->ref );
+
+    TRACE("(%p)->(%d)\n", This, ref);
+
+    if (ref == 0)
+    {
+        release_dispex(&This->dispex);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI MXAttributes_GetTypeInfoCount(IMXAttributes *iface, UINT* pctinfo)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
+}
+
+static HRESULT WINAPI MXAttributes_GetTypeInfo(IMXAttributes *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
+}
+
+static HRESULT WINAPI MXAttributes_GetIDsOfNames(
+    IMXAttributes *iface,
+    REFIID riid,
+    LPOLESTR* rgszNames,
+    UINT cNames,
+    LCID lcid,
+    DISPID* rgDispId)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
+        riid, rgszNames, cNames, lcid, rgDispId);
+}
+
+static HRESULT WINAPI MXAttributes_Invoke(
+    IMXAttributes *iface,
+    DISPID dispIdMember,
+    REFIID riid,
+    LCID lcid,
+    WORD wFlags,
+    DISPPARAMS* pDispParams,
+    VARIANT* pVarResult,
+    EXCEPINFO* pExcepInfo,
+    UINT* puArgErr)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
+        dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+}
+
+static HRESULT WINAPI MXAttributes_addAttribute(IMXAttributes *iface,
+    BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p)->(%s %s %s %s %s): stub\n", This, debugstr_w(uri), debugstr_w(localName),
+        debugstr_w(QName), debugstr_w(type), debugstr_w(value));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MXAttributes_addAttributeFromIndex(IMXAttributes *iface,
+    VARIANT atts, int index)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p)->(%s %d): stub\n", This, debugstr_variant(&atts), index);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MXAttributes_clear(IMXAttributes *iface)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p): stub\n", This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MXAttributes_removeAttribute(IMXAttributes *iface, int index)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p)->(%d): stub\n", This, index);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MXAttributes_setAttribute(IMXAttributes *iface, int index,
+    BSTR uri, BSTR localName, BSTR QName, BSTR type, BSTR value)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p)->(%d %s %s %s %s %s): stub\n", This, index, debugstr_w(uri),
+        debugstr_w(localName), debugstr_w(QName), debugstr_w(type), debugstr_w(value));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MXAttributes_setAttributes(IMXAttributes *iface, VARIANT atts)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p)->(%s): stub\n", This, debugstr_variant(&atts));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MXAttributes_setLocalName(IMXAttributes *iface, int index,
+    BSTR localName)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(localName));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MXAttributes_setQName(IMXAttributes *iface, int index, BSTR QName)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(QName));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MXAttributes_setURI(IMXAttributes *iface, int index, BSTR uri)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(uri));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI MXAttributes_setValue(IMXAttributes *iface, int index, BSTR value)
+{
+    mxattributes *This = impl_from_IMXAttributes( iface );
+    FIXME("(%p)->(%d %s): stub\n", This, index, debugstr_w(value));
+    return E_NOTIMPL;
+}
+
+static const IMXAttributesVtbl MXAttributesVtbl = {
+    MXAttributes_QueryInterface,
+    MXAttributes_AddRef,
+    MXAttributes_Release,
+    MXAttributes_GetTypeInfoCount,
+    MXAttributes_GetTypeInfo,
+    MXAttributes_GetIDsOfNames,
+    MXAttributes_Invoke,
+    MXAttributes_addAttribute,
+    MXAttributes_addAttributeFromIndex,
+    MXAttributes_clear,
+    MXAttributes_removeAttribute,
+    MXAttributes_setAttribute,
+    MXAttributes_setAttributes,
+    MXAttributes_setLocalName,
+    MXAttributes_setQName,
+    MXAttributes_setURI,
+    MXAttributes_setValue
+};
+
+static const tid_t mxattrs_iface_tids[] = {
+    IMXAttributes_tid,
+    0
+};
+
+static dispex_static_data_t mxattrs_dispex = {
+    NULL,
+    IMXAttributes_tid,
+    NULL,
+    mxattrs_iface_tids
+};
+
+HRESULT SAXAttributes_create(MSXML_VERSION version, IUnknown *outer, void **ppObj)
+{
+    mxattributes *This;
+
+    TRACE("(%p, %p)\n", outer, ppObj);
+
+    This = heap_alloc( sizeof (*This) );
+    if( !This )
+        return E_OUTOFMEMORY;
+
+    This->IMXAttributes_iface.lpVtbl = &MXAttributesVtbl;
+    This->ref = 1;
+
+    *ppObj = &This->IMXAttributes_iface;
+
+    init_dispex(&This->dispex, (IUnknown*)&This->IMXAttributes_iface, &mxattrs_dispex);
+
+    TRACE("returning iface %p\n", *ppObj);
+
+    return S_OK;
+}
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index 494d866..28522d8 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -449,8 +449,12 @@ static HRESULT WINAPI contentHandler_startElement(
         int nQName,
         ISAXAttributes *pAttr)
 {
-    int len;
+    IMXAttributes *mxattr;
     HRESULT hres;
+    int len;
+
+    hres = ISAXAttributes_QueryInterface(pAttr, &IID_IMXAttributes, (void**)&mxattr);
+    EXPECT_HR(hres, E_NOINTERFACE);
 
     if(!test_expect_call(CH_STARTELEMENT))
         return E_FAIL;
@@ -3309,7 +3313,15 @@ static void test_mxattr_addAttribute(void)
         EXPECT_HR(hr, S_OK);
 
         hr = IMXAttributes_QueryInterface(mxattr, &IID_ISAXAttributes, (void**)&saxattr);
+todo_wine
         EXPECT_HR(hr, S_OK);
+        if (hr != S_OK)
+        {
+            IMXAttributes_Release(mxattr);
+            table++;
+            i++;
+            continue;
+        }
 
         /* SAXAttributes30 and SAXAttributes60 both crash on this test */
         if (IsEqualGUID(table->clsid, &CLSID_SAXAttributes) ||
@@ -3359,7 +3371,13 @@ static void test_mxattr_clear(void)
     EXPECT_HR(hr, S_OK);
 
     hr = IMXAttributes_QueryInterface(mxattr, &IID_ISAXAttributes, (void**)&saxattr);
+todo_wine
     EXPECT_HR(hr, S_OK);
+    if (hr != S_OK)
+    {
+        IMXAttributes_Release(mxattr);
+        return;
+    }
 
     hr = ISAXAttributes_getQName(saxattr, 0, NULL, NULL);
     EXPECT_HR(hr, E_INVALIDARG);
@@ -3412,6 +3430,27 @@ static void test_mxattr_clear(void)
     free_bstrs();
 }
 
+static void test_mxattr_dispex(void)
+{
+    IMXAttributes *mxattr;
+    IDispatchEx *dispex;
+    IUnknown *unk;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_SAXAttributes, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IMXAttributes, (void**)&mxattr);
+    EXPECT_HR(hr, S_OK);
+
+    hr = IMXAttributes_QueryInterface(mxattr, &IID_IDispatchEx, (void**)&dispex);
+    EXPECT_HR(hr, S_OK);
+    hr = IDispatchEx_QueryInterface(dispex, &IID_IUnknown, (void**)&unk);
+    test_obj_dispex(unk);
+    IUnknown_Release(unk);
+    IDispatchEx_Release(dispex);
+
+    IMXAttributes_Release(mxattr);
+}
+
 START_TEST(saxreader)
 {
     ISAXXMLReader *reader;
@@ -3465,6 +3504,7 @@ START_TEST(saxreader)
     {
         test_mxattr_addAttribute();
         test_mxattr_clear();
+        test_mxattr_dispex();
     }
     else
         skip("SAXAttributes not supported\n");
-- 
1.5.6.5


