>From 8012706ab60c5a13aff38d2ed142a4849788499f Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Mon, 5 Dec 2011 11:07:26 +0300
Subject: [PATCH] Added IDispatchEx support for IMXWriter

---
 dlls/msxml3/mxwriter.c        |   83 +++++++++++++++++-----------------------
 dlls/msxml3/tests/saxreader.c |   22 +++++++++++
 2 files changed, 57 insertions(+), 48 deletions(-)

diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c
index cc75d1d..b402259 100644
--- a/dlls/msxml3/mxwriter.c
+++ b/dlls/msxml3/mxwriter.c
@@ -59,6 +59,7 @@ typedef enum
 
 typedef struct _mxwriter
 {
+    DispatchEx dispex;
     IMXWriter IMXWriter_iface;
     ISAXContentHandler ISAXContentHandler_iface;
 
@@ -209,6 +210,8 @@ static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, voi
 
     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
 
+    *obj = NULL;
+
     if ( IsEqualGUID( riid, &IID_IMXWriter ) ||
          IsEqualGUID( riid, &IID_IDispatch ) ||
          IsEqualGUID( riid, &IID_IUnknown ) )
@@ -219,6 +222,10 @@ static HRESULT WINAPI mxwriter_QueryInterface(IMXWriter *iface, REFIID riid, voi
     {
         *obj = &This->ISAXContentHandler_iface;
     }
+    else if (dispex_query_interface(&This->dispex, riid, obj))
+    {
+        return *obj ? S_OK : E_NOINTERFACE;
+    }
     else
     {
         ERR("interface %s not implemented\n", debugstr_guid(riid));
@@ -257,6 +264,7 @@ static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
 
         xmlOutputBufferClose(This->buffer);
         SysFreeString(This->element);
+        release_dispex(&This->dispex);
         heap_free(This);
     }
 
@@ -266,12 +274,7 @@ static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
 static HRESULT WINAPI mxwriter_GetTypeInfoCount(IMXWriter *iface, UINT* pctinfo)
 {
     mxwriter *This = impl_from_IMXWriter( iface );
-
-    TRACE("(%p)->(%p)\n", This, pctinfo);
-
-    *pctinfo = 1;
-
-    return S_OK;
+    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
 }
 
 static HRESULT WINAPI mxwriter_GetTypeInfo(
@@ -280,10 +283,8 @@ static HRESULT WINAPI mxwriter_GetTypeInfo(
     ITypeInfo** ppTInfo )
 {
     mxwriter *This = impl_from_IMXWriter( iface );
-
-    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
-
-    return get_typeinfo(IMXWriter_tid, ppTInfo);
+    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
+        iTInfo, lcid, ppTInfo);
 }
 
 static HRESULT WINAPI mxwriter_GetIDsOfNames(
@@ -292,23 +293,8 @@ static HRESULT WINAPI mxwriter_GetIDsOfNames(
     UINT cNames, LCID lcid, DISPID* rgDispId )
 {
     mxwriter *This = impl_from_IMXWriter( iface );
-    ITypeInfo *typeinfo;
-    HRESULT hr;
-
-    TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
-          lcid, rgDispId);
-
-    if(!rgszNames || cNames == 0 || !rgDispId)
-        return E_INVALIDARG;
-
-    hr = get_typeinfo(IMXWriter_tid, &typeinfo);
-    if(SUCCEEDED(hr))
-    {
-        hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
-        ITypeInfo_Release(typeinfo);
-    }
-
-    return hr;
+    return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
+        riid, rgszNames, cNames, lcid, rgDispId);
 }
 
 static HRESULT WINAPI mxwriter_Invoke(
@@ -318,21 +304,8 @@ static HRESULT WINAPI mxwriter_Invoke(
     EXCEPINFO* pExcepInfo, UINT* puArgErr )
 {
     mxwriter *This = impl_from_IMXWriter( iface );
-    ITypeInfo *typeinfo;
-    HRESULT hr;
-
-    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
-          lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
-
-    hr = get_typeinfo(IMXWriter_tid, &typeinfo);
-    if(SUCCEEDED(hr))
-    {
-        hr = ITypeInfo_Invoke(typeinfo, &This->IMXWriter_iface, dispIdMember, wFlags,
-                pDispParams, pVarResult, pExcepInfo, puArgErr);
-        ITypeInfo_Release(typeinfo);
-    }
-
-    return hr;
+    return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
+        dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
 }
 
 static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
@@ -575,7 +548,7 @@ static HRESULT WINAPI mxwriter_flush(IMXWriter *iface)
     return flush_output_buffer(This);
 }
 
-static const struct IMXWriterVtbl mxwriter_vtbl =
+static const struct IMXWriterVtbl MXWriterVtbl =
 {
     mxwriter_QueryInterface,
     mxwriter_AddRef,
@@ -897,20 +870,32 @@ static const struct ISAXContentHandlerVtbl mxwriter_saxcontent_vtbl =
     mxwriter_saxcontent_skippedEntity
 };
 
-HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *pUnkOuter, void **ppObj)
+static const tid_t mxwriter_iface_tids[] = {
+    IMXWriter_tid,
+    0
+};
+
+static dispex_static_data_t mxwriter_dispex = {
+    NULL,
+    IMXWriter_tid,
+    NULL,
+    mxwriter_iface_tids
+};
+
+HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *outer, void **ppObj)
 {
     static const WCHAR version10W[] = {'1','.','0',0};
     mxwriter *This;
 
-    TRACE("(%p,%p)\n", pUnkOuter, ppObj);
+    TRACE("(%p, %p)\n", outer, ppObj);
 
-    if (pUnkOuter) FIXME("support aggregation, outer\n");
+    if (outer) FIXME("support aggregation, outer\n");
 
     This = heap_alloc( sizeof (*This) );
     if(!This)
         return E_OUTOFMEMORY;
 
-    This->IMXWriter_iface.lpVtbl = &mxwriter_vtbl;
+    This->IMXWriter_iface.lpVtbl = &MXWriterVtbl;
     This->ISAXContentHandler_iface.lpVtbl = &mxwriter_saxcontent_vtbl;
     This->ref = 1;
     This->class_version = version;
@@ -931,6 +916,8 @@ HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *pUnkOuter, void **ppObj
 
     This->buffer = xmlAllocOutputBuffer(xmlGetCharEncodingHandler(This->encoding));
 
+    init_dispex(&This->dispex, (IUnknown*)&This->IMXWriter_iface, &mxwriter_dispex);
+
     *ppObj = &This->IMXWriter_iface;
 
     TRACE("returning iface %p\n", *ppObj);
@@ -940,7 +927,7 @@ HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *pUnkOuter, void **ppObj
 
 #else
 
-HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *pUnkOuter, void **obj)
+HRESULT MXWriter_create(MSXML_VERSION version, IUnknown *outer, void **obj)
 {
     MESSAGE("This program tried to use a MXXMLWriter object, but\n"
             "libxml2 support was not present at compile time.\n");
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index fbb1bd2..e59c13b 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -2672,6 +2672,27 @@ static void test_dispex(void)
      ISAXXMLReader_Release(reader);
 }
 
+static void test_mxwriter_dispex(void)
+{
+    IDispatchEx *dispex;
+    IMXWriter *writer;
+    IUnknown *unk;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IMXWriter, (void**)&writer);
+    EXPECT_HR(hr, S_OK);
+
+    hr = IMXWriter_QueryInterface(writer, &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);
+
+    IMXWriter_Release(writer);
+}
+
 START_TEST(saxreader)
 {
     ISAXXMLReader *reader;
@@ -2711,6 +2732,7 @@ START_TEST(saxreader)
         test_mxwriter_flush();
         test_mxwriter_stream();
         test_mxwriter_encoding();
+        test_mxwriter_dispex();
     }
     else
         win_skip("MXXMLWriter not supported\n");
-- 
1.5.6.5

