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 = \ ...@@ -13,6 +13,7 @@ C_SRCS = \
bsc.c \ bsc.c \
cdata.c \ cdata.c \
comment.c \ comment.c \
dispex.c \
docfrag.c \ docfrag.c \
domdoc.c \ domdoc.c \
domimpl.c \ domimpl.c \
......
...@@ -41,91 +41,6 @@ ...@@ -41,91 +41,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(msxml); 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) HRESULT WINAPI DllCanUnloadNow(void)
{ {
FIXME("\n"); FIXME("\n");
...@@ -160,7 +75,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) ...@@ -160,7 +75,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
#ifdef HAVE_LIBXML2 #ifdef HAVE_LIBXML2
xmlCleanupParser(); xmlCleanupParser();
#endif #endif
process_detach(); release_typelib();
break; break;
} }
return TRUE; return TRUE;
......
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
#ifndef __MSXML_PRIVATE__ #ifndef __MSXML_PRIVATE__
#define __MSXML_PRIVATE__ #define __MSXML_PRIVATE__
#include "dispex.h"
#include "wine/unicode.h"
#ifndef __WINE_CONFIG_H #ifndef __WINE_CONFIG_H
# error You must include config.h to use this header # error You must include config.h to use this header
#endif #endif
...@@ -99,7 +103,7 @@ HRESULT bind_url(LPCWSTR, HRESULT (*onDataAvailable)(void*,char*,DWORD), void*, ...@@ -99,7 +103,7 @@ HRESULT bind_url(LPCWSTR, HRESULT (*onDataAvailable)(void*,char*,DWORD), void*,
void detach_bsc(bsc_t*); void detach_bsc(bsc_t*);
/* typelibs */ /* typelibs */
enum tid_t { typedef enum tid_t {
IXMLDOMAttribute_tid, IXMLDOMAttribute_tid,
IXMLDOMCDATASection_tid, IXMLDOMCDATASection_tid,
IXMLDOMComment_tid, IXMLDOMComment_tid,
...@@ -131,8 +135,76 @@ enum tid_t { ...@@ -131,8 +135,76 @@ enum tid_t {
IMXReaderControl_tid, IMXReaderControl_tid,
IMXWriter_tid, IMXWriter_tid,
LAST_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__ */ #endif /* __MSXML_PRIVATE__ */
...@@ -52,6 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml); ...@@ -52,6 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
typedef struct _queryresult typedef struct _queryresult
{ {
DispatchEx dispex;
const struct IXMLDOMNodeListVtbl *lpVtbl; const struct IXMLDOMNodeListVtbl *lpVtbl;
LONG ref; LONG ref;
xmlNodePtr node; xmlNodePtr node;
...@@ -64,23 +65,27 @@ static inline queryresult *impl_from_IXMLDOMNodeList( IXMLDOMNodeList *iface ) ...@@ -64,23 +65,27 @@ static inline queryresult *impl_from_IXMLDOMNodeList( IXMLDOMNodeList *iface )
return (queryresult *)((char*)iface - FIELD_OFFSET(queryresult, lpVtbl)); return (queryresult *)((char*)iface - FIELD_OFFSET(queryresult, lpVtbl));
} }
static HRESULT WINAPI queryresult_QueryInterface( static HRESULT WINAPI queryresult_QueryInterface(
IXMLDOMNodeList *iface, IXMLDOMNodeList *iface,
REFIID riid, REFIID riid,
void** ppvObject ) void** ppvObject )
{ {
queryresult *This = impl_from_IXMLDOMNodeList( iface );
TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject); TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
if(!ppvObject) if(!ppvObject)
return E_INVALIDARG; return E_INVALIDARG;
if ( IsEqualGUID( riid, &IID_IUnknown ) || if ( IsEqualGUID( riid, &IID_IUnknown ) ||
IsEqualGUID( riid, &IID_IDispatch ) ||
IsEqualGUID( riid, &IID_IXMLDOMNodeList ) ) IsEqualGUID( riid, &IID_IXMLDOMNodeList ) )
{ {
*ppvObject = iface; *ppvObject = iface;
} }
else if(dispex_query_interface(&This->dispex, riid, ppvObject))
{
return *ppvObject ? S_OK : E_NOINTERFACE;
}
else else
{ {
FIXME("interface %s not implemented\n", debugstr_guid(riid)); FIXME("interface %s not implemented\n", debugstr_guid(riid));
...@@ -111,7 +116,7 @@ static ULONG WINAPI queryresult_Release( ...@@ -111,7 +116,7 @@ static ULONG WINAPI queryresult_Release(
{ {
xmlXPathFreeObject(This->result); xmlXPathFreeObject(This->result);
xmldoc_release(This->node->doc); xmldoc_release(This->node->doc);
CoTaskMemFree(This); heap_free(This);
} }
return ref; return ref;
...@@ -297,9 +302,20 @@ static const struct IXMLDOMNodeListVtbl queryresult_vtbl = ...@@ -297,9 +302,20 @@ static const struct IXMLDOMNodeListVtbl queryresult_vtbl =
queryresult__newEnum, 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) 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); xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc);
xmlChar *str = xmlChar_from_wchar(szQuery); xmlChar *str = xmlChar_from_wchar(szQuery);
HRESULT hr; HRESULT hr;
...@@ -328,7 +344,9 @@ HRESULT queryresult_create(xmlNodePtr node, LPWSTR szQuery, IXMLDOMNodeList **ou ...@@ -328,7 +344,9 @@ HRESULT queryresult_create(xmlNodePtr node, LPWSTR szQuery, IXMLDOMNodeList **ou
goto cleanup; goto cleanup;
} }
*out = (IXMLDOMNodeList *)This; init_dispex(&This->dispex, (IUnknown*)&This->lpVtbl, &queryresult_dispex);
*out = (IXMLDOMNodeList *) &This->lpVtbl;
hr = S_OK; hr = S_OK;
TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval)); 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