Commit 3e3a5b18 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

msxml3: Added queryresult's IDispatchEx implementation.

File dispex.c is copied from mshtml.dll. Jacek helped me to write this patch.
parent 12f7e0aa
......@@ -13,6 +13,7 @@ C_SRCS = \
bsc.c \
cdata.c \
comment.c \
dispex.c \
docfrag.c \
domdoc.c \
domimpl.c \
......
......@@ -41,91 +41,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(msxml);
static ITypeLib *typelib;
static ITypeInfo *typeinfos[LAST_tid];
static REFIID tid_ids[] = {
&IID_IXMLDOMAttribute,
&IID_IXMLDOMCDATASection,
&IID_IXMLDOMComment,
&IID_IXMLDOMDocument2,
&IID_IXMLDOMDocumentFragment,
&IID_IXMLDOMElement,
&IID_IXMLDOMEntityReference,
&IID_IXMLDOMImplementation,
&IID_IXMLDOMNamedNodeMap,
&IID_IXMLDOMNode,
&IID_IXMLDOMNodeList,
&IID_IXMLDOMParseError,
&IID_IXMLDOMProcessingInstruction,
&IID_IXMLDOMSchemaCollection,
&IID_IXMLDOMText,
&IID_IXMLElement,
&IID_IXMLDOMDocument,
&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,
};
HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo)
{
HRESULT hres;
if(!typelib) {
ITypeLib *tl;
hres = LoadRegTypeLib(&LIBID_MSXML2, 3, 0, LOCALE_SYSTEM_DEFAULT, &tl);
if(FAILED(hres)) {
ERR("LoadRegTypeLib failed: %08x\n", hres);
return hres;
}
if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
ITypeLib_Release(tl);
}
if(!typeinfos[tid]) {
ITypeInfo *typeinfo;
hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &typeinfo);
if(FAILED(hres)) {
ERR("GetTypeInfoOfGuid failed: %08x\n", hres);
return hres;
}
if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), typeinfo, NULL))
ITypeInfo_Release(typeinfo);
}
*typeinfo = typeinfos[tid];
ITypeInfo_AddRef(typeinfos[tid]);
return S_OK;
}
static void process_detach(void)
{
if(typelib) {
unsigned i;
for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
if(typeinfos[i])
ITypeInfo_Release(typeinfos[i]);
ITypeLib_Release(typelib);
}
}
HRESULT WINAPI DllCanUnloadNow(void)
{
FIXME("\n");
......@@ -160,7 +75,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
#ifdef HAVE_LIBXML2
xmlCleanupParser();
#endif
process_detach();
release_typelib();
break;
}
return TRUE;
......
......@@ -21,6 +21,10 @@
#ifndef __MSXML_PRIVATE__
#define __MSXML_PRIVATE__
#include "dispex.h"
#include "wine/unicode.h"
#ifndef __WINE_CONFIG_H
# error You must include config.h to use this header
#endif
......@@ -99,7 +103,7 @@ HRESULT bind_url(LPCWSTR, HRESULT (*onDataAvailable)(void*,char*,DWORD), void*,
void detach_bsc(bsc_t*);
/* typelibs */
enum tid_t {
typedef enum tid_t {
IXMLDOMAttribute_tid,
IXMLDOMCDATASection_tid,
IXMLDOMComment_tid,
......@@ -131,8 +135,76 @@ enum tid_t {
IMXReaderControl_tid,
IMXWriter_tid,
LAST_tid
};
} tid_t;
extern HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo);
extern void release_typelib(void);
typedef struct dispex_data_t dispex_data_t;
typedef struct dispex_dynamic_data_t dispex_dynamic_data_t;
#define MSXML_DISPID_CUSTOM_MIN 0x60000000
#define MSXML_DISPID_CUSTOM_MAX 0x6fffffff
typedef struct {
HRESULT (*get_dispid)(IUnknown*,BSTR,DWORD,DISPID*);
HRESULT (*invoke)(IUnknown*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*);
} dispex_static_data_vtbl_t;
typedef struct {
const dispex_static_data_vtbl_t *vtbl;
const tid_t disp_tid;
dispex_data_t *data;
const tid_t* const iface_tids;
} dispex_static_data_t;
typedef struct {
const IDispatchExVtbl *lpIDispatchExVtbl;
IUnknown *outer;
dispex_static_data_t *data;
dispex_dynamic_data_t *dynamic_data;
} DispatchEx;
void init_dispex(DispatchEx*,IUnknown*,dispex_static_data_t*);
BOOL dispex_query_interface(DispatchEx*,REFIID,void**);
/* memory allocation functions */
static inline void *heap_alloc(size_t len)
{
return HeapAlloc(GetProcessHeap(), 0, len);
}
extern HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo);
static inline void *heap_alloc_zero(size_t len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}
static inline void *heap_realloc(void *mem, size_t len)
{
return HeapReAlloc(GetProcessHeap(), 0, mem, len);
}
static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
}
static inline LPWSTR heap_strdupW(LPCWSTR str)
{
LPWSTR ret = NULL;
if(str) {
DWORD size;
size = (strlenW(str)+1)*sizeof(WCHAR);
ret = heap_alloc(size);
memcpy(ret, str, size);
}
return ret;
}
#endif /* __MSXML_PRIVATE__ */
......@@ -52,6 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
typedef struct _queryresult
{
DispatchEx dispex;
const struct IXMLDOMNodeListVtbl *lpVtbl;
LONG ref;
xmlNodePtr node;
......@@ -64,23 +65,27 @@ static inline queryresult *impl_from_IXMLDOMNodeList( IXMLDOMNodeList *iface )
return (queryresult *)((char*)iface - FIELD_OFFSET(queryresult, lpVtbl));
}
static HRESULT WINAPI queryresult_QueryInterface(
IXMLDOMNodeList *iface,
REFIID riid,
void** ppvObject )
{
queryresult *This = impl_from_IXMLDOMNodeList( iface );
TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
if(!ppvObject)
return E_INVALIDARG;
if ( IsEqualGUID( riid, &IID_IUnknown ) ||
IsEqualGUID( riid, &IID_IDispatch ) ||
IsEqualGUID( riid, &IID_IXMLDOMNodeList ) )
{
*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));
......@@ -111,7 +116,7 @@ static ULONG WINAPI queryresult_Release(
{
xmlXPathFreeObject(This->result);
xmldoc_release(This->node->doc);
CoTaskMemFree(This);
heap_free(This);
}
return ref;
......@@ -297,9 +302,20 @@ static const struct IXMLDOMNodeListVtbl queryresult_vtbl =
queryresult__newEnum,
};
static const tid_t queryresult_iface_tids[] = {
IXMLDOMNodeList_tid,
0
};
static dispex_static_data_t queryresult_dispex = {
NULL,
IXMLDOMNodeList_tid,
NULL,
queryresult_iface_tids
};
HRESULT queryresult_create(xmlNodePtr node, LPWSTR szQuery, IXMLDOMNodeList **out)
{
queryresult *This = CoTaskMemAlloc(sizeof(queryresult));
queryresult *This = heap_alloc_zero(sizeof(queryresult));
xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc);
xmlChar *str = xmlChar_from_wchar(szQuery);
HRESULT hr;
......@@ -328,7 +344,9 @@ HRESULT queryresult_create(xmlNodePtr node, LPWSTR szQuery, IXMLDOMNodeList **ou
goto cleanup;
}
*out = (IXMLDOMNodeList *)This;
init_dispex(&This->dispex, (IUnknown*)&This->lpVtbl, &queryresult_dispex);
*out = (IXMLDOMNodeList *) &This->lpVtbl;
hr = S_OK;
TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment