>From 6d668b7f9e0078fc8254fc38a27711eb64371874 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Mon, 21 Nov 2011 12:23:25 +0300
Subject: [PATCH 6/6] Added IDispatchEx support for SAXReader

---
 dlls/msxml3/saxreader.c       |   71 ++++++++++++++------------------------
 dlls/msxml3/tests/saxreader.c |   77 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 103 insertions(+), 45 deletions(-)

diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c
index cda55c4..5891814 100644
--- a/dlls/msxml3/saxreader.c
+++ b/dlls/msxml3/saxreader.c
@@ -77,6 +77,7 @@ struct bstrpool
 
 typedef struct _saxreader
 {
+    DispatchEx dispex;
     IVBSAXXMLReader IVBSAXXMLReader_iface;
     ISAXXMLReader ISAXXMLReader_iface;
     LONG ref;
@@ -2605,6 +2606,10 @@ static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID
     {
         *ppvObject = &This->ISAXXMLReader_iface;
     }
+    else if (dispex_query_interface(&This->dispex, riid, ppvObject))
+    {
+        return *ppvObject ? S_OK : E_NOINTERFACE;
+    }
     else
     {
         FIXME("interface %s not implemented\n", debugstr_guid(riid));
@@ -2660,6 +2665,7 @@ static ULONG WINAPI saxxmlreader_Release(
 
         free_bstr_pool(&This->pool);
 
+        release_dispex(&This->dispex);
         heap_free( This );
     }
 
@@ -2669,12 +2675,7 @@ static ULONG WINAPI saxxmlreader_Release(
 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
 {
     saxreader *This = impl_from_IVBSAXXMLReader( iface );
-
-    TRACE("(%p)->(%p)\n", This, pctinfo);
-
-    *pctinfo = 1;
-
-    return S_OK;
+    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
 }
 
 static HRESULT WINAPI saxxmlreader_GetTypeInfo(
@@ -2682,13 +2683,8 @@ static HRESULT WINAPI saxxmlreader_GetTypeInfo(
     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
 {
     saxreader *This = impl_from_IVBSAXXMLReader( iface );
-    HRESULT hr;
-
-    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
-
-    hr = get_typeinfo(IVBSAXXMLReader_tid, ppTInfo);
-
-    return hr;
+    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
+        iTInfo, lcid, ppTInfo);
 }
 
 static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
@@ -2700,23 +2696,8 @@ static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
     DISPID* rgDispId)
 {
     saxreader *This = impl_from_IVBSAXXMLReader( 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(IVBSAXXMLReader_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 saxxmlreader_Invoke(
@@ -2731,21 +2712,8 @@ static HRESULT WINAPI saxxmlreader_Invoke(
     UINT* puArgErr)
 {
     saxreader *This = impl_from_IVBSAXXMLReader( 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(IVBSAXXMLReader_tid, &typeinfo);
-    if(SUCCEEDED(hr))
-    {
-        hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXXMLReader_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);
 }
 
 /*** IVBSAXXMLReader methods ***/
@@ -3159,6 +3127,17 @@ static const struct ISAXXMLReaderVtbl isaxreader_vtbl =
     isaxxmlreader_parseURL
 };
 
+static const tid_t saxreader_iface_tids[] = {
+    IVBSAXXMLReader_tid,
+    0
+};
+static dispex_static_data_t saxreader_dispex = {
+    NULL,
+    IVBSAXXMLReader_tid,
+    NULL,
+    saxreader_iface_tids
+};
+
 HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *pUnkOuter, LPVOID *ppObj)
 {
     saxreader *reader;
@@ -3187,6 +3166,8 @@ HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *pUnkOuter, LPVOID *
     reader->features = Namespaces;
     reader->version = version;
 
+    init_dispex(&reader->dispex, (IUnknown*)&reader->IVBSAXXMLReader_iface, &saxreader_dispex);
+
     memset(&reader->sax, 0, sizeof(xmlSAXHandler));
     reader->sax.initialized = XML_SAX2_MAGIC;
     reader->sax.startDocument = libxmlStartDocument;
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index 2ec20bf..fbb1bd2 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -28,7 +28,9 @@
 #include "windows.h"
 #include "ole2.h"
 #include "msxml2.h"
+#include "msxml2did.h"
 #include "ocidl.h"
+#include "dispex.h"
 
 #include "wine/test.h"
 
@@ -2596,6 +2598,80 @@ static void test_mxwriter_encoding(void)
     free_bstrs();
 }
 
+static void test_obj_dispex(IUnknown *obj)
+{
+    static const WCHAR starW[] = {'*',0};
+    DISPID dispid = DISPID_SAX_XMLREADER_GETFEATURE;
+    IDispatchEx *dispex;
+    IUnknown *unk;
+    DWORD props;
+    UINT ticnt;
+    HRESULT hr;
+    BSTR name;
+
+    hr = IUnknown_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
+    EXPECT_HR(hr, S_OK);
+    if (FAILED(hr)) return;
+
+    ticnt = 0;
+    hr = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
+    EXPECT_HR(hr, S_OK);
+    ok(ticnt == 1, "ticnt=%u\n", ticnt);
+
+    name = SysAllocString(starW);
+    hr = IDispatchEx_DeleteMemberByName(dispex, name, fdexNameCaseSensitive);
+    EXPECT_HR(hr, E_NOTIMPL);
+    SysFreeString(name);
+
+    hr = IDispatchEx_DeleteMemberByDispID(dispex, dispid);
+    EXPECT_HR(hr, E_NOTIMPL);
+
+    props = 0;
+    hr = IDispatchEx_GetMemberProperties(dispex, dispid, grfdexPropCanAll, &props);
+    EXPECT_HR(hr, E_NOTIMPL);
+    ok(props == 0, "expected 0 got %d\n", props);
+
+    hr = IDispatchEx_GetMemberName(dispex, dispid, &name);
+    EXPECT_HR(hr, E_NOTIMPL);
+    if (SUCCEEDED(hr)) SysFreeString(name);
+
+    hr = IDispatchEx_GetNextDispID(dispex, fdexEnumDefault, DISPID_SAX_XMLREADER_GETFEATURE, &dispid);
+    EXPECT_HR(hr, E_NOTIMPL);
+
+    hr = IDispatchEx_GetNameSpaceParent(dispex, &unk);
+    EXPECT_HR(hr, E_NOTIMPL);
+    if (hr == S_OK && unk) IUnknown_Release(unk);
+
+    IDispatchEx_Release(dispex);
+}
+
+static void test_dispex(void)
+{
+     IVBSAXXMLReader *vbreader;
+     ISAXXMLReader *reader;
+     IUnknown *unk;
+     HRESULT hr;
+
+     hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
+                &IID_ISAXXMLReader, (void**)&reader);
+     EXPECT_HR(hr, S_OK);
+
+     hr = ISAXXMLReader_QueryInterface(reader, &IID_IUnknown, (void**)&unk);
+     EXPECT_HR(hr, S_OK);
+     test_obj_dispex(unk);
+     IUnknown_Release(unk);
+
+     hr = ISAXXMLReader_QueryInterface(reader, &IID_IVBSAXXMLReader, (void**)&vbreader);
+     EXPECT_HR(hr, S_OK);
+     hr = IVBSAXXMLReader_QueryInterface(vbreader, &IID_IUnknown, (void**)&unk);
+     EXPECT_HR(hr, S_OK);
+     test_obj_dispex(unk);
+     IUnknown_Release(unk);
+     IVBSAXXMLReader_Release(vbreader);
+
+     ISAXXMLReader_Release(reader);
+}
+
 START_TEST(saxreader)
 {
     ISAXXMLReader *reader;
@@ -2621,6 +2697,7 @@ START_TEST(saxreader)
     test_saxreader_properties();
     test_saxreader_features();
     test_encoding();
+    test_dispex();
 
     /* MXXMLWriter tests */
     get_supported_mxwriter_data(msxmlsupported_data);
-- 
1.5.6.5

