From c32db174175c3d4add62a3d8a9435887e00d0b9c Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 4 Nov 2011 11:46:45 +0300 Subject: [PATCH] msxml3: Fix IDispatch support for IXMLDocument. --- dlls/msxml3/dispex.c | 129 +++++++++++++++++++++++++++------------------ dlls/msxml3/tests/xmldoc.c | 62 ++++++++++++---------- dlls/msxml3/xmldoc.c | 21 ++++---- 3 files changed, 122 insertions(+), 90 deletions(-) diff --git a/dlls/msxml3/dispex.c b/dlls/msxml3/dispex.c index 67ce77c48c2..ae84ab9fa7b 100644 --- a/dlls/msxml3/dispex.c +++ b/dlls/msxml3/dispex.c @@ -45,6 +45,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); +enum lib_version_t +{ + LibXml = 0, + LibXml2, + LibXml_Last +}; + +typedef struct { + REFIID iid; + enum lib_version_t lib; +} tid_id_t; + +typedef struct { + REFIID iid; + unsigned short major; +} lib_id_t; + typedef struct { DISPID id; BSTR name; @@ -74,74 +91,85 @@ struct dispex_dynamic_data_t { #define DISPID_DYNPROP_MAX 0x5fffffff static struct list dispex_data_list = LIST_INIT(dispex_data_list); -static ITypeLib *typelib; +static ITypeLib *typelib[LibXml_Last]; static ITypeInfo *typeinfos[LAST_tid]; -static REFIID tid_ids[] = { - &IID_NULL, - &IID_IXMLDOMAttribute, - &IID_IXMLDOMCDATASection, - &IID_IXMLDOMComment, - &IID_IXMLDOMDocument, - &IID_IXMLDOMDocument2, - &IID_IXMLDOMDocumentFragment, - &IID_IXMLDOMDocumentType, - &IID_IXMLDOMElement, - &IID_IXMLDOMEntityReference, - &IID_IXMLDOMImplementation, - &IID_IXMLDOMNamedNodeMap, - &IID_IXMLDOMNode, - &IID_IXMLDOMNodeList, - &IID_IXMLDOMParseError, - &IID_IXMLDOMProcessingInstruction, - &IID_IXMLDOMSchemaCollection, - &IID_IXMLDOMSelection, - &IID_IXMLDOMText, - &IID_IXMLElement, - &IID_IXMLDOMDocument, - &IID_IXMLHTTPRequest, - &IID_IXSLProcessor, - &IID_IXSLTemplate, - &IID_IVBSAXAttributes, - &IID_IVBSAXContentHandler, - &IID_IVBSAXDeclHandler, - &IID_IVBSAXDTDHandler, - &IID_IVBSAXEntityResolver, - &IID_IVBSAXErrorHandler, - &IID_IVBSAXLexicalHandler, - &IID_IVBSAXLocator, - &IID_IVBSAXXMLFilter, - &IID_IVBSAXXMLReader, - &IID_IMXAttributes, - &IID_IMXReaderControl, - &IID_IMXWriter, - &IID_IVBMXNamespaceManager +/* indexed with lib_version_t values */ +static lib_id_t lib_ids[] = { + { &LIBID_MSXML, 2 }, + { &LIBID_MSXML2, 3 } +}; + +static tid_id_t tid_ids[] = { + { &IID_NULL, LibXml_Last }, + { &IID_IXMLDOMAttribute, LibXml2 }, + { &IID_IXMLDOMCDATASection, LibXml2 }, + { &IID_IXMLDOMComment, LibXml2 }, + { &IID_IXMLDOMDocument, LibXml2 }, + { &IID_IXMLDOMDocument2, LibXml2 }, + { &IID_IXMLDOMDocumentFragment, LibXml2 }, + { &IID_IXMLDOMDocumentType, LibXml2 }, + { &IID_IXMLDOMElement, LibXml2 }, + { &IID_IXMLDOMEntityReference, LibXml2 }, + { &IID_IXMLDOMImplementation, LibXml2 }, + { &IID_IXMLDOMNamedNodeMap, LibXml2 }, + { &IID_IXMLDOMNode, LibXml2 }, + { &IID_IXMLDOMNodeList, LibXml2 }, + { &IID_IXMLDOMParseError, LibXml2 }, + { &IID_IXMLDOMProcessingInstruction, LibXml2 }, + { &IID_IXMLDOMSchemaCollection, LibXml2 }, + { &IID_IXMLDOMSelection, LibXml2 }, + { &IID_IXMLDOMText, LibXml2 }, + { &IID_IXMLElement, LibXml }, + { &IID_IXMLDocument, LibXml }, + { &IID_IXMLHTTPRequest, LibXml2 }, + { &IID_IXSLProcessor, LibXml2 }, + { &IID_IXSLTemplate, LibXml2 }, + { &IID_IVBSAXAttributes, LibXml2 }, + { &IID_IVBSAXContentHandler, LibXml2 }, + { &IID_IVBSAXDeclHandler, LibXml2 }, + { &IID_IVBSAXDTDHandler, LibXml2 }, + { &IID_IVBSAXEntityResolver, LibXml2 }, + { &IID_IVBSAXErrorHandler, LibXml2 }, + { &IID_IVBSAXLexicalHandler, LibXml2 }, + { &IID_IVBSAXLocator, LibXml2 }, + { &IID_IVBSAXXMLFilter, LibXml2 }, + { &IID_IVBSAXXMLReader, LibXml2 }, + { &IID_IMXAttributes, LibXml2 }, + { &IID_IMXReaderControl, LibXml2 }, + { &IID_IMXWriter, LibXml2 }, + { &IID_IVBMXNamespaceManager, LibXml2 } }; HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo) { + unsigned lib = tid_ids[tid].lib; HRESULT hres; - if(!typelib) { + if(!typelib[lib]) { ITypeLib *tl; - hres = LoadRegTypeLib(&LIBID_MSXML2, 3, 0, LOCALE_SYSTEM_DEFAULT, &tl); + hres = LoadRegTypeLib(lib_ids[lib].iid, lib_ids[lib].major, 0, LOCALE_SYSTEM_DEFAULT, &tl); if(FAILED(hres)) { ERR("LoadRegTypeLib failed: %08x\n", hres); return hres; } - if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) + if(InterlockedCompareExchangePointer((void**)&typelib[lib], tl, NULL)) ITypeLib_Release(tl); } if(!typeinfos[tid]) { ITypeInfo *ti; - hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); + hres = ITypeLib_GetTypeInfoOfGuid(typelib[lib], tid_ids[tid].iid, &ti); if(FAILED(hres)) { - ERR("GetTypeInfoOfGuid failed: %08x\n", hres); - return hres; + /* try harder with typelib from msxml.dll */ + hres = ITypeLib_GetTypeInfoOfGuid(typelib[LibXml], tid_ids[tid].iid, &ti); + if(FAILED(hres)) { + ERR("GetTypeInfoOfGuid failed: %08x\n", hres); + return hres; + } } if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) @@ -171,14 +199,13 @@ void release_typelib(void) heap_free(iter); } - if(!typelib) - return; - for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) if(typeinfos[i]) ITypeInfo_Release(typeinfos[i]); - ITypeLib_Release(typelib); + for(i=0; i < sizeof(typelib)/sizeof(*typelib); i++) + if(typelib[i]) + ITypeLib_Release(typelib[i]); } static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, DISPID id, ITypeInfo *dti) @@ -555,7 +582,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc return hres; } - hres = IUnknown_QueryInterface(This->outer, tid_ids[data->funcs[n].tid], (void**)&unk); + hres = IUnknown_QueryInterface(This->outer, tid_ids[data->funcs[n].tid].iid, (void**)&unk); if(FAILED(hres)) { ERR("Could not get iface: %08x\n", hres); return E_FAIL; diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c index 476924c7bc3..d2828dbd553 100644 --- a/dlls/msxml3/tests/xmldoc.c +++ b/dlls/msxml3/tests/xmldoc.c @@ -24,10 +24,14 @@ #include "windows.h" #include "ole2.h" #include "msxml2.h" +#include "msxml2did.h" #include "ocidl.h" #include "wine/test.h" +#define EXPECT_HR(hr,hr_exp) \ + ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp) + /* Deprecated Error Code */ #define XML_E_INVALIDATROOTLEVEL 0xc00ce556 @@ -49,25 +53,6 @@ static void create_xml_file(LPCSTR filename) CloseHandle(hf); } -/* -static void create_xml_file(LPCSTR filename) -{ - DWORD dwNumberOfBytesWritten; - HANDLE hf = CreateFile(filename, GENERIC_WRITE, 0, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - static const char data[] = - "\n" - "\n" - " 1234\n" - " Captain Ahab\n" - "\n"; - - WriteFile(hf, data, sizeof(data) - 1, &dwNumberOfBytesWritten, NULL); - CloseHandle(hf); -} -*/ - static void create_stream_on_file(IStream **stream, LPCSTR path) { HANDLE hfile; @@ -97,16 +82,18 @@ static void create_stream_on_file(IStream **stream, LPCSTR path) static void test_xmldoc(void) { - HRESULT hr; - IXMLDocument *doc = NULL; IXMLElement *element = NULL, *child = NULL, *value = NULL; IXMLElementCollection *collection = NULL, *inner = NULL; IPersistStreamInit *psi = NULL; + IXMLDocument *doc = NULL; IStream *stream = NULL; - CHAR path[MAX_PATH]; - LONG type, num_child; VARIANT vIndex, vName; - BSTR name = NULL; + LONG type, num_child; + CHAR path[MAX_PATH]; + IDispatch *disp; + ITypeInfo *ti; + HRESULT hr; + BSTR name; static const WCHAR szBankAccount[] = {'B','A','N','K','A','C','C','O','U','N','T',0}; static const WCHAR szNumber[] = {'N','U','M','B','E','R',0}; @@ -114,16 +101,36 @@ static void test_xmldoc(void) static const WCHAR szName[] = {'N','A','M','E',0}; static const WCHAR szNameVal[] = {'C','a','p','t','a','i','n',' ','A','h','a','b',0}; static const WCHAR szVersion[] = {'1','.','0',0}; + static const WCHAR rootW[] = {'r','o','o','t',0}; hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, - &IID_IXMLDocument, (LPVOID*)&doc); - ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + &IID_IXMLDocument, (void**)&doc); + EXPECT_HR(hr, S_OK); + + /* IDispatch */ + hr = IXMLDocument_QueryInterface(doc, &IID_IDispatch, (void**)&disp); + EXPECT_HR(hr, S_OK); + + /* just to make sure we're on right type data */ + hr = IDispatch_GetTypeInfo(disp, 0, 0, &ti); + EXPECT_HR(hr, S_OK); + name = NULL; + hr = ITypeInfo_GetDocumentation(ti, DISPID_XMLDOCUMENT_ROOT, &name, NULL, NULL, NULL); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(name, rootW), "got name %s\n", wine_dbgstr_w(name)); + SysFreeString(name); + + ITypeInfo_Release(ti); + IDispatch_Release(disp); + + hr = IXMLDocument_QueryInterface(doc, &IID_IXMLDOMDocument, (void**)&disp); + EXPECT_HR(hr, E_NOINTERFACE); create_xml_file("bank.xml"); GetFullPathNameA("bank.xml", MAX_PATH, path, NULL); create_stream_on_file(&stream, path); - hr = IXMLDocument_QueryInterface(doc, &IID_IPersistStreamInit, (LPVOID *)&psi); + hr = IXMLDocument_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&psi); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(psi != NULL, "Expected non-NULL psi\n"); @@ -142,6 +149,7 @@ static void test_xmldoc(void) hr = IXMLDocument_get_version(doc, NULL); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); + name = NULL; hr = IXMLDocument_get_version(doc, &name); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); ok(!lstrcmpW(name, szVersion), "Expected 1.0, got %s\n", wine_dbgstr_w(name)); diff --git a/dlls/msxml3/xmldoc.c b/dlls/msxml3/xmldoc.c index a9d1dd8d66e..1cf87855878 100644 --- a/dlls/msxml3/xmldoc.c +++ b/dlls/msxml3/xmldoc.c @@ -81,9 +81,9 @@ static HRESULT WINAPI xmldoc_QueryInterface(IXMLDocument *iface, REFIID riid, vo TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IXMLDocument) || - IsEqualGUID(riid, &IID_IXMLDOMDocument)) + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IXMLDocument)) { *ppvObject = iface; } @@ -107,18 +107,18 @@ static HRESULT WINAPI xmldoc_QueryInterface(IXMLDocument *iface, REFIID riid, vo static ULONG WINAPI xmldoc_AddRef(IXMLDocument *iface) { xmldoc *This = impl_from_IXMLDocument(iface); - TRACE("%p\n", This); - return InterlockedIncrement(&This->ref); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p)->(%d)\n", This, ref); + return ref; } static ULONG WINAPI xmldoc_Release(IXMLDocument *iface) { xmldoc *This = impl_from_IXMLDocument(iface); - LONG ref; + LONG ref = InterlockedDecrement(&This->ref); - TRACE("%p\n", This); + TRACE("(%p)->(%d)\n", This, ref); - ref = InterlockedDecrement(&This->ref); if (ref == 0) { xmlFreeDoc(This->xmldoc); @@ -144,13 +144,10 @@ static HRESULT WINAPI xmldoc_GetTypeInfo(IXMLDocument *iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { xmldoc *This = impl_from_IXMLDocument(iface); - HRESULT hr; TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); - hr = get_typeinfo(IXMLDocument_tid, ppTInfo); - - return hr; + return get_typeinfo(IXMLDocument_tid, ppTInfo); } static HRESULT WINAPI xmldoc_GetIDsOfNames(IXMLDocument *iface, REFIID riid, -- 2.11.4.GIT