>From 4005440325b3fb9ad3624888f342cefec4bd21f3 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Sun, 11 Dec 2011 13:58:24 +0300
Subject: [PATCH 6/9] Added IDispatchEx support for IXMLDOMSchemaCollection2

---
 dlls/msxml3/dispex.c        |    1 +
 dlls/msxml3/msxml_private.h |    1 +
 dlls/msxml3/schema.c        |   71 ++++++++++++++++---------------------------
 dlls/msxml3/tests/schema.c  |   66 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 94 insertions(+), 45 deletions(-)

diff --git a/dlls/msxml3/dispex.c b/dlls/msxml3/dispex.c
index 529fd96..5114222 100644
--- a/dlls/msxml3/dispex.c
+++ b/dlls/msxml3/dispex.c
@@ -129,6 +129,7 @@ static tid_id_t tid_ids[] = {
     { &IID_IXMLDOMParseError, LibXml2 },
     { &IID_IXMLDOMProcessingInstruction, LibXml2 },
     { &IID_IXMLDOMSchemaCollection, LibXml2 },
+    { &IID_IXMLDOMSchemaCollection2, LibXml2 },
     { &IID_IXMLDOMSelection, LibXml2 },
     { &IID_IXMLDOMText, LibXml2 },
     { &IID_IXMLElement, LibXml },
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index bb517a7..cba00bb 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -56,6 +56,7 @@ typedef enum tid_t {
     IXMLDOMParseError_tid,
     IXMLDOMProcessingInstruction_tid,
     IXMLDOMSchemaCollection_tid,
+    IXMLDOMSchemaCollection2_tid,
     IXMLDOMSelection_tid,
     IXMLDOMText_tid,
     IXMLElement_tid,
diff --git a/dlls/msxml3/schema.c b/dlls/msxml3/schema.c
index aff763e..7473dbb 100644
--- a/dlls/msxml3/schema.c
+++ b/dlls/msxml3/schema.c
@@ -89,6 +89,7 @@ typedef enum _SCHEMA_TYPE {
 
 typedef struct
 {
+    DispatchEx dispex;
     IXMLDOMSchemaCollection2 IXMLDOMSchemaCollection2_iface;
     LONG ref;
 
@@ -961,6 +962,10 @@ static HRESULT WINAPI schema_cache_QueryInterface(IXMLDOMSchemaCollection2* ifac
     {
         *ppvObject = 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));
@@ -995,6 +1000,7 @@ static ULONG WINAPI schema_cache_Release(IXMLDOMSchemaCollection2* iface)
     if (ref == 0)
     {
         xmlHashFree(This->cache, cache_free);
+        release_dispex(&This->dispex);
         heap_free(This);
     }
 
@@ -1005,25 +1011,15 @@ static HRESULT WINAPI schema_cache_GetTypeInfoCount(IXMLDOMSchemaCollection2* if
                                                     UINT* pctinfo)
 {
     schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface);
-
-    TRACE("(%p)->(%p)\n", This, pctinfo);
-
-    *pctinfo = 1;
-
-    return S_OK;
+    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
 }
 
 static HRESULT WINAPI schema_cache_GetTypeInfo(IXMLDOMSchemaCollection2* iface,
                                                UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
 {
     schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface);
-    HRESULT hr;
-
-    TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
-
-    hr = get_typeinfo(IXMLDOMSchemaCollection_tid, ppTInfo);
-
-    return hr;
+    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
+        iTInfo, lcid, ppTInfo);
 }
 
 static HRESULT WINAPI schema_cache_GetIDsOfNames(IXMLDOMSchemaCollection2* iface,
@@ -1031,23 +1027,8 @@ static HRESULT WINAPI schema_cache_GetIDsOfNames(IXMLDOMSchemaCollection2* iface
                                                  UINT cNames, LCID lcid, DISPID* rgDispId)
 {
     schema_cache* This = impl_from_IXMLDOMSchemaCollection2(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(IXMLDOMSchemaCollection_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 schema_cache_Invoke(IXMLDOMSchemaCollection2* iface,
@@ -1057,21 +1038,8 @@ static HRESULT WINAPI schema_cache_Invoke(IXMLDOMSchemaCollection2* iface,
                                           UINT* puArgErr)
 {
     schema_cache* This = impl_from_IXMLDOMSchemaCollection2(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(IXMLDOMSchemaCollection_tid, &typeinfo);
-    if(SUCCEEDED(hr))
-    {
-        hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDOMSchemaCollection2_iface.lpVtbl, 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 schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri, VARIANT var)
@@ -1437,6 +1405,18 @@ XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2* iface, xmlNodePtr node)
     return dt;
 }
 
+static const tid_t schemacache_iface_tids[] = {
+    IXMLDOMSchemaCollection2_tid,
+    0
+};
+
+static dispex_static_data_t schemacache_dispex = {
+    NULL,
+    IXMLDOMSchemaCollection2_tid,
+    NULL,
+    schemacache_iface_tids
+};
+
 HRESULT SchemaCache_create(MSXML_VERSION version, IUnknown* outer, void** obj)
 {
     schema_cache* This = heap_alloc(sizeof(schema_cache));
@@ -1450,6 +1430,7 @@ HRESULT SchemaCache_create(MSXML_VERSION version, IUnknown* outer, void** obj)
     This->ref = 1;
     This->version = version;
     This->validateOnLoad = VARIANT_TRUE;
+    init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMSchemaCollection2_iface, &schemacache_dispex);
 
     *obj = &This->IXMLDOMSchemaCollection2_iface;
     return S_OK;
diff --git a/dlls/msxml3/tests/schema.c b/dlls/msxml3/tests/schema.c
index 951ee68..59ceac5 100644
--- a/dlls/msxml3/tests/schema.c
+++ b/dlls/msxml3/tests/schema.c
@@ -27,6 +27,7 @@
 #include "windows.h"
 #include "ole2.h"
 #include "msxml2.h"
+#include "msxml2did.h"
 #include "dispex.h"
 
 #include "wine/test.h"
@@ -1996,6 +1997,70 @@ static void test_validate_on_load(void)
     IXMLDOMSchemaCollection2_Release(cache);
 }
 
+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_XMLDOM_SCHEMACOLLECTION_ADD, &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)
+{
+    IXMLDOMSchemaCollection *cache;
+    IUnknown *unk;
+    HRESULT hr;
+
+    cache = create_cache(&IID_IXMLDOMSchemaCollection);
+    if (!cache) return;
+
+    hr = IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IUnknown, (void**)&unk);
+    EXPECT_HR(hr, S_OK);
+    test_obj_dispex(unk);
+    IUnknown_Release(unk);
+
+    IXMLDOMSchemaCollection_Release(cache);
+}
+
 START_TEST(schema)
 {
     HRESULT r;
@@ -2010,6 +2075,7 @@ START_TEST(schema)
     test_XDR_schemas();
     test_XDR_datatypes();
     test_validate_on_load();
+    test_dispex();
 
     CoUninitialize();
 }
-- 
1.5.6.5


