msxml3: Fix IDispatch support for IXMLDocument.
This commit is contained in:
parent
08a4ca7b53
commit
c32db17417
|
@ -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;
|
||||
|
|
|
@ -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[] =
|
||||
"<?xml version=\"1.0\" ?>\n"
|
||||
"<BankAccount>\n"
|
||||
" <Number>1234</Number>\n"
|
||||
" <Name>Captain Ahab</Name>\n"
|
||||
"</BankAccount>\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));
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue