From d206ae228c6b6e82e18f8c17fc50fc52bed40600 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Mon, 8 Sep 2008 16:58:34 +0000 Subject: [PATCH] forgot to add these files svn path=/trunk/; revision=36065 --- reactos/dll/win32/msxml3/bsc.c | 310 +++ reactos/dll/win32/msxml3/cdata.c | 794 ++++++++ reactos/dll/win32/msxml3/dispex.c | 630 ++++++ reactos/dll/win32/msxml3/docfrag.c | 552 +++++ reactos/dll/win32/msxml3/domimpl.c | 229 +++ reactos/dll/win32/msxml3/entityref.c | 551 +++++ reactos/dll/win32/msxml3/msxml3_v1.idl | 19 + reactos/dll/win32/msxml3/saxreader.c | 2569 ++++++++++++++++++++++++ 8 files changed, 5654 insertions(+) create mode 100644 reactos/dll/win32/msxml3/bsc.c create mode 100644 reactos/dll/win32/msxml3/cdata.c create mode 100644 reactos/dll/win32/msxml3/dispex.c create mode 100644 reactos/dll/win32/msxml3/docfrag.c create mode 100644 reactos/dll/win32/msxml3/domimpl.c create mode 100644 reactos/dll/win32/msxml3/entityref.c create mode 100644 reactos/dll/win32/msxml3/msxml3_v1.idl create mode 100644 reactos/dll/win32/msxml3/saxreader.c diff --git a/reactos/dll/win32/msxml3/bsc.c b/reactos/dll/win32/msxml3/bsc.c new file mode 100644 index 00000000000..bd29c318f00 --- /dev/null +++ b/reactos/dll/win32/msxml3/bsc.c @@ -0,0 +1,310 @@ +/* + * Copyright 2008 Piotr Caban + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS +#define NONAMELESSUNION + +#include "config.h" + +#include +#include +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" +#include "msxml2.h" +#include "wininet.h" +#include "urlmon.h" +#include "winreg.h" +#include "shlwapi.h" + +#include "wine/debug.h" + +#include "msxml_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msxml); + +struct bsc_t { + const struct IBindStatusCallbackVtbl *lpVtbl; + + LONG ref; + + void *obj; + HRESULT (*onDataAvailable)(void*,char*,DWORD); + + IBinding *binding; + IStream *memstream; +}; + +static inline bsc_t *impl_from_IBindStatusCallback( IBindStatusCallback *iface ) +{ + return (bsc_t *)((char*)iface - FIELD_OFFSET(bsc_t, lpVtbl)); +} + +static HRESULT WINAPI bsc_QueryInterface( + IBindStatusCallback *iface, + REFIID riid, + LPVOID *ppobj ) +{ + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IBindStatusCallback)) + { + IBindStatusCallback_AddRef( iface ); + *ppobj = iface; + return S_OK; + } + + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI bsc_AddRef( + IBindStatusCallback *iface ) +{ + bsc_t *This = impl_from_IBindStatusCallback(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI bsc_Release( + IBindStatusCallback *iface ) +{ + bsc_t *This = impl_from_IBindStatusCallback(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + if(This->binding) + IBinding_Release(This->binding); + if(This->memstream) + IStream_Release(This->memstream); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI bsc_OnStartBinding( + IBindStatusCallback* iface, + DWORD dwReserved, + IBinding* pib) +{ + bsc_t *This = impl_from_IBindStatusCallback(iface); + HRESULT hr; + + TRACE("(%p)->(%x %p)\n", This, dwReserved, pib); + + This->binding = pib; + IBindStatusCallback_AddRef(pib); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream); + if(FAILED(hr)) + return hr; + + return S_OK; +} + +static HRESULT WINAPI bsc_GetPriority( + IBindStatusCallback* iface, + LONG* pnPriority) +{ + return S_OK; +} + +static HRESULT WINAPI bsc_OnLowResource( + IBindStatusCallback* iface, + DWORD reserved) +{ + return S_OK; +} + +static HRESULT WINAPI bsc_OnProgress( + IBindStatusCallback* iface, + ULONG ulProgress, + ULONG ulProgressMax, + ULONG ulStatusCode, + LPCWSTR szStatusText) +{ + return S_OK; +} + +static HRESULT WINAPI bsc_OnStopBinding( + IBindStatusCallback* iface, + HRESULT hresult, + LPCWSTR szError) +{ + bsc_t *This = impl_from_IBindStatusCallback(iface); + HRESULT hr = S_OK; + + TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError)); + + if(This->binding) { + IBinding_Release(This->binding); + This->binding = NULL; + } + + if(This->obj && SUCCEEDED(hresult)) { + HGLOBAL hglobal; + hr = GetHGlobalFromStream(This->memstream, &hglobal); + if(SUCCEEDED(hr)) + { + DWORD len = GlobalSize(hglobal); + char *ptr = GlobalLock(hglobal); + + hr = This->onDataAvailable(This->obj, ptr, len); + + GlobalUnlock(hglobal); + } + } + + return hr; +} + +static HRESULT WINAPI bsc_GetBindInfo( + IBindStatusCallback* iface, + DWORD* grfBINDF, + BINDINFO* pbindinfo) +{ + *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE; + + return S_OK; +} + +static HRESULT WINAPI bsc_OnDataAvailable( + IBindStatusCallback* iface, + DWORD grfBSCF, + DWORD dwSize, + FORMATETC* pformatetc, + STGMEDIUM* pstgmed) +{ + bsc_t *This = impl_from_IBindStatusCallback(iface); + BYTE buf[4096]; + DWORD read, written; + HRESULT hr; + + TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed); + + do + { + hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read); + if(FAILED(hr)) + break; + + hr = IStream_Write(This->memstream, buf, read, &written); + } while(SUCCEEDED(hr) && written != 0 && read != 0); + + return S_OK; +} + +static HRESULT WINAPI bsc_OnObjectAvailable( + IBindStatusCallback* iface, + REFIID riid, + IUnknown* punk) +{ + return S_OK; +} + +static const struct IBindStatusCallbackVtbl bsc_vtbl = +{ + bsc_QueryInterface, + bsc_AddRef, + bsc_Release, + bsc_OnStartBinding, + bsc_GetPriority, + bsc_OnLowResource, + bsc_OnProgress, + bsc_OnStopBinding, + bsc_GetBindInfo, + bsc_OnDataAvailable, + bsc_OnObjectAvailable +}; + +HRESULT bind_url(LPCWSTR url, HRESULT (*onDataAvailable)(void*,char*,DWORD), void *obj, bsc_t **ret) +{ + WCHAR fileUrl[INTERNET_MAX_URL_LENGTH]; + bsc_t *bsc; + IBindCtx *pbc; + HRESULT hr; + + TRACE("%s\n", debugstr_w(url)); + + if(!PathIsURLW(url)) + { + WCHAR fullpath[MAX_PATH]; + DWORD needed = sizeof(fileUrl)/sizeof(WCHAR); + + if(!PathSearchAndQualifyW(url, fullpath, sizeof(fullpath)/sizeof(WCHAR))) + { + WARN("can't find path\n"); + return E_FAIL; + } + + if(FAILED(UrlCreateFromPathW(url, fileUrl, &needed, 0))) + { + ERR("can't create url from path\n"); + return E_FAIL; + } + url = fileUrl; + } + + hr = CreateBindCtx(0, &pbc); + if(FAILED(hr)) + return hr; + + bsc = HeapAlloc(GetProcessHeap(), 0, sizeof(bsc_t)); + + bsc->lpVtbl = &bsc_vtbl; + bsc->ref = 1; + bsc->obj = obj; + bsc->onDataAvailable = onDataAvailable; + bsc->binding = NULL; + bsc->memstream = NULL; + + hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&bsc->lpVtbl, NULL, 0); + if(SUCCEEDED(hr)) + { + IMoniker *moniker; + + hr = CreateURLMoniker(NULL, url, &moniker); + if(SUCCEEDED(hr)) + { + IStream *stream; + hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream); + IMoniker_Release(moniker); + if(stream) + IStream_Release(stream); + } + IBindCtx_Release(pbc); + } + + *ret = bsc; + return hr; +} + +void detach_bsc(bsc_t *bsc) +{ + if(bsc->binding) + IBinding_Abort(bsc->binding); + + bsc->obj = NULL; + IBindStatusCallback_Release((IBindStatusCallback*)&bsc->lpVtbl); +} diff --git a/reactos/dll/win32/msxml3/cdata.c b/reactos/dll/win32/msxml3/cdata.c new file mode 100644 index 00000000000..06d8bb1cb35 --- /dev/null +++ b/reactos/dll/win32/msxml3/cdata.c @@ -0,0 +1,794 @@ +/* + * DOM CDATA node implementation + * + * Copyright 2007 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "config.h" + +#include +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" +#include "msxml2.h" + +#include "msxml_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msxml); + +#ifdef HAVE_LIBXML2 + +typedef struct _domcdata +{ + const struct IXMLDOMCDATASectionVtbl *lpVtbl; + LONG ref; + IUnknown *element_unk; + IXMLDOMCDATASection *element; +} domcdata; + +static inline domcdata *impl_from_IXMLDOMCDATASection( IXMLDOMCDATASection *iface ) +{ + return (domcdata *)((char*)iface - FIELD_OFFSET(domcdata, lpVtbl)); +} + +static HRESULT WINAPI domcdata_QueryInterface( + IXMLDOMCDATASection *iface, + REFIID riid, + void** ppvObject ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); + + if ( IsEqualGUID( riid, &IID_IXMLDOMCDATASection ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) || + IsEqualGUID( riid, &IID_IXMLDOMElement ) ) + { + return IUnknown_QueryInterface(This->element_unk, riid, ppvObject); + } + else + { + FIXME("Unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IXMLDOMCDATASection_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI domcdata_AddRef( + IXMLDOMCDATASection *iface ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI domcdata_Release( + IXMLDOMCDATASection *iface ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + ULONG ref; + + ref = InterlockedDecrement( &This->ref ); + if ( ref == 0 ) + { + IUnknown_Release( This->element_unk ); + HeapFree( GetProcessHeap(), 0, This ); + } + + return ref; +} + +static HRESULT WINAPI domcdata_GetTypeInfoCount( + IXMLDOMCDATASection *iface, + UINT* pctinfo ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + + return S_OK; +} + +static HRESULT WINAPI domcdata_GetTypeInfo( + IXMLDOMCDATASection *iface, + UINT iTInfo, LCID lcid, + ITypeInfo** ppTInfo ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + HRESULT hr; + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + hr = get_typeinfo(IXMLDOMCDATASection_tid, ppTInfo); + + return hr; +} + +static HRESULT WINAPI domcdata_GetIDsOfNames( + IXMLDOMCDATASection *iface, + REFIID riid, LPOLESTR* rgszNames, + UINT cNames, LCID lcid, DISPID* rgDispId ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( 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(IXMLDOMCDATASection_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI domcdata_Invoke( + IXMLDOMCDATASection *iface, + DISPID dispIdMember, REFIID riid, LCID lcid, + WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, UINT* puArgErr ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( 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(IXMLDOMCDATASection_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI domcdata_get_nodeName( + IXMLDOMCDATASection *iface, + BSTR* p ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_nodeName( This->element, p ); +} + +static HRESULT WINAPI domcdata_get_nodeValue( + IXMLDOMCDATASection *iface, + VARIANT* var1 ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_nodeValue( This->element, var1 ); +} + +static HRESULT WINAPI domcdata_put_nodeValue( + IXMLDOMCDATASection *iface, + VARIANT var1 ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_put_nodeValue( This->element, var1 ); +} + +static HRESULT WINAPI domcdata_get_nodeType( + IXMLDOMCDATASection *iface, + DOMNodeType* domNodeType ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_nodeType( This->element, domNodeType ); +} + +static HRESULT WINAPI domcdata_get_parentNode( + IXMLDOMCDATASection *iface, + IXMLDOMNode** parent ) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_parentNode( This->element, parent ); +} + +static HRESULT WINAPI domcdata_get_childNodes( + IXMLDOMCDATASection *iface, + IXMLDOMNodeList** outList) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_childNodes( This->element, outList ); +} + +static HRESULT WINAPI domcdata_get_firstChild( + IXMLDOMCDATASection *iface, + IXMLDOMNode** domNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_firstChild( This->element, domNode ); +} + +static HRESULT WINAPI domcdata_get_lastChild( + IXMLDOMCDATASection *iface, + IXMLDOMNode** domNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_lastChild( This->element, domNode ); +} + +static HRESULT WINAPI domcdata_get_previousSibling( + IXMLDOMCDATASection *iface, + IXMLDOMNode** domNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_previousSibling( This->element, domNode ); +} + +static HRESULT WINAPI domcdata_get_nextSibling( + IXMLDOMCDATASection *iface, + IXMLDOMNode** domNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_nextSibling( This->element, domNode ); +} + +static HRESULT WINAPI domcdata_get_attributes( + IXMLDOMCDATASection *iface, + IXMLDOMNamedNodeMap** attributeMap) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_attributes( This->element, attributeMap ); +} + +static HRESULT WINAPI domcdata_insertBefore( + IXMLDOMCDATASection *iface, + IXMLDOMNode* newNode, VARIANT var1, + IXMLDOMNode** outOldNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_insertBefore( This->element, newNode, var1, outOldNode ); +} + +static HRESULT WINAPI domcdata_replaceChild( + IXMLDOMCDATASection *iface, + IXMLDOMNode* newNode, + IXMLDOMNode* oldNode, + IXMLDOMNode** outOldNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_replaceChild( This->element, newNode, oldNode, outOldNode ); +} + +static HRESULT WINAPI domcdata_removeChild( + IXMLDOMCDATASection *iface, + IXMLDOMNode* domNode, IXMLDOMNode** oldNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_removeChild( This->element, domNode, oldNode ); +} + +static HRESULT WINAPI domcdata_appendChild( + IXMLDOMCDATASection *iface, + IXMLDOMNode* newNode, IXMLDOMNode** outNewNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_appendChild( This->element, newNode, outNewNode ); +} + +static HRESULT WINAPI domcdata_hasChildNodes( + IXMLDOMCDATASection *iface, + VARIANT_BOOL* pbool) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_hasChildNodes( This->element, pbool ); +} + +static HRESULT WINAPI domcdata_get_ownerDocument( + IXMLDOMCDATASection *iface, + IXMLDOMDocument** domDocument) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_ownerDocument( This->element, domDocument ); +} + +static HRESULT WINAPI domcdata_cloneNode( + IXMLDOMCDATASection *iface, + VARIANT_BOOL pbool, IXMLDOMNode** outNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_cloneNode( This->element, pbool, outNode ); +} + +static HRESULT WINAPI domcdata_get_nodeTypeString( + IXMLDOMCDATASection *iface, + BSTR* p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_nodeTypeString( This->element, p ); +} + +static HRESULT WINAPI domcdata_get_text( + IXMLDOMCDATASection *iface, + BSTR* p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_text( This->element, p ); +} + +static HRESULT WINAPI domcdata_put_text( + IXMLDOMCDATASection *iface, + BSTR p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_put_text( This->element, p ); +} + +static HRESULT WINAPI domcdata_get_specified( + IXMLDOMCDATASection *iface, + VARIANT_BOOL* pbool) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_specified( This->element, pbool ); +} + +static HRESULT WINAPI domcdata_get_definition( + IXMLDOMCDATASection *iface, + IXMLDOMNode** domNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_definition( This->element, domNode ); +} + +static HRESULT WINAPI domcdata_get_nodeTypedValue( + IXMLDOMCDATASection *iface, + VARIANT* var1) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_nodeTypedValue( This->element, var1 ); +} + +static HRESULT WINAPI domcdata_put_nodeTypedValue( + IXMLDOMCDATASection *iface, + VARIANT var1) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_put_nodeTypedValue( This->element, var1 ); +} + +static HRESULT WINAPI domcdata_get_dataType( + IXMLDOMCDATASection *iface, + VARIANT* var1) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_dataType( This->element, var1 ); +} + +static HRESULT WINAPI domcdata_put_dataType( + IXMLDOMCDATASection *iface, + BSTR p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_put_dataType( This->element, p ); +} + +static HRESULT WINAPI domcdata_get_xml( + IXMLDOMCDATASection *iface, + BSTR* p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_xml( This->element, p ); +} + +static HRESULT WINAPI domcdata_transformNode( + IXMLDOMCDATASection *iface, + IXMLDOMNode* domNode, BSTR* p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_transformNode( This->element, domNode, p ); +} + +static HRESULT WINAPI domcdata_selectNodes( + IXMLDOMCDATASection *iface, + BSTR p, IXMLDOMNodeList** outList) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_selectNodes( This->element, p, outList ); +} + +static HRESULT WINAPI domcdata_selectSingleNode( + IXMLDOMCDATASection *iface, + BSTR p, IXMLDOMNode** outNode) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_selectSingleNode( This->element, p, outNode ); +} + +static HRESULT WINAPI domcdata_get_parsed( + IXMLDOMCDATASection *iface, + VARIANT_BOOL* pbool) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_parsed( This->element, pbool ); +} + +static HRESULT WINAPI domcdata_get_namespaceURI( + IXMLDOMCDATASection *iface, + BSTR* p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_namespaceURI( This->element, p ); +} + +static HRESULT WINAPI domcdata_get_prefix( + IXMLDOMCDATASection *iface, + BSTR* p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_prefix( This->element, p ); +} + +static HRESULT WINAPI domcdata_get_baseName( + IXMLDOMCDATASection *iface, + BSTR* p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_get_baseName( This->element, p ); +} + +static HRESULT WINAPI domcdata_transformNodeToObject( + IXMLDOMCDATASection *iface, + IXMLDOMNode* domNode, VARIANT var1) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + return IXMLDOMNode_transformNodeToObject( This->element, domNode, var1 ); +} + +static HRESULT WINAPI domcdata_get_data( + IXMLDOMCDATASection *iface, + BSTR *p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + HRESULT hr = E_FAIL; + VARIANT vRet; + + if(!p) + return E_INVALIDARG; + + hr = IXMLDOMNode_get_nodeValue( This->element, &vRet ); + if(hr == S_OK) + { + *p = V_BSTR(&vRet); + } + + return hr; +} + +static HRESULT WINAPI domcdata_put_data( + IXMLDOMCDATASection *iface, + BSTR data) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + HRESULT hr = E_FAIL; + VARIANT val; + + TRACE("%p %s\n", This, debugstr_w(data) ); + + V_VT(&val) = VT_BSTR; + V_BSTR(&val) = data; + + hr = IXMLDOMNode_put_nodeValue( This->element, val ); + + return hr; +} + +static HRESULT WINAPI domcdata_get_length( + IXMLDOMCDATASection *iface, + long *len) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->element ); + xmlChar *pContent; + long nLength = 0; + + TRACE("%p\n", iface); + + if(!len) + return E_INVALIDARG; + + pContent = xmlNodeGetContent(pDOMNode->node); + if(pContent) + { + nLength = xmlStrlen(pContent); + xmlFree(pContent); + } + + *len = nLength; + + return S_OK; +} + +static HRESULT WINAPI domcdata_substringData( + IXMLDOMCDATASection *iface, + long offset, long count, BSTR *p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->element ); + xmlChar *pContent; + long nLength = 0; + HRESULT hr = S_FALSE; + + TRACE("%p\n", iface); + + if(!p) + return E_INVALIDARG; + + *p = NULL; + if(offset < 0 || count < 0) + return E_INVALIDARG; + + if(count == 0) + return hr; + + pContent = xmlNodeGetContent(pDOMNode->node); + if(pContent) + { + nLength = xmlStrlen(pContent); + + if( offset < nLength) + { + BSTR sContent = bstr_from_xmlChar(pContent); + if(offset + count > nLength) + *p = SysAllocString(&sContent[offset]); + else + *p = SysAllocStringLen(&sContent[offset], count); + + SysFreeString(sContent); + hr = S_OK; + } + + xmlFree(pContent); + } + + return hr; +} + +static HRESULT WINAPI domcdata_appendData( + IXMLDOMCDATASection *iface, + BSTR p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->element ); + xmlChar *pContent; + HRESULT hr = S_FALSE; + + TRACE("%p\n", iface); + + /* Nothing to do if NULL or an Empty string passed in. */ + if(p == NULL || SysStringLen(p) == 0) + return S_OK; + + pContent = xmlChar_from_wchar( (WCHAR*)p ); + if(pContent) + { + if(xmlTextConcat(pDOMNode->node, pContent, SysStringLen(p) ) == 0) + hr = S_OK; + else + hr = E_FAIL; + } + else + hr = E_FAIL; + + return hr; +} + +static HRESULT WINAPI domcdata_insertData( + IXMLDOMCDATASection *iface, + long offset, BSTR p) +{ + domcdata *This = impl_from_IXMLDOMCDATASection( iface ); + xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->element ); + xmlChar *pXmlContent; + BSTR sNewString; + HRESULT hr = S_FALSE; + long nLength = 0, nLengthP = 0; + xmlChar *str = NULL; + + TRACE("%p\n", This); + + /* If have a NULL or empty string, don't do anything. */ + if(SysStringLen(p) == 0) + return S_OK; + + if(offset < 0) + { + return E_INVALIDARG; + } + + pXmlContent = xmlNodeGetContent(pDOMNode->node); + if(pXmlContent) + { + BSTR sContent = bstr_from_xmlChar( pXmlContent ); + nLength = SysStringLen(sContent); + nLengthP = SysStringLen(p); + + if(nLength < offset) + { + SysFreeString(sContent); + xmlFree(pXmlContent); + + return E_INVALIDARG; + } + + sNewString = SysAllocStringLen(NULL, nLength + nLengthP + 1); + if(sNewString) + { + if(offset > 0) + memcpy(sNewString, sContent, offset * sizeof(WCHAR)); + + memcpy(&sNewString[offset], p, nLengthP * sizeof(WCHAR)); + + if(offset+nLengthP < nLength) + memcpy(&sNewString[offset+nLengthP], &sContent[offset], (nLength-offset) * sizeof(WCHAR)); + + sNewString[nLengthP + nLength] = 0; + + str = xmlChar_from_wchar((WCHAR*)sNewString); + if(str) + { + xmlNodeSetContent(pDOMNode->node, str); + hr = S_OK; + } + + SysFreeString(sNewString); + } + + SysFreeString(sContent); + + xmlFree(pXmlContent); + } + + return hr; +} + +static HRESULT WINAPI domcdata_deleteData( + IXMLDOMCDATASection *iface, + long offset, long count) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI domcdata_replaceData( + IXMLDOMCDATASection *iface, + long offset, long count, BSTR p) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI domcdata_splitText( + IXMLDOMCDATASection *iface, + long offset, IXMLDOMText **txtNode) +{ + FIXME("\n"); + return E_NOTIMPL; +} + + +static const struct IXMLDOMCDATASectionVtbl domcdata_vtbl = +{ + domcdata_QueryInterface, + domcdata_AddRef, + domcdata_Release, + domcdata_GetTypeInfoCount, + domcdata_GetTypeInfo, + domcdata_GetIDsOfNames, + domcdata_Invoke, + domcdata_get_nodeName, + domcdata_get_nodeValue, + domcdata_put_nodeValue, + domcdata_get_nodeType, + domcdata_get_parentNode, + domcdata_get_childNodes, + domcdata_get_firstChild, + domcdata_get_lastChild, + domcdata_get_previousSibling, + domcdata_get_nextSibling, + domcdata_get_attributes, + domcdata_insertBefore, + domcdata_replaceChild, + domcdata_removeChild, + domcdata_appendChild, + domcdata_hasChildNodes, + domcdata_get_ownerDocument, + domcdata_cloneNode, + domcdata_get_nodeTypeString, + domcdata_get_text, + domcdata_put_text, + domcdata_get_specified, + domcdata_get_definition, + domcdata_get_nodeTypedValue, + domcdata_put_nodeTypedValue, + domcdata_get_dataType, + domcdata_put_dataType, + domcdata_get_xml, + domcdata_transformNode, + domcdata_selectNodes, + domcdata_selectSingleNode, + domcdata_get_parsed, + domcdata_get_namespaceURI, + domcdata_get_prefix, + domcdata_get_baseName, + domcdata_transformNodeToObject, + domcdata_get_data, + domcdata_put_data, + domcdata_get_length, + domcdata_substringData, + domcdata_appendData, + domcdata_insertData, + domcdata_deleteData, + domcdata_replaceData, + domcdata_splitText +}; + +IUnknown* create_cdata( xmlNodePtr text ) +{ + domcdata *This; + HRESULT hr; + + This = HeapAlloc( GetProcessHeap(), 0, sizeof *This ); + if ( !This ) + return NULL; + + This->lpVtbl = &domcdata_vtbl; + This->ref = 1; + + This->element_unk = create_element( text, (IUnknown*)&This->lpVtbl ); + if(!This->element_unk) + { + HeapFree(GetProcessHeap(), 0, This); + return NULL; + } + + hr = IUnknown_QueryInterface(This->element_unk, &IID_IXMLDOMNode, (LPVOID*)&This->element); + if(FAILED(hr)) + { + IUnknown_Release(This->element_unk); + HeapFree( GetProcessHeap(), 0, This ); + return NULL; + } + /* The ref on This->element is actually looped back into this object, so release it */ + IXMLDOMNode_Release(This->element); + + return (IUnknown*) &This->lpVtbl; +} + +#endif diff --git a/reactos/dll/win32/msxml3/dispex.c b/reactos/dll/win32/msxml3/dispex.c new file mode 100644 index 00000000000..4156c78a4a7 --- /dev/null +++ b/reactos/dll/win32/msxml3/dispex.c @@ -0,0 +1,630 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "config.h" + +#include +#include +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" +#include "ole2.h" +#include "msxml2.h" +#include "wininet.h" +#include "urlmon.h" +#include "winreg.h" +#include "shlwapi.h" + +#include "wine/debug.h" +#include "wine/list.h" +#include "wine/unicode.h" + +#include "msxml_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msxml); + +#define DISPATCHEX(x) ((IDispatchEx*) &(x)->lpIDispatchExVtbl) + +typedef struct { + DISPID id; + BSTR name; + enum tid_t tid; +} func_info_t; + +struct dispex_data_t { + DWORD func_cnt; + func_info_t *funcs; + func_info_t **name_table; + + struct list entry; +}; + +typedef struct { + VARIANT var; + LPWSTR name; +} dynamic_prop_t; + +struct dispex_dynamic_data_t { + DWORD buf_size; + DWORD prop_cnt; + dynamic_prop_t *props; +}; + +#define DISPID_DYNPROP_0 0x50000000 +#define DISPID_DYNPROP_MAX 0x5fffffff + +static struct list dispex_data_list = LIST_INIT(dispex_data_list); +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; +} + +void release_typelib(void) +{ + dispex_data_t *iter; + unsigned i; + + while(!list_empty(&dispex_data_list)) { + iter = LIST_ENTRY(list_head(&dispex_data_list), dispex_data_t, entry); + list_remove(&iter->entry); + + for(i=0; i < iter->func_cnt; i++) + SysFreeString(iter->funcs[i].name); + + heap_free(iter->funcs); + heap_free(iter->name_table); + 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); +} + +static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, DISPID id, ITypeInfo *dti) +{ + HRESULT hres; + + if(data->func_cnt && data->funcs[data->func_cnt-1].id == id) + return; + + if(data->func_cnt == *size) + data->funcs = heap_realloc(data->funcs, (*size <<= 1)*sizeof(func_info_t)); + + hres = ITypeInfo_GetDocumentation(dti, id, &data->funcs[data->func_cnt].name, NULL, NULL, NULL); + if(FAILED(hres)) + return; + + data->funcs[data->func_cnt].id = id; + data->funcs[data->func_cnt].tid = tid; + + data->func_cnt++; +} + +static int dispid_cmp(const void *p1, const void *p2) +{ + return ((func_info_t*)p1)->id - ((func_info_t*)p2)->id; +} + +static int func_name_cmp(const void *p1, const void *p2) +{ + return strcmpiW((*(func_info_t**)p1)->name, (*(func_info_t**)p2)->name); +} + +static dispex_data_t *preprocess_dispex_data(DispatchEx *This) +{ + const tid_t *tid = This->data->iface_tids; + FUNCDESC *funcdesc; + dispex_data_t *data; + DWORD size = 16, i; + ITypeInfo *ti, *dti; + HRESULT hres; + + TRACE("(%p)\n", This); + + hres = get_typeinfo(This->data->disp_tid, &dti); + if(FAILED(hres)) { + ERR("Could not get disp type info: %08x\n", hres); + return NULL; + } + + data = heap_alloc(sizeof(dispex_data_t)); + data->func_cnt = 0; + data->funcs = heap_alloc(size*sizeof(func_info_t)); + list_add_tail(&dispex_data_list, &data->entry); + + while(*tid) { + hres = get_typeinfo(*tid, &ti); + if(FAILED(hres)) + break; + + i=0; + while(1) { + hres = ITypeInfo_GetFuncDesc(ti, i++, &funcdesc); + if(FAILED(hres)) + break; + + add_func_info(data, &size, *tid, funcdesc->memid, dti); + ITypeInfo_ReleaseFuncDesc(ti, funcdesc); + } + + ITypeInfo_Release(ti); + tid++; + } + + if(!data->func_cnt) { + heap_free(data->funcs); + data->funcs = NULL; + }else if(data->func_cnt != size) { + data->funcs = heap_realloc(data->funcs, data->func_cnt * sizeof(func_info_t)); + } + + qsort(data->funcs, data->func_cnt, sizeof(func_info_t), dispid_cmp); + + if(data->funcs) { + data->name_table = heap_alloc(data->func_cnt * sizeof(func_info_t*)); + for(i=0; i < data->func_cnt; i++) + data->name_table[i] = data->funcs+i; + qsort(data->name_table, data->func_cnt, sizeof(func_info_t*), func_name_cmp); + }else { + data->name_table = NULL; + } + + ITypeInfo_Release(dti); + return data; +} + +static CRITICAL_SECTION cs_dispex_static_data; +static CRITICAL_SECTION_DEBUG cs_dispex_static_data_dbg = +{ + 0, 0, &cs_dispex_static_data, + { &cs_dispex_static_data_dbg.ProcessLocksList, &cs_dispex_static_data_dbg.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": dispex_static_data") } +}; +static CRITICAL_SECTION cs_dispex_static_data = { &cs_dispex_static_data_dbg, -1, 0, 0, 0, 0 }; + + +static dispex_data_t *get_dispex_data(DispatchEx *This) +{ + if(This->data->data) + return This->data->data; + + EnterCriticalSection(&cs_dispex_static_data); + + if(!This->data->data) + This->data->data = preprocess_dispex_data(This); + + LeaveCriticalSection(&cs_dispex_static_data); + + return This->data->data; +} + +static inline BOOL is_custom_dispid(DISPID id) +{ + return MSXML_DISPID_CUSTOM_MIN <= id && id <= MSXML_DISPID_CUSTOM_MAX; +} + +static inline BOOL is_dynamic_dispid(DISPID id) +{ + return DISPID_DYNPROP_0 <= id && id <= DISPID_DYNPROP_MAX; +} + +static inline DispatchEx *impl_from_IDispatchEx(IDispatchEx *iface) +{ + return (DispatchEx*)((char*)iface - FIELD_OFFSET(DispatchEx, lpIDispatchExVtbl)); +} + +static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + + return IUnknown_QueryInterface(This->outer, riid, ppv); +} + +static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + + return IUnknown_Release(This->outer); +} + +static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + return S_OK; +} + +static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + return get_typeinfo(This->data->disp_tid, ppTInfo); +} + +static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + UINT i; + HRESULT hres; + + TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, + lcid, rgDispId); + + for(i=0; i < cNames; i++) { + hres = IDispatchEx_GetDispID(DISPATCHEX(This), rgszNames[i], 0, rgDispId+i); + if(FAILED(hres)) + return hres; + } + + return S_OK; +} + +static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + + TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + return IDispatchEx_InvokeEx(DISPATCHEX(This), dispIdMember, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, NULL); +} + +static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + dispex_data_t *data; + int min, max, n, c; + + TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid); + + if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit)) + FIXME("Unsupported grfdex %x\n", grfdex); + + data = get_dispex_data(This); + if(!data) + return E_FAIL; + + min = 0; + max = data->func_cnt-1; + + while(min <= max) { + n = (min+max)/2; + + c = strcmpiW(data->name_table[n]->name, bstrName); + if(!c) { + if((grfdex & fdexNameCaseSensitive) && strcmpW(data->name_table[n]->name, bstrName)) + break; + + *pid = data->name_table[n]->id; + return S_OK; + } + + if(c > 0) + max = n-1; + else + min = n+1; + } + + if(This->dynamic_data) { + unsigned i; + + for(i=0; i < This->dynamic_data->prop_cnt; i++) { + if(!strcmpW(This->dynamic_data->props[i].name, bstrName)) { + *pid = DISPID_DYNPROP_0 + i; + return S_OK; + } + } + } + + if(This->data->vtbl && This->data->vtbl->get_dispid) { + HRESULT hres; + + hres = This->data->vtbl->get_dispid(This->outer, bstrName, grfdex, pid); + if(hres != DISP_E_UNKNOWNNAME) + return hres; + } + + if(grfdex & fdexNameEnsure) { + TRACE("creating dynamic prop %s\n", debugstr_w(bstrName)); + + if(!This->dynamic_data) { + This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t)); + This->dynamic_data->props = heap_alloc(This->dynamic_data->buf_size = 4); + }else if(This->dynamic_data->buf_size == This->dynamic_data->prop_cnt) { + This->dynamic_data->props = heap_realloc(This->dynamic_data->props, This->dynamic_data->buf_size<<=1); + } + + This->dynamic_data->props[This->dynamic_data->prop_cnt].name = heap_strdupW(bstrName); + VariantInit(&This->dynamic_data->props[This->dynamic_data->prop_cnt].var); + *pid = DISPID_DYNPROP_0 + This->dynamic_data->prop_cnt++; + + return S_OK; + } + + TRACE("not found %s\n", debugstr_w(bstrName)); + return DISP_E_UNKNOWNNAME; +} + +static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + IUnknown *unk; + ITypeInfo *ti; + dispex_data_t *data; + UINT argerr=0; + int min, max, n; + HRESULT hres; + + TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); + + if(is_custom_dispid(id) && This->data->vtbl && This->data->vtbl->invoke) + return This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei); + + if(wFlags == DISPATCH_CONSTRUCT) { + FIXME("DISPATCH_CONSTRUCT not implemented\n"); + return E_NOTIMPL; + } + + if(is_dynamic_dispid(id)) { + DWORD idx = id - DISPID_DYNPROP_0; + VARIANT *var; + + if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx) + return DISP_E_UNKNOWNNAME; + + var = &This->dynamic_data->props[idx].var; + + switch(wFlags) { + case INVOKE_PROPERTYGET: + return VariantCopy(pvarRes, var); + case INVOKE_PROPERTYPUT: + VariantClear(var); + return VariantCopy(var, pdp->rgvarg); + default: + FIXME("unhandled wFlags %x\n", wFlags); + return E_NOTIMPL; + } + } + + data = get_dispex_data(This); + if(!data) + return E_FAIL; + + min = 0; + max = data->func_cnt-1; + + while(min <= max) { + n = (min+max)/2; + + if(data->funcs[n].id == id) + break; + + if(data->funcs[n].id < id) + min = n+1; + else + max = n-1; + } + + if(min > max) { + WARN("invalid id %x\n", id); + return DISP_E_UNKNOWNNAME; + } + + hres = get_typeinfo(data->funcs[n].tid, &ti); + if(FAILED(hres)) { + ERR("Could not get type info: %08x\n", hres); + return hres; + } + + hres = IUnknown_QueryInterface(This->outer, tid_ids[data->funcs[n].tid], (void**)&unk); + if(FAILED(hres)) { + ERR("Could not get iface: %08x\n", hres); + return E_FAIL; + } + + hres = ITypeInfo_Invoke(ti, unk, id, wFlags, pdp, pvarRes, pei, &argerr); + + ITypeInfo_Release(ti); + IUnknown_Release(unk); + return hres; +} + +static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + FIXME("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex); + return S_OK; +} + +static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + FIXME("(%p)->(%x)\n", This, id); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + FIXME("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + FIXME("(%p)->(%x %p)\n", This, id, pbstrName); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + FIXME("(%p)->(%x %x %p)\n", This, grfdex, id, pid); + return E_NOTIMPL; +} + +static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk) +{ + DispatchEx *This = impl_from_IDispatchEx(iface); + FIXME("(%p)->(%p)\n", This, ppunk); + return E_NOTIMPL; +} + +static IDispatchExVtbl DispatchExVtbl = { + DispatchEx_QueryInterface, + DispatchEx_AddRef, + DispatchEx_Release, + DispatchEx_GetTypeInfoCount, + DispatchEx_GetTypeInfo, + DispatchEx_GetIDsOfNames, + DispatchEx_Invoke, + DispatchEx_GetDispID, + DispatchEx_InvokeEx, + DispatchEx_DeleteMemberByName, + DispatchEx_DeleteMemberByDispID, + DispatchEx_GetMemberProperties, + DispatchEx_GetMemberName, + DispatchEx_GetNextDispID, + DispatchEx_GetNameSpaceParent +}; + +BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv) +{ + static const IID IID_UndocumentedScriptIface = + {0x719c3050,0xf9d3,0x11cf,{0xa4,0x93,0x00,0x40,0x05,0x23,0xa8,0xa0}}; + + if(IsEqualGUID(&IID_IDispatch, riid)) { + TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); + *ppv = DISPATCHEX(This); + }else if(IsEqualGUID(&IID_IDispatchEx, riid)) { + TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv); + *ppv = DISPATCHEX(This); + }else if(IsEqualGUID(&IID_UndocumentedScriptIface, riid)) { + TRACE("(%p)->(IID_UndocumentedScriptIface %p) returning NULL\n", This, ppv); + *ppv = NULL; + }else { + return FALSE; + } + + if(*ppv) + IUnknown_AddRef((IUnknown*)*ppv); + return TRUE; +} + +void init_dispex(DispatchEx *dispex, IUnknown *outer, dispex_static_data_t *data) +{ + dispex->lpIDispatchExVtbl = &DispatchExVtbl; + dispex->outer = outer; + dispex->data = data; +} diff --git a/reactos/dll/win32/msxml3/docfrag.c b/reactos/dll/win32/msxml3/docfrag.c new file mode 100644 index 00000000000..f922faaa229 --- /dev/null +++ b/reactos/dll/win32/msxml3/docfrag.c @@ -0,0 +1,552 @@ +/* + * DOM Document Fragment implementation + * + * Copyright 2007 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "config.h" + +#include +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" +#include "msxml2.h" + +#include "msxml_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msxml); + +#ifdef HAVE_LIBXML2 + +typedef struct _domfrag +{ + const struct IXMLDOMDocumentFragmentVtbl *lpVtbl; + LONG ref; + IUnknown *node_unk; + IXMLDOMNode *node; +} domfrag; + +static inline domfrag *impl_from_IXMLDOMDocumentFragment( IXMLDOMDocumentFragment *iface ) +{ + return (domfrag *)((char*)iface - FIELD_OFFSET(domfrag, lpVtbl)); +} + +static HRESULT WINAPI domfrag_QueryInterface( + IXMLDOMDocumentFragment *iface, + REFIID riid, + void** ppvObject ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); + + if ( IsEqualGUID( riid, &IID_IXMLDOMDocumentFragment ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) ) + { + return IUnknown_QueryInterface(This->node_unk, riid, ppvObject); + } + else + { + FIXME("Unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IXMLDOMDocumentFragment_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI domfrag_AddRef( + IXMLDOMDocumentFragment *iface ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI domfrag_Release( + IXMLDOMDocumentFragment *iface ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + ULONG ref; + + ref = InterlockedDecrement( &This->ref ); + if ( ref == 0 ) + { + IUnknown_Release( This->node_unk ); + HeapFree( GetProcessHeap(), 0, This ); + } + + return ref; +} + +static HRESULT WINAPI domfrag_GetTypeInfoCount( + IXMLDOMDocumentFragment *iface, + UINT* pctinfo ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + + return S_OK; +} + +static HRESULT WINAPI domfrag_GetTypeInfo( + IXMLDOMDocumentFragment *iface, + UINT iTInfo, LCID lcid, + ITypeInfo** ppTInfo ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + HRESULT hr; + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + hr = get_typeinfo(IXMLDOMDocumentFragment_tid, ppTInfo); + + return hr; +} + +static HRESULT WINAPI domfrag_GetIDsOfNames( + IXMLDOMDocumentFragment *iface, + REFIID riid, LPOLESTR* rgszNames, + UINT cNames, LCID lcid, DISPID* rgDispId ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( 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(IXMLDOMDocumentFragment_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI domfrag_Invoke( + IXMLDOMDocumentFragment *iface, + DISPID dispIdMember, REFIID riid, LCID lcid, + WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, UINT* puArgErr ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( 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(IXMLDOMDocumentFragment_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI domfrag_get_nodeName( + IXMLDOMDocumentFragment *iface, + BSTR* p ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_nodeName( This->node, p ); +} + +static HRESULT WINAPI domfrag_get_nodeValue( + IXMLDOMDocumentFragment *iface, + VARIANT* var1 ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_nodeValue( This->node, var1 ); +} + +static HRESULT WINAPI domfrag_put_nodeValue( + IXMLDOMDocumentFragment *iface, + VARIANT var1 ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_put_nodeValue( This->node, var1 ); +} + +static HRESULT WINAPI domfrag_get_nodeType( + IXMLDOMDocumentFragment *iface, + DOMNodeType* domNodeType ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_nodeType( This->node, domNodeType ); +} + +static HRESULT WINAPI domfrag_get_parentNode( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode** parent ) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_parentNode( This->node, parent ); +} + +static HRESULT WINAPI domfrag_get_childNodes( + IXMLDOMDocumentFragment *iface, + IXMLDOMNodeList** outList) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_childNodes( This->node, outList ); +} + +static HRESULT WINAPI domfrag_get_firstChild( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode** domNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_firstChild( This->node, domNode ); +} + +static HRESULT WINAPI domfrag_get_lastChild( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode** domNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_lastChild( This->node, domNode ); +} + +static HRESULT WINAPI domfrag_get_previousSibling( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode** domNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_previousSibling( This->node, domNode ); +} + +static HRESULT WINAPI domfrag_get_nextSibling( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode** domNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_nextSibling( This->node, domNode ); +} + +static HRESULT WINAPI domfrag_get_attributes( + IXMLDOMDocumentFragment *iface, + IXMLDOMNamedNodeMap** attributeMap) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_attributes( This->node, attributeMap ); +} + +static HRESULT WINAPI domfrag_insertBefore( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode* newNode, VARIANT var1, + IXMLDOMNode** outOldNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_insertBefore( This->node, newNode, var1, outOldNode ); +} + +static HRESULT WINAPI domfrag_replaceChild( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode* newNode, + IXMLDOMNode* oldNode, + IXMLDOMNode** outOldNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_replaceChild( This->node, newNode, oldNode, outOldNode ); +} + +static HRESULT WINAPI domfrag_removeChild( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode* domNode, IXMLDOMNode** oldNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_removeChild( This->node, domNode, oldNode ); +} + +static HRESULT WINAPI domfrag_appendChild( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode* newNode, IXMLDOMNode** outNewNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_appendChild( This->node, newNode, outNewNode ); +} + +static HRESULT WINAPI domfrag_hasChildNodes( + IXMLDOMDocumentFragment *iface, + VARIANT_BOOL* pbool) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_hasChildNodes( This->node, pbool ); +} + +static HRESULT WINAPI domfrag_get_ownerDocument( + IXMLDOMDocumentFragment *iface, + IXMLDOMDocument** domDocument) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_ownerDocument( This->node, domDocument ); +} + +static HRESULT WINAPI domfrag_cloneNode( + IXMLDOMDocumentFragment *iface, + VARIANT_BOOL pbool, IXMLDOMNode** outNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_cloneNode( This->node, pbool, outNode ); +} + +static HRESULT WINAPI domfrag_get_nodeTypeString( + IXMLDOMDocumentFragment *iface, + BSTR* p) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_nodeTypeString( This->node, p ); +} + +static HRESULT WINAPI domfrag_get_text( + IXMLDOMDocumentFragment *iface, + BSTR* p) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_text( This->node, p ); +} + +static HRESULT WINAPI domfrag_put_text( + IXMLDOMDocumentFragment *iface, + BSTR p) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_put_text( This->node, p ); +} + +static HRESULT WINAPI domfrag_get_specified( + IXMLDOMDocumentFragment *iface, + VARIANT_BOOL* pbool) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_specified( This->node, pbool ); +} + +static HRESULT WINAPI domfrag_get_definition( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode** domNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_definition( This->node, domNode ); +} + +static HRESULT WINAPI domfrag_get_nodeTypedValue( + IXMLDOMDocumentFragment *iface, + VARIANT* var1) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_nodeTypedValue( This->node, var1 ); +} + +static HRESULT WINAPI domfrag_put_nodeTypedValue( + IXMLDOMDocumentFragment *iface, + VARIANT var1) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_put_nodeTypedValue( This->node, var1 ); +} + +static HRESULT WINAPI domfrag_get_dataType( + IXMLDOMDocumentFragment *iface, + VARIANT* var1) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_dataType( This->node, var1 ); +} + +static HRESULT WINAPI domfrag_put_dataType( + IXMLDOMDocumentFragment *iface, + BSTR p) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_put_dataType( This->node, p ); +} + +static HRESULT WINAPI domfrag_get_xml( + IXMLDOMDocumentFragment *iface, + BSTR* p) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_xml( This->node, p ); +} + +static HRESULT WINAPI domfrag_transformNode( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode* domNode, BSTR* p) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_transformNode( This->node, domNode, p ); +} + +static HRESULT WINAPI domfrag_selectNodes( + IXMLDOMDocumentFragment *iface, + BSTR p, IXMLDOMNodeList** outList) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_selectNodes( This->node, p, outList ); +} + +static HRESULT WINAPI domfrag_selectSingleNode( + IXMLDOMDocumentFragment *iface, + BSTR p, IXMLDOMNode** outNode) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_selectSingleNode( This->node, p, outNode ); +} + +static HRESULT WINAPI domfrag_get_parsed( + IXMLDOMDocumentFragment *iface, + VARIANT_BOOL* pbool) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_parsed( This->node, pbool ); +} + +static HRESULT WINAPI domfrag_get_namespaceURI( + IXMLDOMDocumentFragment *iface, + BSTR* p) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_namespaceURI( This->node, p ); +} + +static HRESULT WINAPI domfrag_get_prefix( + IXMLDOMDocumentFragment *iface, + BSTR* p) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_prefix( This->node, p ); +} + +static HRESULT WINAPI domfrag_get_baseName( + IXMLDOMDocumentFragment *iface, + BSTR* p) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_get_baseName( This->node, p ); +} + +static HRESULT WINAPI domfrag_transformNodeToObject( + IXMLDOMDocumentFragment *iface, + IXMLDOMNode* domNode, VARIANT var1) +{ + domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); + return IXMLDOMNode_transformNodeToObject( This->node, domNode, var1 ); +} + +static const struct IXMLDOMDocumentFragmentVtbl domfrag_vtbl = +{ + domfrag_QueryInterface, + domfrag_AddRef, + domfrag_Release, + domfrag_GetTypeInfoCount, + domfrag_GetTypeInfo, + domfrag_GetIDsOfNames, + domfrag_Invoke, + domfrag_get_nodeName, + domfrag_get_nodeValue, + domfrag_put_nodeValue, + domfrag_get_nodeType, + domfrag_get_parentNode, + domfrag_get_childNodes, + domfrag_get_firstChild, + domfrag_get_lastChild, + domfrag_get_previousSibling, + domfrag_get_nextSibling, + domfrag_get_attributes, + domfrag_insertBefore, + domfrag_replaceChild, + domfrag_removeChild, + domfrag_appendChild, + domfrag_hasChildNodes, + domfrag_get_ownerDocument, + domfrag_cloneNode, + domfrag_get_nodeTypeString, + domfrag_get_text, + domfrag_put_text, + domfrag_get_specified, + domfrag_get_definition, + domfrag_get_nodeTypedValue, + domfrag_put_nodeTypedValue, + domfrag_get_dataType, + domfrag_put_dataType, + domfrag_get_xml, + domfrag_transformNode, + domfrag_selectNodes, + domfrag_selectSingleNode, + domfrag_get_parsed, + domfrag_get_namespaceURI, + domfrag_get_prefix, + domfrag_get_baseName, + domfrag_transformNodeToObject +}; + +IUnknown* create_doc_fragment( xmlNodePtr fragment ) +{ + domfrag *This; + HRESULT hr; + + This = HeapAlloc( GetProcessHeap(), 0, sizeof *This ); + if ( !This ) + return NULL; + + This->lpVtbl = &domfrag_vtbl; + This->ref = 1; + + This->node_unk = create_basic_node( fragment, (IUnknown*)&This->lpVtbl ); + if(!This->node_unk) + { + HeapFree(GetProcessHeap(), 0, This); + return NULL; + } + + hr = IUnknown_QueryInterface(This->node_unk, &IID_IXMLDOMNode, (LPVOID*)&This->node); + if(FAILED(hr)) + { + IUnknown_Release(This->node_unk); + HeapFree( GetProcessHeap(), 0, This ); + return NULL; + } + /* The ref on This->node is actually looped back into this object, so release it */ + IXMLDOMNode_Release(This->node); + + return (IUnknown*) &This->lpVtbl; +} + +#endif diff --git a/reactos/dll/win32/msxml3/domimpl.c b/reactos/dll/win32/msxml3/domimpl.c new file mode 100644 index 00000000000..b0b1cdead0e --- /dev/null +++ b/reactos/dll/win32/msxml3/domimpl.c @@ -0,0 +1,229 @@ +/* + * DOM Document Implementation implementation + * + * Copyright 2007 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "config.h" + +#include +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" +#include "msxml2.h" + +#include "msxml_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msxml); + +#ifdef HAVE_LIBXML2 + +typedef struct _domimpl +{ + const struct IXMLDOMImplementationVtbl *lpVtbl; + LONG ref; +} domimpl; + +static inline domimpl *impl_from_IXMLDOMImplementation( IXMLDOMImplementation *iface ) +{ + return (domimpl *)((char*)iface - FIELD_OFFSET(domimpl, lpVtbl)); +} + +static HRESULT WINAPI dimimpl_QueryInterface( + IXMLDOMImplementation *iface, + REFIID riid, + void** ppvObject ) +{ + domimpl *This = impl_from_IXMLDOMImplementation( iface ); + TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); + + if ( IsEqualGUID( riid, &IID_IXMLDOMImplementation ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else + { + FIXME("Unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IXMLDOMImplementation_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI dimimpl_AddRef( + IXMLDOMImplementation *iface ) +{ + domimpl *This = impl_from_IXMLDOMImplementation( iface ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI dimimpl_Release( + IXMLDOMImplementation *iface ) +{ + domimpl *This = impl_from_IXMLDOMImplementation( iface ); + ULONG ref; + + ref = InterlockedDecrement( &This->ref ); + if ( ref == 0 ) + { + HeapFree( GetProcessHeap(), 0, This ); + } + + return ref; +} + +static HRESULT WINAPI dimimpl_GetTypeInfoCount( + IXMLDOMImplementation *iface, + UINT* pctinfo ) +{ + domimpl *This = impl_from_IXMLDOMImplementation( iface ); + + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + + return S_OK; +} + +static HRESULT WINAPI dimimpl_GetTypeInfo( + IXMLDOMImplementation *iface, + UINT iTInfo, LCID lcid, + ITypeInfo** ppTInfo ) +{ + domimpl *This = impl_from_IXMLDOMImplementation( iface ); + HRESULT hr; + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + hr = get_typeinfo(IXMLDOMImplementation_tid, ppTInfo); + + return hr; +} + +static HRESULT WINAPI dimimpl_GetIDsOfNames( + IXMLDOMImplementation *iface, + REFIID riid, LPOLESTR* rgszNames, + UINT cNames, LCID lcid, DISPID* rgDispId ) +{ + domimpl *This = impl_from_IXMLDOMImplementation( 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(IXMLDOMImplementation_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI dimimpl_Invoke( + IXMLDOMImplementation *iface, + DISPID dispIdMember, REFIID riid, LCID lcid, + WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, UINT* puArgErr ) +{ + domimpl *This = impl_from_IXMLDOMImplementation( 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(IXMLDOMImplementation_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI dimimpl_hasFeature(IXMLDOMImplementation* This, BSTR feature, BSTR version, VARIANT_BOOL *hasFeature) +{ + static const WCHAR bVersion[] = {'1','.','0',0}; + static const WCHAR bXML[] = {'X','M','L',0}; + static const WCHAR bDOM[] = {'D','O','M',0}; + static const WCHAR bMSDOM[] = {'M','S','-','D','O','M',0}; + BOOL bValidFeature = FALSE; + BOOL bValidVersion = FALSE; + + TRACE("feature(%s) version (%s)\n", debugstr_w(feature), debugstr_w(version)); + + if(!feature || !hasFeature) + return E_INVALIDARG; + + *hasFeature = VARIANT_FALSE; + + if(!version || lstrcmpiW(version, bVersion) == 0) + bValidVersion = TRUE; + + if(lstrcmpiW(feature, bXML) == 0 || lstrcmpiW(feature, bDOM) == 0 || lstrcmpiW(feature, bMSDOM) == 0) + bValidFeature = TRUE; + + if(bValidVersion && bValidFeature) + *hasFeature = VARIANT_TRUE; + + return S_OK; +} + +static const struct IXMLDOMImplementationVtbl dimimpl_vtbl = +{ + dimimpl_QueryInterface, + dimimpl_AddRef, + dimimpl_Release, + dimimpl_GetTypeInfoCount, + dimimpl_GetTypeInfo, + dimimpl_GetIDsOfNames, + dimimpl_Invoke, + dimimpl_hasFeature +}; + +IUnknown* create_doc_Implementation(void) +{ + domimpl *This; + + This = HeapAlloc( GetProcessHeap(), 0, sizeof *This ); + if ( !This ) + return NULL; + + This->lpVtbl = &dimimpl_vtbl; + This->ref = 1; + + return (IUnknown*) &This->lpVtbl; +} + +#endif diff --git a/reactos/dll/win32/msxml3/entityref.c b/reactos/dll/win32/msxml3/entityref.c new file mode 100644 index 00000000000..a72b11022e7 --- /dev/null +++ b/reactos/dll/win32/msxml3/entityref.c @@ -0,0 +1,551 @@ +/* + * DOM Entity Reference implementation + * + * Copyright 2007 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "config.h" + +#include +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" +#include "msxml2.h" + +#include "msxml_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msxml); + +#ifdef HAVE_LIBXML2 + +typedef struct _entityref +{ + const struct IXMLDOMEntityReferenceVtbl *lpVtbl; + LONG ref; + IUnknown *node_unk; + IXMLDOMNode *node; +} entityref; + +static inline entityref *impl_from_IXMLDOMEntityReference( IXMLDOMEntityReference *iface ) +{ + return (entityref *)((char*)iface - FIELD_OFFSET(entityref, lpVtbl)); +} + +static HRESULT WINAPI entityref_QueryInterface( + IXMLDOMEntityReference *iface, + REFIID riid, + void** ppvObject ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); + + if ( IsEqualGUID( riid, &IID_IXMLDOMEntityReference ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown ) ) + { + *ppvObject = iface; + } + else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) ) + { + return IUnknown_QueryInterface(This->node_unk, riid, ppvObject); + } + else + { + FIXME("Unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IXMLDOMEntityReference_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI entityref_AddRef( + IXMLDOMEntityReference *iface ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI entityref_Release( + IXMLDOMEntityReference *iface ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + ULONG ref; + + ref = InterlockedDecrement( &This->ref ); + if ( ref == 0 ) + { + IUnknown_Release( This->node_unk ); + HeapFree( GetProcessHeap(), 0, This ); + } + + return ref; +} + +static HRESULT WINAPI entityref_GetTypeInfoCount( + IXMLDOMEntityReference *iface, + UINT* pctinfo ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + + return S_OK; +} + +static HRESULT WINAPI entityref_GetTypeInfo( + IXMLDOMEntityReference *iface, + UINT iTInfo, LCID lcid, + ITypeInfo** ppTInfo ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + HRESULT hr; + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + hr = get_typeinfo(IXMLDOMEntityReference_tid, ppTInfo); + + return hr; +} + +static HRESULT WINAPI entityref_GetIDsOfNames( + IXMLDOMEntityReference *iface, + REFIID riid, LPOLESTR* rgszNames, + UINT cNames, LCID lcid, DISPID* rgDispId ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( 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(IXMLDOMEntityReference_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI entityref_Invoke( + IXMLDOMEntityReference *iface, + DISPID dispIdMember, REFIID riid, LCID lcid, + WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, UINT* puArgErr ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( 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(IXMLDOMEntityReference_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI entityref_get_nodeName( + IXMLDOMEntityReference *iface, + BSTR* p ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_nodeName( This->node, p ); +} + +static HRESULT WINAPI entityref_get_nodeValue( + IXMLDOMEntityReference *iface, + VARIANT* var1 ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_nodeValue( This->node, var1 ); +} + +static HRESULT WINAPI entityref_put_nodeValue( + IXMLDOMEntityReference *iface, + VARIANT var1 ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_put_nodeValue( This->node, var1 ); +} + +static HRESULT WINAPI entityref_get_nodeType( + IXMLDOMEntityReference *iface, + DOMNodeType* domNodeType ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_nodeType( This->node, domNodeType ); +} + +static HRESULT WINAPI entityref_get_parentNode( + IXMLDOMEntityReference *iface, + IXMLDOMNode** parent ) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_parentNode( This->node, parent ); +} + +static HRESULT WINAPI entityref_get_childNodes( + IXMLDOMEntityReference *iface, + IXMLDOMNodeList** outList) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_childNodes( This->node, outList ); +} + +static HRESULT WINAPI entityref_get_firstChild( + IXMLDOMEntityReference *iface, + IXMLDOMNode** domNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_firstChild( This->node, domNode ); +} + +static HRESULT WINAPI entityref_get_lastChild( + IXMLDOMEntityReference *iface, + IXMLDOMNode** domNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_lastChild( This->node, domNode ); +} + +static HRESULT WINAPI entityref_get_previousSibling( + IXMLDOMEntityReference *iface, + IXMLDOMNode** domNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_previousSibling( This->node, domNode ); +} + +static HRESULT WINAPI entityref_get_nextSibling( + IXMLDOMEntityReference *iface, + IXMLDOMNode** domNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_nextSibling( This->node, domNode ); +} + +static HRESULT WINAPI entityref_get_attributes( + IXMLDOMEntityReference *iface, + IXMLDOMNamedNodeMap** attributeMap) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_attributes( This->node, attributeMap ); +} + +static HRESULT WINAPI entityref_insertBefore( + IXMLDOMEntityReference *iface, + IXMLDOMNode* newNode, VARIANT var1, + IXMLDOMNode** outOldNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_insertBefore( This->node, newNode, var1, outOldNode ); +} + +static HRESULT WINAPI entityref_replaceChild( + IXMLDOMEntityReference *iface, + IXMLDOMNode* newNode, + IXMLDOMNode* oldNode, + IXMLDOMNode** outOldNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_replaceChild( This->node, newNode, oldNode, outOldNode ); +} + +static HRESULT WINAPI entityref_removeChild( + IXMLDOMEntityReference *iface, + IXMLDOMNode* domNode, IXMLDOMNode** oldNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_removeChild( This->node, domNode, oldNode ); +} + +static HRESULT WINAPI entityref_appendChild( + IXMLDOMEntityReference *iface, + IXMLDOMNode* newNode, IXMLDOMNode** outNewNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_appendChild( This->node, newNode, outNewNode ); +} + +static HRESULT WINAPI entityref_hasChildNodes( + IXMLDOMEntityReference *iface, + VARIANT_BOOL* pbool) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_hasChildNodes( This->node, pbool ); +} + +static HRESULT WINAPI entityref_get_ownerDocument( + IXMLDOMEntityReference *iface, + IXMLDOMDocument** domDocument) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_ownerDocument( This->node, domDocument ); +} + +static HRESULT WINAPI entityref_cloneNode( + IXMLDOMEntityReference *iface, + VARIANT_BOOL pbool, IXMLDOMNode** outNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_cloneNode( This->node, pbool, outNode ); +} + +static HRESULT WINAPI entityref_get_nodeTypeString( + IXMLDOMEntityReference *iface, + BSTR* p) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_nodeTypeString( This->node, p ); +} + +static HRESULT WINAPI entityref_get_text( + IXMLDOMEntityReference *iface, + BSTR* p) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_text( This->node, p ); +} + +static HRESULT WINAPI entityref_put_text( + IXMLDOMEntityReference *iface, + BSTR p) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_put_text( This->node, p ); +} + +static HRESULT WINAPI entityref_get_specified( + IXMLDOMEntityReference *iface, + VARIANT_BOOL* pbool) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_specified( This->node, pbool ); +} + +static HRESULT WINAPI entityref_get_definition( + IXMLDOMEntityReference *iface, + IXMLDOMNode** domNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_definition( This->node, domNode ); +} + +static HRESULT WINAPI entityref_get_nodeTypedValue( + IXMLDOMEntityReference *iface, + VARIANT* var1) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_nodeTypedValue( This->node, var1 ); +} + +static HRESULT WINAPI entityref_put_nodeTypedValue( + IXMLDOMEntityReference *iface, + VARIANT var1) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_put_nodeTypedValue( This->node, var1 ); +} + +static HRESULT WINAPI entityref_get_dataType( + IXMLDOMEntityReference *iface, + VARIANT* var1) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_dataType( This->node, var1 ); +} + +static HRESULT WINAPI entityref_put_dataType( + IXMLDOMEntityReference *iface, + BSTR p) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_put_dataType( This->node, p ); +} + +static HRESULT WINAPI entityref_get_xml( + IXMLDOMEntityReference *iface, + BSTR* p) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_xml( This->node, p ); +} + +static HRESULT WINAPI entityref_transformNode( + IXMLDOMEntityReference *iface, + IXMLDOMNode* domNode, BSTR* p) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_transformNode( This->node, domNode, p ); +} + +static HRESULT WINAPI entityref_selectNodes( + IXMLDOMEntityReference *iface, + BSTR p, IXMLDOMNodeList** outList) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_selectNodes( This->node, p, outList ); +} + +static HRESULT WINAPI entityref_selectSingleNode( + IXMLDOMEntityReference *iface, + BSTR p, IXMLDOMNode** outNode) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_selectSingleNode( This->node, p, outNode ); +} + +static HRESULT WINAPI entityref_get_parsed( + IXMLDOMEntityReference *iface, + VARIANT_BOOL* pbool) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_parsed( This->node, pbool ); +} + +static HRESULT WINAPI entityref_get_namespaceURI( + IXMLDOMEntityReference *iface, + BSTR* p) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_namespaceURI( This->node, p ); +} + +static HRESULT WINAPI entityref_get_prefix( + IXMLDOMEntityReference *iface, + BSTR* p) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_prefix( This->node, p ); +} + +static HRESULT WINAPI entityref_get_baseName( + IXMLDOMEntityReference *iface, + BSTR* p) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_get_baseName( This->node, p ); +} + +static HRESULT WINAPI entityref_transformNodeToObject( + IXMLDOMEntityReference *iface, + IXMLDOMNode* domNode, VARIANT var1) +{ + entityref *This = impl_from_IXMLDOMEntityReference( iface ); + return IXMLDOMNode_transformNodeToObject( This->node, domNode, var1 ); +} + +static const struct IXMLDOMEntityReferenceVtbl entityref_vtbl = +{ + entityref_QueryInterface, + entityref_AddRef, + entityref_Release, + entityref_GetTypeInfoCount, + entityref_GetTypeInfo, + entityref_GetIDsOfNames, + entityref_Invoke, + entityref_get_nodeName, + entityref_get_nodeValue, + entityref_put_nodeValue, + entityref_get_nodeType, + entityref_get_parentNode, + entityref_get_childNodes, + entityref_get_firstChild, + entityref_get_lastChild, + entityref_get_previousSibling, + entityref_get_nextSibling, + entityref_get_attributes, + entityref_insertBefore, + entityref_replaceChild, + entityref_removeChild, + entityref_appendChild, + entityref_hasChildNodes, + entityref_get_ownerDocument, + entityref_cloneNode, + entityref_get_nodeTypeString, + entityref_get_text, + entityref_put_text, + entityref_get_specified, + entityref_get_definition, + entityref_get_nodeTypedValue, + entityref_put_nodeTypedValue, + entityref_get_dataType, + entityref_put_dataType, + entityref_get_xml, + entityref_transformNode, + entityref_selectNodes, + entityref_selectSingleNode, + entityref_get_parsed, + entityref_get_namespaceURI, + entityref_get_prefix, + entityref_get_baseName, + entityref_transformNodeToObject, +}; + +IUnknown* create_doc_entity_ref( xmlNodePtr entity ) +{ + entityref *This; + HRESULT hr; + + This = HeapAlloc( GetProcessHeap(), 0, sizeof *This ); + if ( !This ) + return NULL; + + This->lpVtbl = &entityref_vtbl; + This->ref = 1; + + This->node_unk = create_basic_node( entity, (IUnknown*)&This->lpVtbl ); + if(!This->node_unk) + { + HeapFree(GetProcessHeap(), 0, This); + return NULL; + } + + hr = IUnknown_QueryInterface(This->node_unk, &IID_IXMLDOMNode, (LPVOID*)&This->node); + if(FAILED(hr)) + { + IUnknown_Release(This->node_unk); + HeapFree( GetProcessHeap(), 0, This ); + return NULL; + } + /* The ref on This->node is actually looped back into this object, so release it */ + IXMLDOMNode_Release(This->node); + + return (IUnknown*) &This->lpVtbl; +} + +#endif diff --git a/reactos/dll/win32/msxml3/msxml3_v1.idl b/reactos/dll/win32/msxml3/msxml3_v1.idl new file mode 100644 index 00000000000..d80833fafb6 --- /dev/null +++ b/reactos/dll/win32/msxml3/msxml3_v1.idl @@ -0,0 +1,19 @@ +/* + * Copyright 2007 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "msxml2.idl" diff --git a/reactos/dll/win32/msxml3/saxreader.c b/reactos/dll/win32/msxml3/saxreader.c new file mode 100644 index 00000000000..ef62c9f7840 --- /dev/null +++ b/reactos/dll/win32/msxml3/saxreader.c @@ -0,0 +1,2569 @@ +/* + * SAX Reader implementation + * + * Copyright 2008 Alistair Leslie-Hughes + * Copyright 2008 Piotr Caban + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define COBJMACROS + +#include "config.h" + +#include +#include +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" +#include "ole2.h" +#include "msxml2.h" +#include "wininet.h" +#include "urlmon.h" +#include "winreg.h" +#include "shlwapi.h" + +#include "wine/debug.h" + +#include "msxml_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msxml); + +#ifdef HAVE_LIBXML2 + +#include +#include + +typedef struct _saxreader +{ + const struct IVBSAXXMLReaderVtbl *lpVBSAXXMLReaderVtbl; + const struct ISAXXMLReaderVtbl *lpSAXXMLReaderVtbl; + LONG ref; + struct ISAXContentHandler *contentHandler; + struct IVBSAXContentHandler *vbcontentHandler; + struct ISAXErrorHandler *errorHandler; + struct IVBSAXErrorHandler *vberrorHandler; + xmlSAXHandler sax; +} saxreader; + +typedef struct _saxlocator +{ + const struct IVBSAXLocatorVtbl *lpVBSAXLocatorVtbl; + const struct ISAXLocatorVtbl *lpSAXLocatorVtbl; + LONG ref; + saxreader *saxreader; + HRESULT ret; + xmlParserCtxtPtr pParserCtxt; + WCHAR *publicId; + WCHAR *systemId; + xmlChar *lastCur; + int line; + int column; + BOOL vbInterface; + int nsStackSize; + int nsStackLast; + int *nsStack; +} saxlocator; + +typedef struct _saxattributes +{ + const struct IVBSAXAttributesVtbl *lpVBSAXAttributesVtbl; + const struct ISAXAttributesVtbl *lpSAXAttributesVtbl; + LONG ref; + int nb_attributes; + BSTR *szLocalname; + BSTR *szURI; + BSTR *szValue; + BSTR *szQName; +} saxattributes; + +static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface ) +{ + return (saxreader *)((char*)iface - FIELD_OFFSET(saxreader, lpVBSAXXMLReaderVtbl)); +} + +static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface ) +{ + return (saxreader *)((char*)iface - FIELD_OFFSET(saxreader, lpSAXXMLReaderVtbl)); +} + +static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface ) +{ + return (saxlocator *)((char*)iface - FIELD_OFFSET(saxlocator, lpVBSAXLocatorVtbl)); +} + +static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface ) +{ + return (saxlocator *)((char*)iface - FIELD_OFFSET(saxlocator, lpSAXLocatorVtbl)); +} + +static inline saxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface ) +{ + return (saxattributes *)((char*)iface - FIELD_OFFSET(saxattributes, lpVBSAXAttributesVtbl)); +} + +static inline saxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface ) +{ + return (saxattributes *)((char*)iface - FIELD_OFFSET(saxattributes, lpSAXAttributesVtbl)); +} + + +static HRESULT namespacePush(saxlocator *locator, int ns) +{ + if(locator->nsStackLast>=locator->nsStackSize) + { + int *new_stack; + + new_stack = HeapReAlloc(GetProcessHeap(), 0, + locator->nsStack, locator->nsStackSize*2); + if(!new_stack) return E_OUTOFMEMORY; + locator->nsStack = new_stack; + locator->nsStackSize *= 2; + } + locator->nsStack[locator->nsStackLast++] = ns; + + return S_OK; +} + +static int namespacePop(saxlocator *locator) +{ + if(locator->nsStackLast == 0) return 0; + return locator->nsStack[--locator->nsStackLast]; +} + +static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len) +{ + DWORD dLen; + LPWSTR str; + BSTR bstr; + + if (!buf) + return NULL; + + dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0); + if(len != -1) dLen++; + str = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dLen * sizeof (WCHAR)); + if (!str) + return NULL; + MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, str, dLen); + if(len != -1) str[dLen-1] = '\0'; + bstr = SysAllocString(str); + HeapFree(GetProcessHeap(), 0, str); + + return bstr; +} + +static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name) +{ + DWORD dLen, dLast; + LPWSTR str; + BSTR bstr; + + if(!name) return NULL; + + if(!prefix || *prefix=='\0') + return bstr_from_xmlChar(name); + + dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)prefix, -1, NULL, 0) + + MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1, NULL, 0); + str = HeapAlloc(GetProcessHeap(), 0, dLen * sizeof(WCHAR)); + if(!str) + return NULL; + + dLast = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)prefix, -1, str, dLen); + str[dLast-1] = ':'; + MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1, &str[dLast], dLen-dLast); + bstr = SysAllocString(str); + + HeapFree(GetProcessHeap(), 0, str); + + return bstr; +} + +static void format_error_message_from_id(saxlocator *This, HRESULT hr) +{ + xmlStopParser(This->pParserCtxt); + This->ret = hr; + + if((This->vbInterface && This->saxreader->vberrorHandler) + || (!This->vbInterface && This->saxreader->errorHandler)) + { + WCHAR msg[1024]; + if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, hr, 0, msg, sizeof(msg), NULL)) + { + FIXME("MSXML errors not yet supported.\n"); + msg[0] = '\0'; + } + + if(This->vbInterface) + { + BSTR bstrMsg = SysAllocString(msg); + IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler, + (IVBSAXLocator*)&This->lpVBSAXLocatorVtbl, &bstrMsg, hr); + } + else + ISAXErrorHandler_fatalError(This->saxreader->errorHandler, + (ISAXLocator*)&This->lpSAXLocatorVtbl, msg, hr); + } +} + +static void update_position(saxlocator *This, xmlChar *end) +{ + if(This->lastCur == NULL) + { + This->lastCur = (xmlChar*)This->pParserCtxt->input->base; + This->line = 1; + This->column = 1; + } + else if(This->lastCur < This->pParserCtxt->input->base) + { + This->lastCur = (xmlChar*)This->pParserCtxt->input->base; + This->line = 1; + This->column = 1; + } + + if(!end) end = (xmlChar*)This->pParserCtxt->input->cur; + + while(This->lastCur < end) + { + if(*(This->lastCur) == '\n') + { + This->line++; + This->column = 1; + } + else if(*(This->lastCur) == '\r' && (This->lastCur==This->pParserCtxt->input->end || *(This->lastCur+1)!='\n')) + { + This->line++; + This->column = 1; + } + else This->column++; + + This->lastCur++; + } +} + +/*** IVBSAXAttributes interface ***/ +/*** IUnknown methods ***/ +static HRESULT WINAPI ivbsaxattributes_QueryInterface( + IVBSAXAttributes* iface, + REFIID riid, + void **ppvObject) +{ + saxattributes *This = impl_from_IVBSAXAttributes(iface); + + TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); + + *ppvObject = NULL; + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IVBSAXAttributes)) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IVBSAXAttributes_AddRef(iface); + + return S_OK; +} + +static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface) +{ + saxattributes *This = impl_from_IVBSAXAttributes(iface); + return ISAXAttributes_AddRef((ISAXAttributes*)&This->lpSAXAttributesVtbl); +} + +static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface) +{ + saxattributes *This = impl_from_IVBSAXAttributes(iface); + return ISAXAttributes_Release((ISAXAttributes*)&This->lpSAXAttributesVtbl); +} + +/*** IDispatch methods ***/ +static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo ) +{ + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + + return S_OK; +} + +static HRESULT WINAPI ivbsaxattributes_GetTypeInfo( + IVBSAXAttributes *iface, + UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) +{ + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + HRESULT hr; + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + hr = get_typeinfo(IVBSAXAttributes_tid, ppTInfo); + + return hr; +} + +static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames( + IVBSAXAttributes *iface, + REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, + LCID lcid, + DISPID* rgDispId) +{ + saxattributes *This = impl_from_IVBSAXAttributes( 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(IVBSAXAttributes_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI ivbsaxattributes_Invoke( + IVBSAXAttributes *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + saxattributes *This = impl_from_IVBSAXAttributes( 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(IVBSAXAttributes_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &(This->lpVBSAXAttributesVtbl), dispIdMember, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +/*** IVBSAXAttributes methods ***/ +static HRESULT WINAPI ivbsaxattributes_get_length( + IVBSAXAttributes* iface, + int *nLength) +{ + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getLength( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + nLength); +} + +static HRESULT WINAPI ivbsaxattributes_getURI( + IVBSAXAttributes* iface, + int nIndex, + BSTR *uri) +{ + int len; + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getURI( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + nIndex, (const WCHAR**)uri, &len); +} + +static HRESULT WINAPI ivbsaxattributes_getLocalName( + IVBSAXAttributes* iface, + int nIndex, + BSTR *localName) +{ + int len; + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getLocalName( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + nIndex, (const WCHAR**)localName, &len); +} + +static HRESULT WINAPI ivbsaxattributes_getQName( + IVBSAXAttributes* iface, + int nIndex, + BSTR *QName) +{ + int len; + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getQName( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + nIndex, (const WCHAR**)QName, &len); +} + +static HRESULT WINAPI ivbsaxattributes_getIndexFromName( + IVBSAXAttributes* iface, + BSTR uri, + BSTR localName, + int *index) +{ + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getIndexFromName( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + (const WCHAR*)uri, SysStringLen(uri), + (const WCHAR*)localName, SysStringLen(localName), index); +} + +static HRESULT WINAPI ivbsaxattributes_getIndexFromQName( + IVBSAXAttributes* iface, + BSTR QName, + int *index) +{ + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getIndexFromQName( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + (const WCHAR*)QName, SysStringLen(QName), index); +} + +static HRESULT WINAPI ivbsaxattributes_getType( + IVBSAXAttributes* iface, + int nIndex, + BSTR *type) +{ + int len; + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getType( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + nIndex, (const WCHAR**)type, &len); +} + +static HRESULT WINAPI ivbsaxattributes_getTypeFromName( + IVBSAXAttributes* iface, + BSTR uri, + BSTR localName, + BSTR *type) +{ + int len; + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getTypeFromName( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + (const WCHAR*)uri, SysStringLen(uri), + (const WCHAR*)localName, SysStringLen(localName), + (const WCHAR**)type, &len); +} + +static HRESULT WINAPI ivbsaxattributes_getTypeFromQName( + IVBSAXAttributes* iface, + BSTR QName, + BSTR *type) +{ + int len; + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getTypeFromQName( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + (const WCHAR*)QName, SysStringLen(QName), + (const WCHAR**)type, &len); +} + +static HRESULT WINAPI ivbsaxattributes_getValue( + IVBSAXAttributes* iface, + int nIndex, + BSTR *value) +{ + int len; + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getValue( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + nIndex, (const WCHAR**)value, &len); +} + +static HRESULT WINAPI ivbsaxattributes_getValueFromName( + IVBSAXAttributes* iface, + BSTR uri, + BSTR localName, + BSTR *value) +{ + int len; + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getValueFromName( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + (const WCHAR*)uri, SysStringLen(uri), + (const WCHAR*)localName, SysStringLen(localName), + (const WCHAR**)value, &len); +} + +static HRESULT WINAPI ivbsaxattributes_getValueFromQName( + IVBSAXAttributes* iface, + BSTR QName, + BSTR *value) +{ + int len; + saxattributes *This = impl_from_IVBSAXAttributes( iface ); + return ISAXAttributes_getValueFromQName( + (ISAXAttributes*)&This->lpSAXAttributesVtbl, + (const WCHAR*)QName, SysStringLen(QName), + (const WCHAR**)value, &len); +} + +static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl = +{ + ivbsaxattributes_QueryInterface, + ivbsaxattributes_AddRef, + ivbsaxattributes_Release, + ivbsaxattributes_GetTypeInfoCount, + ivbsaxattributes_GetTypeInfo, + ivbsaxattributes_GetIDsOfNames, + ivbsaxattributes_Invoke, + ivbsaxattributes_get_length, + ivbsaxattributes_getURI, + ivbsaxattributes_getLocalName, + ivbsaxattributes_getQName, + ivbsaxattributes_getIndexFromName, + ivbsaxattributes_getIndexFromQName, + ivbsaxattributes_getType, + ivbsaxattributes_getTypeFromName, + ivbsaxattributes_getTypeFromQName, + ivbsaxattributes_getValue, + ivbsaxattributes_getValueFromName, + ivbsaxattributes_getValueFromQName +}; + +/*** ISAXAttributes interface ***/ +/*** IUnknown methods ***/ +static HRESULT WINAPI isaxattributes_QueryInterface( + ISAXAttributes* iface, + REFIID riid, + void **ppvObject) +{ + saxattributes *This = impl_from_ISAXAttributes(iface); + + TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); + + *ppvObject = NULL; + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_ISAXAttributes)) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + ISAXAttributes_AddRef(iface); + + return S_OK; +} + +static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface) +{ + saxattributes *This = impl_from_ISAXAttributes(iface); + TRACE("%p\n", This); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface) +{ + saxattributes *This = impl_from_ISAXAttributes(iface); + LONG ref; + + TRACE("%p\n", This); + + ref = InterlockedDecrement(&This->ref); + if (ref==0) + { + int index; + for(index=0; indexnb_attributes; index++) + { + SysFreeString(This->szLocalname[index]); + SysFreeString(This->szURI[index]); + SysFreeString(This->szValue[index]); + SysFreeString(This->szQName[index]); + } + + HeapFree(GetProcessHeap(), 0, This->szLocalname); + HeapFree(GetProcessHeap(), 0, This->szURI); + HeapFree(GetProcessHeap(), 0, This->szValue); + HeapFree(GetProcessHeap(), 0, This->szQName); + + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +/*** ISAXAttributes methods ***/ +static HRESULT WINAPI isaxattributes_getLength( + ISAXAttributes* iface, + int *length) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + + *length = This->nb_attributes; + TRACE("Length set to %d\n", *length); + return S_OK; +} + +static HRESULT WINAPI isaxattributes_getURI( + ISAXAttributes* iface, + int nIndex, + const WCHAR **pUrl, + int *pUriSize) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + TRACE("(%p)->(%d)\n", This, nIndex); + + if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; + if(!pUrl || !pUriSize) return E_POINTER; + + *pUriSize = SysStringLen(This->szURI[nIndex]); + *pUrl = This->szURI[nIndex]; + + return S_OK; +} + +static HRESULT WINAPI isaxattributes_getLocalName( + ISAXAttributes* iface, + int nIndex, + const WCHAR **pLocalName, + int *pLocalNameLength) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + TRACE("(%p)->(%d)\n", This, nIndex); + + if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; + if(!pLocalName || !pLocalNameLength) return E_POINTER; + + *pLocalNameLength = SysStringLen(This->szLocalname[nIndex]); + *pLocalName = This->szLocalname[nIndex]; + + return S_OK; +} + +static HRESULT WINAPI isaxattributes_getQName( + ISAXAttributes* iface, + int nIndex, + const WCHAR **pQName, + int *pQNameLength) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + TRACE("(%p)->(%d)\n", This, nIndex); + + if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; + if(!pQName || !pQNameLength) return E_POINTER; + + *pQNameLength = SysStringLen(This->szQName[nIndex]); + *pQName = This->szQName[nIndex]; + + return S_OK; +} + +static HRESULT WINAPI isaxattributes_getName( + ISAXAttributes* iface, + int nIndex, + const WCHAR **pUri, + int *pUriLength, + const WCHAR **pLocalName, + int *pLocalNameSize, + const WCHAR **pQName, + int *pQNameLength) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + TRACE("(%p)->(%d)\n", This, nIndex); + + if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; + if(!pUri || !pUriLength || !pLocalName || !pLocalNameSize + || !pQName || !pQNameLength) return E_POINTER; + + *pUriLength = SysStringLen(This->szURI[nIndex]); + *pUri = This->szURI[nIndex]; + *pLocalNameSize = SysStringLen(This->szLocalname[nIndex]); + *pLocalName = This->szLocalname[nIndex]; + *pQNameLength = SysStringLen(This->szQName[nIndex]); + *pQName = This->szQName[nIndex]; + + return S_OK; +} + +static HRESULT WINAPI isaxattributes_getIndexFromName( + ISAXAttributes* iface, + const WCHAR *pUri, + int cUriLength, + const WCHAR *pLocalName, + int cocalNameLength, + int *index) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + int i; + TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength, + debugstr_w(pLocalName), cocalNameLength); + + if(!pUri || !pLocalName || !index) return E_POINTER; + + for(i=0; inb_attributes; i++) + { + if(cUriLength!=SysStringLen(This->szURI[i]) + || cocalNameLength!=SysStringLen(This->szLocalname[i])) + continue; + if(cUriLength && memcmp(pUri, This->szURI[i], + sizeof(WCHAR)*cUriLength)) + continue; + if(cocalNameLength && memcmp(pLocalName, This->szLocalname[i], + sizeof(WCHAR)*cocalNameLength)) + continue; + + *index = i; + return S_OK; + } + + return E_INVALIDARG; +} + +static HRESULT WINAPI isaxattributes_getIndexFromQName( + ISAXAttributes* iface, + const WCHAR *pQName, + int nQNameLength, + int *index) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + int i; + TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength); + + if(!pQName || !index) return E_POINTER; + if(!nQNameLength) return E_INVALIDARG; + + for(i=0; inb_attributes; i++) + { + if(nQNameLength!=SysStringLen(This->szQName[i])) continue; + if(memcmp(pQName, This->szQName, sizeof(WCHAR)*nQNameLength)) continue; + + *index = i; + return S_OK; + } + + return E_INVALIDARG; +} + +static HRESULT WINAPI isaxattributes_getType( + ISAXAttributes* iface, + int nIndex, + const WCHAR **pType, + int *pTypeLength) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + + FIXME("(%p)->(%d) stub\n", This, nIndex); + return E_NOTIMPL; +} + +static HRESULT WINAPI isaxattributes_getTypeFromName( + ISAXAttributes* iface, + const WCHAR *pUri, + int nUri, + const WCHAR *pLocalName, + int nLocalName, + const WCHAR **pType, + int *nType) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + + FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri, + debugstr_w(pLocalName), nLocalName); + return E_NOTIMPL; +} + +static HRESULT WINAPI isaxattributes_getTypeFromQName( + ISAXAttributes* iface, + const WCHAR *pQName, + int nQName, + const WCHAR **pType, + int *nType) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + + FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName); + return E_NOTIMPL; +} + +static HRESULT WINAPI isaxattributes_getValue( + ISAXAttributes* iface, + int nIndex, + const WCHAR **pValue, + int *nValue) +{ + saxattributes *This = impl_from_ISAXAttributes( iface ); + TRACE("(%p)->(%d)\n", This, nIndex); + + if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; + if(!pValue || !nValue) return E_POINTER; + + *nValue = SysStringLen(This->szValue[nIndex]); + *pValue = This->szValue[nIndex]; + + return S_OK; +} + +static HRESULT WINAPI isaxattributes_getValueFromName( + ISAXAttributes* iface, + const WCHAR *pUri, + int nUri, + const WCHAR *pLocalName, + int nLocalName, + const WCHAR **pValue, + int *nValue) +{ + HRESULT hr; + int index; + saxattributes *This = impl_from_ISAXAttributes( iface ); + TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri, + debugstr_w(pLocalName), nLocalName); + + hr = ISAXAttributes_getIndexFromName(iface, + pUri, nUri, pLocalName, nLocalName, &index); + if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue); + + return hr; +} + +static HRESULT WINAPI isaxattributes_getValueFromQName( + ISAXAttributes* iface, + const WCHAR *pQName, + int nQName, + const WCHAR **pValue, + int *nValue) +{ + HRESULT hr; + int index; + saxattributes *This = impl_from_ISAXAttributes( iface ); + TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName); + + hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index); + if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue); + + return hr; +} + +static const struct ISAXAttributesVtbl isaxattributes_vtbl = +{ + isaxattributes_QueryInterface, + isaxattributes_AddRef, + isaxattributes_Release, + isaxattributes_getLength, + isaxattributes_getURI, + isaxattributes_getLocalName, + isaxattributes_getQName, + isaxattributes_getName, + isaxattributes_getIndexFromName, + isaxattributes_getIndexFromQName, + isaxattributes_getType, + isaxattributes_getTypeFromName, + isaxattributes_getTypeFromQName, + isaxattributes_getValue, + isaxattributes_getValueFromName, + isaxattributes_getValueFromQName +}; + +static HRESULT SAXAttributes_create(saxattributes **attr, + int nb_namespaces, const xmlChar **xmlNamespaces, + int nb_attributes, const xmlChar **xmlAttributes) +{ + saxattributes *attributes; + int index; + static const xmlChar xmlns[] = "xmlns"; + + attributes = HeapAlloc(GetProcessHeap(), 0, sizeof(*attributes)); + if(!attributes) + return E_OUTOFMEMORY; + + attributes->lpVBSAXAttributesVtbl = &ivbsaxattributes_vtbl; + attributes->lpSAXAttributesVtbl = &isaxattributes_vtbl; + attributes->ref = 1; + + attributes->nb_attributes = nb_namespaces+nb_attributes; + + attributes->szLocalname = + HeapAlloc(GetProcessHeap(), 0, sizeof(BSTR)*attributes->nb_attributes); + attributes->szURI = + HeapAlloc(GetProcessHeap(), 0, sizeof(BSTR)*attributes->nb_attributes); + attributes->szValue = + HeapAlloc(GetProcessHeap(), 0, sizeof(BSTR)*attributes->nb_attributes); + attributes->szQName = + HeapAlloc(GetProcessHeap(), 0, sizeof(BSTR)*attributes->nb_attributes); + + if(!attributes->szLocalname || !attributes->szURI + || !attributes->szValue || !attributes->szQName) + { + HeapFree(GetProcessHeap(), 0, attributes->szLocalname); + HeapFree(GetProcessHeap(), 0, attributes->szURI); + HeapFree(GetProcessHeap(), 0, attributes->szValue); + HeapFree(GetProcessHeap(), 0, attributes->szQName); + HeapFree(GetProcessHeap(), 0, attributes); + return E_FAIL; + } + + for(index=0; indexszLocalname[index] = SysAllocStringLen(NULL, 0); + attributes->szURI[index] = SysAllocStringLen(NULL, 0); + attributes->szValue[index] = bstr_from_xmlChar(xmlNamespaces[2*index+1]); + attributes->szQName[index] = QName_from_xmlChar(xmlns, xmlNamespaces[2*index]); + } + + for(index=0; indexszLocalname[nb_namespaces+index] = + bstr_from_xmlChar(xmlAttributes[index*5]); + attributes->szURI[nb_namespaces+index] = + bstr_from_xmlChar(xmlAttributes[index*5+2]); + attributes->szValue[nb_namespaces+index] = + bstr_from_xmlCharN(xmlAttributes[index*5+3], + xmlAttributes[index*5+4]-xmlAttributes[index*5+3]); + attributes->szQName[nb_namespaces+index] = + QName_from_xmlChar(xmlAttributes[index*5+1], xmlAttributes[index*5]); + } + + *attr = attributes; + + TRACE("returning %p\n", *attr); + + return S_OK; +} + +/*** LibXML callbacks ***/ +static void libxmlStartDocument(void *ctx) +{ + saxlocator *This = ctx; + HRESULT hr; + + if((This->vbInterface && This->saxreader->vbcontentHandler) + || (!This->vbInterface && This->saxreader->contentHandler)) + { + if(This->vbInterface) + hr = IVBSAXContentHandler_startDocument(This->saxreader->vbcontentHandler); + else + hr = ISAXContentHandler_startDocument(This->saxreader->contentHandler); + + if(hr != S_OK) + format_error_message_from_id(This, hr); + } + + update_position(This, NULL); +} + +static void libxmlEndDocument(void *ctx) +{ + saxlocator *This = ctx; + HRESULT hr; + + This->column = 0; + This->line = 0; + + if(This->ret != S_OK) return; + + if((This->vbInterface && This->saxreader->vbcontentHandler) + || (!This->vbInterface && This->saxreader->contentHandler)) + { + if(This->vbInterface) + hr = IVBSAXContentHandler_endDocument(This->saxreader->vbcontentHandler); + else + hr = ISAXContentHandler_endDocument(This->saxreader->contentHandler); + + if(hr != S_OK) + format_error_message_from_id(This, hr); + } +} + +static void libxmlStartElementNS( + void *ctx, + const xmlChar *localname, + const xmlChar *prefix, + const xmlChar *URI, + int nb_namespaces, + const xmlChar **namespaces, + int nb_attributes, + int nb_defaulted, + const xmlChar **attributes) +{ + BSTR NamespaceUri, LocalName, QName, Prefix, Uri; + saxlocator *This = ctx; + HRESULT hr; + saxattributes *attr; + int index; + + update_position(This, (xmlChar*)This->pParserCtxt->input->cur+1); + + hr = namespacePush(This, nb_namespaces); + if(hr==S_OK && ((This->vbInterface && This->saxreader->vbcontentHandler) + || (!This->vbInterface && This->saxreader->contentHandler))) + { + for(index=0; indexvbInterface) + hr = IVBSAXContentHandler_startPrefixMapping( + This->saxreader->vbcontentHandler, + &Prefix, &Uri); + else + hr = ISAXContentHandler_startPrefixMapping( + This->saxreader->contentHandler, + Prefix, SysStringLen(Prefix), + Uri, SysStringLen(Uri)); + + SysFreeString(Prefix); + SysFreeString(Uri); + + if(hr != S_OK) + { + format_error_message_from_id(This, hr); + return; + } + } + + NamespaceUri = bstr_from_xmlChar(URI); + LocalName = bstr_from_xmlChar(localname); + QName = QName_from_xmlChar(prefix, localname); + + hr = SAXAttributes_create(&attr, nb_namespaces, namespaces, nb_attributes, attributes); + if(hr == S_OK) + { + if(This->vbInterface) + hr = IVBSAXContentHandler_startElement( + This->saxreader->vbcontentHandler, + &NamespaceUri, &LocalName, &QName, + (IVBSAXAttributes*)&attr->lpVBSAXAttributesVtbl); + else + hr = ISAXContentHandler_startElement( + This->saxreader->contentHandler, + NamespaceUri, SysStringLen(NamespaceUri), + LocalName, SysStringLen(LocalName), + QName, SysStringLen(QName), + (ISAXAttributes*)&attr->lpSAXAttributesVtbl); + + ISAXAttributes_Release((ISAXAttributes*)&attr->lpSAXAttributesVtbl); + } + + SysFreeString(NamespaceUri); + SysFreeString(LocalName); + SysFreeString(QName); + } + + if(hr != S_OK) + format_error_message_from_id(This, hr); +} + +static void libxmlEndElementNS( + void *ctx, + const xmlChar *localname, + const xmlChar *prefix, + const xmlChar *URI) +{ + BSTR NamespaceUri, LocalName, QName, Prefix; + saxlocator *This = ctx; + HRESULT hr; + xmlChar *end; + int nsNr, index; + + end = This->lastCur; + while(*end != '<' && *(end+1) != '/') end++; + update_position(This, end+2); + + nsNr = namespacePop(This); + + if((This->vbInterface && This->saxreader->vbcontentHandler) + || (!This->vbInterface && This->saxreader->contentHandler)) + { + NamespaceUri = bstr_from_xmlChar(URI); + LocalName = bstr_from_xmlChar(localname); + QName = QName_from_xmlChar(prefix, localname); + + if(This->vbInterface) + hr = IVBSAXContentHandler_endElement( + This->saxreader->vbcontentHandler, + &NamespaceUri, &LocalName, &QName); + else + hr = ISAXContentHandler_endElement( + This->saxreader->contentHandler, + NamespaceUri, SysStringLen(NamespaceUri), + LocalName, SysStringLen(LocalName), + QName, SysStringLen(QName)); + + SysFreeString(NamespaceUri); + SysFreeString(LocalName); + SysFreeString(QName); + + if(hr != S_OK) + { + format_error_message_from_id(This, hr); + return; + } + + for(index=This->pParserCtxt->nsNr-2; + index>=This->pParserCtxt->nsNr-nsNr*2; index-=2) + { + Prefix = bstr_from_xmlChar(This->pParserCtxt->nsTab[index]); + + if(This->vbInterface) + hr = IVBSAXContentHandler_endPrefixMapping( + This->saxreader->vbcontentHandler, &Prefix); + else + hr = ISAXContentHandler_endPrefixMapping( + This->saxreader->contentHandler, + Prefix, SysStringLen(Prefix)); + + SysFreeString(Prefix); + } + } +} + +static void libxmlCharacters( + void *ctx, + const xmlChar *ch, + int len) +{ + BSTR Chars; + saxlocator *This = ctx; + HRESULT hr; + xmlChar *end; + xmlChar *lastCurCopy; + xmlChar *chEnd; + int columnCopy; + int lineCopy; + + if(*(This->lastCur-1) != '>' && *(This->lastCur-1) != '/') return; + + if(*(This->lastCur-1) != '>') + { + end = (xmlChar*)This->pParserCtxt->input->cur-len; + while(*(end-1) != '>') end--; + update_position(This, end); + } + + chEnd = This->lastCur+len; + while(*chEnd != '<') chEnd++; + + Chars = bstr_from_xmlChar(ch); + + lastCurCopy = This->lastCur; + columnCopy = This->column; + lineCopy = This->line; + end = This->lastCur; + + if((This->vbInterface && This->saxreader->vbcontentHandler) + || (!This->vbInterface && This->saxreader->contentHandler)) + { + while(This->lastCur < chEnd) + { + end = This->lastCur; + while(end < chEnd-1) + { + if(*end == '\r') break; + end++; + } + + Chars = bstr_from_xmlChar(This->lastCur); + + if(*end == '\r' && *(end+1) == '\n') + { + memmove((WCHAR*)Chars+(end-This->lastCur), + (WCHAR*)Chars+(end-This->lastCur)+1, + (SysStringLen(Chars)-(end-This->lastCur))*sizeof(WCHAR)); + SysReAllocStringLen(&Chars, Chars, SysStringLen(Chars)-1); + } + else if(*end == '\r') Chars[end-This->lastCur] = '\n'; + + if(This->vbInterface) + hr = IVBSAXContentHandler_characters( + This->saxreader->vbcontentHandler, &Chars); + else + hr = ISAXContentHandler_characters( + This->saxreader->contentHandler, + Chars, end-This->lastCur+1); + + SysFreeString(Chars); + if(hr != S_OK) + { + format_error_message_from_id(This, hr); + return; + } + + if(*(end+1) == '\n') end++; + if(end < chEnd) end++; + + This->column += end-This->lastCur; + This->lastCur = end; + } + + This->lastCur = lastCurCopy; + This->column = columnCopy; + This->line = lineCopy; + update_position(This, chEnd); + } +} + +static void libxmlSetDocumentLocator( + void *ctx, + xmlSAXLocatorPtr loc) +{ + saxlocator *This = ctx; + HRESULT hr; + + if(This->vbInterface) + hr = IVBSAXContentHandler_putref_documentLocator( + This->saxreader->vbcontentHandler, + (IVBSAXLocator*)&This->lpVBSAXLocatorVtbl); + else + hr = ISAXContentHandler_putDocumentLocator( + This->saxreader->contentHandler, + (ISAXLocator*)&This->lpSAXLocatorVtbl); + + if(FAILED(hr)) + format_error_message_from_id(This, hr); +} + +void libxmlFatalError(void *ctx, const char *msg, ...) +{ + saxlocator *This = ctx; + char message[1024]; + WCHAR *wszError; + DWORD len; + va_list args; + + if((This->vbInterface && !This->saxreader->vberrorHandler) + || (!This->vbInterface && !This->saxreader->errorHandler)) + { + xmlStopParser(This->pParserCtxt); + This->ret = E_FAIL; + return; + } + + FIXME("Error handling is not compatible.\n"); + + va_start(args, msg); + vsprintf(message, msg, args); + va_end(args); + + len = MultiByteToWideChar(CP_ACP, 0, message, -1, NULL, 0); + wszError = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len); + if(wszError) + MultiByteToWideChar(CP_ACP, 0, message, -1, (LPWSTR)wszError, len); + + if(This->vbInterface) + { + BSTR bstrError = SysAllocString(wszError); + IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler, + (IVBSAXLocator*)&This->lpVBSAXLocatorVtbl, &bstrError, E_FAIL); + } + else + ISAXErrorHandler_fatalError(This->saxreader->errorHandler, + (ISAXLocator*)&This->lpSAXLocatorVtbl, wszError, E_FAIL); + + HeapFree(GetProcessHeap(), 0, wszError); + + xmlStopParser(This->pParserCtxt); + This->ret = E_FAIL; +} + +/*** IVBSAXLocator interface ***/ +/*** IUnknown methods ***/ +static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject) +{ + saxlocator *This = impl_from_IVBSAXLocator( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject); + + *ppvObject = NULL; + + if ( IsEqualGUID( riid, &IID_IUnknown ) || + IsEqualGUID( riid, &IID_IDispatch) || + IsEqualGUID( riid, &IID_IVBSAXLocator )) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IVBSAXLocator_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface) +{ + saxlocator *This = impl_from_IVBSAXLocator( iface ); + TRACE("%p\n", This ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI ivbsaxlocator_Release( + IVBSAXLocator* iface) +{ + saxlocator *This = impl_from_IVBSAXLocator( iface ); + return ISAXLocator_Release((ISAXLocator*)&This->lpVBSAXLocatorVtbl); +} + +/*** IDispatch methods ***/ +static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo ) +{ + saxlocator *This = impl_from_IVBSAXLocator( iface ); + + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + + return S_OK; +} + +static HRESULT WINAPI ivbsaxlocator_GetTypeInfo( + IVBSAXLocator *iface, + UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) +{ + saxlocator *This = impl_from_IVBSAXLocator( iface ); + HRESULT hr; + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + hr = get_typeinfo(IVBSAXLocator_tid, ppTInfo); + + return hr; +} + +static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames( + IVBSAXLocator *iface, + REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, + LCID lcid, + DISPID* rgDispId) +{ + saxlocator *This = impl_from_IVBSAXLocator( 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(IVBSAXLocator_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI ivbsaxlocator_Invoke( + IVBSAXLocator *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + saxlocator *This = impl_from_IVBSAXLocator( 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(IVBSAXLocator_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &(This->lpVBSAXLocatorVtbl), dispIdMember, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +/*** IVBSAXLocator methods ***/ +static HRESULT WINAPI ivbsaxlocator_get_columnNumber( + IVBSAXLocator* iface, + int *pnColumn) +{ + saxlocator *This = impl_from_IVBSAXLocator( iface ); + return ISAXLocator_getColumnNumber( + (ISAXLocator*)&This->lpVBSAXLocatorVtbl, + pnColumn); +} + +static HRESULT WINAPI ivbsaxlocator_get_lineNumber( + IVBSAXLocator* iface, + int *pnLine) +{ + saxlocator *This = impl_from_IVBSAXLocator( iface ); + return ISAXLocator_getLineNumber( + (ISAXLocator*)&This->lpVBSAXLocatorVtbl, + pnLine); +} + +static HRESULT WINAPI ivbsaxlocator_get_publicId( + IVBSAXLocator* iface, + BSTR* publicId) +{ + saxlocator *This = impl_from_IVBSAXLocator( iface ); + return ISAXLocator_getPublicId( + (ISAXLocator*)&This->lpVBSAXLocatorVtbl, + (const WCHAR**)publicId); +} + +static HRESULT WINAPI ivbsaxlocator_get_systemId( + IVBSAXLocator* iface, + BSTR* systemId) +{ + saxlocator *This = impl_from_IVBSAXLocator( iface ); + return ISAXLocator_getSystemId( + (ISAXLocator*)&This->lpVBSAXLocatorVtbl, + (const WCHAR**)systemId); +} + +static const struct IVBSAXLocatorVtbl ivbsaxlocator_vtbl = +{ + ivbsaxlocator_QueryInterface, + ivbsaxlocator_AddRef, + ivbsaxlocator_Release, + ivbsaxlocator_GetTypeInfoCount, + ivbsaxlocator_GetTypeInfo, + ivbsaxlocator_GetIDsOfNames, + ivbsaxlocator_Invoke, + ivbsaxlocator_get_columnNumber, + ivbsaxlocator_get_lineNumber, + ivbsaxlocator_get_publicId, + ivbsaxlocator_get_systemId +}; + +/*** ISAXLocator interface ***/ +/*** IUnknown methods ***/ +static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject) +{ + saxlocator *This = impl_from_ISAXLocator( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + *ppvObject = NULL; + + if ( IsEqualGUID( riid, &IID_IUnknown ) || + IsEqualGUID( riid, &IID_ISAXLocator )) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + ISAXLocator_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface) +{ + saxlocator *This = impl_from_ISAXLocator( iface ); + TRACE("%p\n", This ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI isaxlocator_Release( + ISAXLocator* iface) +{ + saxlocator *This = impl_from_ISAXLocator( iface ); + LONG ref; + + TRACE("%p\n", This ); + + ref = InterlockedDecrement( &This->ref ); + if ( ref == 0 ) + { + if(This->publicId) + SysFreeString(This->publicId); + if(This->systemId) + SysFreeString(This->systemId); + HeapFree(GetProcessHeap(), 0, This->nsStack); + + ISAXXMLReader_Release((ISAXXMLReader*)&This->saxreader->lpSAXXMLReaderVtbl); + HeapFree( GetProcessHeap(), 0, This ); + } + + return ref; +} + +/*** ISAXLocator methods ***/ +static HRESULT WINAPI isaxlocator_getColumnNumber( + ISAXLocator* iface, + int *pnColumn) +{ + saxlocator *This = impl_from_ISAXLocator( iface ); + + *pnColumn = This->column; + return S_OK; +} + +static HRESULT WINAPI isaxlocator_getLineNumber( + ISAXLocator* iface, + int *pnLine) +{ + saxlocator *This = impl_from_ISAXLocator( iface ); + + *pnLine = This->line; + return S_OK; +} + +static HRESULT WINAPI isaxlocator_getPublicId( + ISAXLocator* iface, + const WCHAR ** ppwchPublicId) +{ + BSTR publicId; + saxlocator *This = impl_from_ISAXLocator( iface ); + + if(This->publicId) SysFreeString(This->publicId); + + publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt)); + if(SysStringLen(publicId)) + This->publicId = (WCHAR*)&publicId; + else + { + SysFreeString(publicId); + This->publicId = NULL; + } + + *ppwchPublicId = This->publicId; + return S_OK; +} + +static HRESULT WINAPI isaxlocator_getSystemId( + ISAXLocator* iface, + const WCHAR ** ppwchSystemId) +{ + BSTR systemId; + saxlocator *This = impl_from_ISAXLocator( iface ); + + if(This->systemId) SysFreeString(This->systemId); + + systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt)); + if(SysStringLen(systemId)) + This->systemId = (WCHAR*)&systemId; + else + { + SysFreeString(systemId); + This->systemId = NULL; + } + + *ppwchSystemId = This->systemId; + return S_OK; +} + +static const struct ISAXLocatorVtbl isaxlocator_vtbl = +{ + isaxlocator_QueryInterface, + isaxlocator_AddRef, + isaxlocator_Release, + isaxlocator_getColumnNumber, + isaxlocator_getLineNumber, + isaxlocator_getPublicId, + isaxlocator_getSystemId +}; + +static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface) +{ + saxlocator *locator; + + locator = HeapAlloc( GetProcessHeap(), 0, sizeof (*locator) ); + if( !locator ) + return E_OUTOFMEMORY; + + locator->lpVBSAXLocatorVtbl = &ivbsaxlocator_vtbl; + locator->lpSAXLocatorVtbl = &isaxlocator_vtbl; + locator->ref = 1; + locator->vbInterface = vbInterface; + + locator->saxreader = reader; + ISAXXMLReader_AddRef((ISAXXMLReader*)&reader->lpSAXXMLReaderVtbl); + + locator->pParserCtxt = NULL; + locator->publicId = NULL; + locator->systemId = NULL; + locator->lastCur = NULL; + locator->line = 0; + locator->column = 0; + locator->ret = S_OK; + locator->nsStackSize = 8; + locator->nsStackLast = 0; + locator->nsStack = HeapAlloc(GetProcessHeap(), 0, locator->nsStackSize); + if(!locator->nsStack) + { + ISAXXMLReader_Release((ISAXXMLReader*)&reader->lpSAXXMLReaderVtbl); + HeapFree(GetProcessHeap(), 0, locator); + return E_OUTOFMEMORY; + } + + *ppsaxlocator = locator; + + TRACE("returning %p\n", *ppsaxlocator); + + return S_OK; +} + +/*** SAXXMLReader internal functions ***/ +static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface) +{ + saxlocator *locator; + HRESULT hr; + + hr = SAXLocator_create(This, &locator, vbInterface); + if(FAILED(hr)) + return E_FAIL; + + locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size); + if(!locator->pParserCtxt) + { + ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl); + return E_FAIL; + } + + locator->pParserCtxt->sax = &locator->saxreader->sax; + locator->pParserCtxt->userData = locator; + + if(xmlParseDocument(locator->pParserCtxt)) hr = E_FAIL; + else hr = locator->ret; + + if(locator->pParserCtxt) + { + locator->pParserCtxt->sax = NULL; + xmlFreeParserCtxt(locator->pParserCtxt); + locator->pParserCtxt = NULL; + } + + ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl); + return S_OK; +} + +static HRESULT WINAPI internal_getEntityResolver( + saxreader *This, + void *pEntityResolver, + BOOL vbInterface) +{ + FIXME("(%p)->(%p) stub\n", This, pEntityResolver); + return E_NOTIMPL; +} + +static HRESULT WINAPI internal_putEntityResolver( + saxreader *This, + void *pEntityResolver, + BOOL vbInterface) +{ + FIXME("(%p)->(%p) stub\n", This, pEntityResolver); + return E_NOTIMPL; +} + +static HRESULT WINAPI internal_getContentHandler( + saxreader* This, + void *pContentHandler, + BOOL vbInterface) +{ + TRACE("(%p)->(%p)\n", This, pContentHandler); + if(pContentHandler == NULL) + return E_POINTER; + if((vbInterface && This->vbcontentHandler) + || (!vbInterface && This->contentHandler)) + { + if(vbInterface) + IVBSAXContentHandler_AddRef(This->vbcontentHandler); + else + ISAXContentHandler_AddRef(This->contentHandler); + } + if(vbInterface) *(IVBSAXContentHandler**)pContentHandler = + This->vbcontentHandler; + else *(ISAXContentHandler**)pContentHandler = This->contentHandler; + + return S_OK; +} + +static HRESULT WINAPI internal_putContentHandler( + saxreader* This, + void *contentHandler, + BOOL vbInterface) +{ + TRACE("(%p)->(%p)\n", This, contentHandler); + if(contentHandler) + { + if(vbInterface) + IVBSAXContentHandler_AddRef((IVBSAXContentHandler*)contentHandler); + else + ISAXContentHandler_AddRef((ISAXContentHandler*)contentHandler); + } + if((vbInterface && This->vbcontentHandler) + || (!vbInterface && This->contentHandler)) + { + if(vbInterface) + IVBSAXContentHandler_Release(This->vbcontentHandler); + else + ISAXContentHandler_Release(This->contentHandler); + } + if(vbInterface) + This->vbcontentHandler = contentHandler; + else + This->contentHandler = contentHandler; + + return S_OK; +} + +static HRESULT WINAPI internal_getDTDHandler( + saxreader* This, + void *pDTDHandler, + BOOL vbInterface) +{ + FIXME("(%p)->(%p) stub\n", This, pDTDHandler); + return E_NOTIMPL; +} + +static HRESULT WINAPI internal_putDTDHandler( + saxreader* This, + void *pDTDHandler, + BOOL vbInterface) +{ + FIXME("(%p)->(%p) stub\n", This, pDTDHandler); + return E_NOTIMPL; +} + +static HRESULT WINAPI internal_getErrorHandler( + saxreader* This, + void *pErrorHandler, + BOOL vbInterface) +{ + TRACE("(%p)->(%p)\n", This, pErrorHandler); + if(pErrorHandler == NULL) + return E_POINTER; + + if(vbInterface && This->vberrorHandler) + IVBSAXErrorHandler_AddRef(This->vberrorHandler); + else if(!vbInterface && This->errorHandler) + ISAXErrorHandler_AddRef(This->errorHandler); + + if(vbInterface) + *(IVBSAXErrorHandler**)pErrorHandler = This->vberrorHandler; + else + *(ISAXErrorHandler**)pErrorHandler = This->errorHandler; + + return S_OK; + +} + +static HRESULT WINAPI internal_putErrorHandler( + saxreader* This, + void *errorHandler, + BOOL vbInterface) +{ + TRACE("(%p)->(%p)\n", This, errorHandler); + if(errorHandler) + { + if(vbInterface) + IVBSAXErrorHandler_AddRef((IVBSAXErrorHandler*)errorHandler); + else + ISAXErrorHandler_AddRef((ISAXErrorHandler*)errorHandler); + } + + if(vbInterface && This->vberrorHandler) + IVBSAXErrorHandler_Release(This->vberrorHandler); + else if(!vbInterface && This->errorHandler) + ISAXErrorHandler_Release(This->errorHandler); + + if(vbInterface) + This->vberrorHandler = errorHandler; + else + This->errorHandler = errorHandler; + + return S_OK; + +} + +static HRESULT WINAPI internal_parse( + saxreader* This, + VARIANT varInput, + BOOL vbInterface) +{ + HRESULT hr; + + TRACE("(%p)\n", This); + + hr = S_OK; + switch(V_VT(&varInput)) + { + case VT_BSTR: + hr = internal_parseBuffer(This, (const char*)V_BSTR(&varInput), + SysStringByteLen(V_BSTR(&varInput)), vbInterface); + break; + case VT_ARRAY|VT_UI1: { + void *pSAData; + LONG lBound, uBound; + ULONG dataRead; + + hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound); + if(hr != S_OK) break; + hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound); + if(hr != S_OK) break; + dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput)); + hr = SafeArrayAccessData(V_ARRAY(&varInput), (void**)&pSAData); + if(hr != S_OK) break; + hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface); + SafeArrayUnaccessData(V_ARRAY(&varInput)); + break; + } + case VT_UNKNOWN: + case VT_DISPATCH: { + IPersistStream *persistStream; + IStream *stream = NULL; + IXMLDOMDocument *xmlDoc; + + if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), + &IID_IPersistStream, (void**)&persistStream) == S_OK) + { + hr = IPersistStream_Save(persistStream, stream, TRUE); + IPersistStream_Release(persistStream); + if(hr != S_OK) break; + } + if(stream || IUnknown_QueryInterface(V_UNKNOWN(&varInput), + &IID_IStream, (void**)&stream) == S_OK) + { + STATSTG dataInfo; + ULONG dataRead; + char *data; + + while(1) + { + hr = IStream_Stat(stream, &dataInfo, STATFLAG_NONAME); + if(hr == E_PENDING) continue; + break; + } + if(hr != S_OK) + { + IStream_Release(stream); + break; + } + + data = HeapAlloc(GetProcessHeap(), 0, + dataInfo.cbSize.QuadPart); + if(!data) + { + IStream_Release(stream); + break; + } + + while(1) + { + hr = IStream_Read(stream, data, + dataInfo.cbSize.QuadPart, &dataRead); + if(hr == E_PENDING) continue; + break; + } + if(hr != S_OK) + { + HeapFree(GetProcessHeap(), 0, data); + IStream_Release(stream); + break; + } + + hr = internal_parseBuffer(This, data, + dataInfo.cbSize.QuadPart, vbInterface); + HeapFree(GetProcessHeap(), 0, data); + IStream_Release(stream); + break; + } + if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), + &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK) + { + BSTR bstrData; + + IXMLDOMDocument_get_xml(xmlDoc, &bstrData); + hr = internal_parseBuffer(This, (const char*)bstrData, + SysStringByteLen(bstrData), vbInterface); + IXMLDOMDocument_Release(xmlDoc); + hr = E_NOTIMPL; + break; + } + } + default: + WARN("vt %d not implemented\n", V_VT(&varInput)); + hr = E_INVALIDARG; + } + + return hr; +} + +static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len) +{ + saxreader *This = obj; + + return internal_parseBuffer(This, ptr, len, TRUE); +} + +static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len) +{ + saxreader *This = obj; + + return internal_parseBuffer(This, ptr, len, FALSE); +} + +static HRESULT WINAPI internal_parseURL( + saxreader* This, + const WCHAR *url, + BOOL vbInterface) +{ + bsc_t *bsc; + HRESULT hr; + + TRACE("(%p)->(%s)\n", This, debugstr_w(url)); + + if(vbInterface) hr = bind_url(url, internal_vbonDataAvailable, This, &bsc); + else hr = bind_url(url, internal_onDataAvailable, This, &bsc); + + if(FAILED(hr)) + return hr; + + detach_bsc(bsc); + + return S_OK; +} + +/*** IVBSAXXMLReader interface ***/ +/*** IUnknown methods ***/ +static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); + + *ppvObject = NULL; + + if ( IsEqualGUID( riid, &IID_IUnknown ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IVBSAXXMLReader )) + { + *ppvObject = iface; + } + else if( IsEqualGUID( riid, &IID_ISAXXMLReader )) + { + *ppvObject = (ISAXXMLReader*)&This->lpSAXXMLReaderVtbl; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IVBSAXXMLReader_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + TRACE("%p\n", This ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI saxxmlreader_Release( + IVBSAXXMLReader* iface) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + LONG ref; + + TRACE("%p\n", This ); + + ref = InterlockedDecrement( &This->ref ); + if ( ref == 0 ) + { + if(This->contentHandler) + ISAXContentHandler_Release(This->contentHandler); + + if(This->vbcontentHandler) + IVBSAXContentHandler_Release(This->vbcontentHandler); + + if(This->errorHandler) + ISAXErrorHandler_Release(This->errorHandler); + + if(This->vberrorHandler) + IVBSAXErrorHandler_Release(This->vberrorHandler); + + HeapFree( GetProcessHeap(), 0, This ); + } + + return ref; +} +/*** IDispatch ***/ +static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo ) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + + return S_OK; +} + +static HRESULT WINAPI saxxmlreader_GetTypeInfo( + IVBSAXXMLReader *iface, + UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + HRESULT hr; + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + hr = get_typeinfo(IVBSAXXMLReader_tid, ppTInfo); + + return hr; +} + +static HRESULT WINAPI saxxmlreader_GetIDsOfNames( + IVBSAXXMLReader *iface, + REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, + LCID lcid, + DISPID* rgDispId) +{ + saxreader *This = impl_from_IVBSAXXMLReader( 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(IVBSAXXMLReader_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI saxxmlreader_Invoke( + IVBSAXXMLReader *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + saxreader *This = impl_from_IVBSAXXMLReader( 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(IVBSAXXMLReader_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, &(This->lpVBSAXXMLReaderVtbl), dispIdMember, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +/*** IVBSAXXMLReader methods ***/ +static HRESULT WINAPI saxxmlreader_getFeature( + IVBSAXXMLReader* iface, + const WCHAR *pFeature, + VARIANT_BOOL *pValue) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pFeature), pValue); + return E_NOTIMPL; +} + +static HRESULT WINAPI saxxmlreader_putFeature( + IVBSAXXMLReader* iface, + const WCHAR *pFeature, + VARIANT_BOOL vfValue) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(pFeature), vfValue); + return E_NOTIMPL; +} + +static HRESULT WINAPI saxxmlreader_getProperty( + IVBSAXXMLReader* iface, + const WCHAR *pProp, + VARIANT *pValue) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pProp), pValue); + return E_NOTIMPL; +} + +static HRESULT WINAPI saxxmlreader_putProperty( + IVBSAXXMLReader* iface, + const WCHAR *pProp, + VARIANT value) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + FIXME("(%p)->(%s) stub\n", This, debugstr_w(pProp)); + return E_NOTIMPL; +} + +static HRESULT WINAPI saxxmlreader_getEntityResolver( + IVBSAXXMLReader* iface, + IVBSAXEntityResolver **pEntityResolver) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_getEntityResolver(This, pEntityResolver, TRUE); +} + +static HRESULT WINAPI saxxmlreader_putEntityResolver( + IVBSAXXMLReader* iface, + IVBSAXEntityResolver *pEntityResolver) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_putEntityResolver(This, pEntityResolver, TRUE); +} + +static HRESULT WINAPI saxxmlreader_getContentHandler( + IVBSAXXMLReader* iface, + IVBSAXContentHandler **ppContentHandler) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_getContentHandler(This, ppContentHandler, TRUE); +} + +static HRESULT WINAPI saxxmlreader_putContentHandler( + IVBSAXXMLReader* iface, + IVBSAXContentHandler *contentHandler) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_putContentHandler(This, contentHandler, TRUE); +} + +static HRESULT WINAPI saxxmlreader_getDTDHandler( + IVBSAXXMLReader* iface, + IVBSAXDTDHandler **pDTDHandler) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_getDTDHandler(This, pDTDHandler, TRUE); +} + +static HRESULT WINAPI saxxmlreader_putDTDHandler( + IVBSAXXMLReader* iface, + IVBSAXDTDHandler *pDTDHandler) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_putDTDHandler(This, pDTDHandler, TRUE); +} + +static HRESULT WINAPI saxxmlreader_getErrorHandler( + IVBSAXXMLReader* iface, + IVBSAXErrorHandler **pErrorHandler) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_getErrorHandler(This, pErrorHandler, TRUE); +} + +static HRESULT WINAPI saxxmlreader_putErrorHandler( + IVBSAXXMLReader* iface, + IVBSAXErrorHandler *errorHandler) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_putErrorHandler(This, errorHandler, TRUE); +} + +static HRESULT WINAPI saxxmlreader_getBaseURL( + IVBSAXXMLReader* iface, + const WCHAR **pBaseUrl) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + FIXME("(%p)->(%p) stub\n", This, pBaseUrl); + return E_NOTIMPL; +} + +static HRESULT WINAPI saxxmlreader_putBaseURL( + IVBSAXXMLReader* iface, + const WCHAR *pBaseUrl) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl)); + return E_NOTIMPL; +} + +static HRESULT WINAPI saxxmlreader_getSecureBaseURL( + IVBSAXXMLReader* iface, + const WCHAR **pSecureBaseUrl) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl); + return E_NOTIMPL; +} + + +static HRESULT WINAPI saxxmlreader_putSecureBaseURL( + IVBSAXXMLReader* iface, + const WCHAR *secureBaseUrl) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + + FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl)); + return E_NOTIMPL; +} + +static HRESULT WINAPI saxxmlreader_parse( + IVBSAXXMLReader* iface, + VARIANT varInput) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_parse(This, varInput, TRUE); +} + +static HRESULT WINAPI saxxmlreader_parseURL( + IVBSAXXMLReader* iface, + const WCHAR *url) +{ + saxreader *This = impl_from_IVBSAXXMLReader( iface ); + return internal_parseURL(This, url, TRUE); +} + +static const struct IVBSAXXMLReaderVtbl saxreader_vtbl = +{ + saxxmlreader_QueryInterface, + saxxmlreader_AddRef, + saxxmlreader_Release, + saxxmlreader_GetTypeInfoCount, + saxxmlreader_GetTypeInfo, + saxxmlreader_GetIDsOfNames, + saxxmlreader_Invoke, + saxxmlreader_getFeature, + saxxmlreader_putFeature, + saxxmlreader_getProperty, + saxxmlreader_putProperty, + saxxmlreader_getEntityResolver, + saxxmlreader_putEntityResolver, + saxxmlreader_getContentHandler, + saxxmlreader_putContentHandler, + saxxmlreader_getDTDHandler, + saxxmlreader_putDTDHandler, + saxxmlreader_getErrorHandler, + saxxmlreader_putErrorHandler, + saxxmlreader_getBaseURL, + saxxmlreader_putBaseURL, + saxxmlreader_getSecureBaseURL, + saxxmlreader_putSecureBaseURL, + saxxmlreader_parse, + saxxmlreader_parseURL +}; + +/*** ISAXXMLReader interface ***/ +/*** IUnknown methods ***/ +static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return saxxmlreader_QueryInterface((IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, riid, ppvObject); +} + +static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return saxxmlreader_AddRef((IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl); +} + +static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return saxxmlreader_Release((IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl); +} + +/*** ISAXXMLReader methods ***/ +static HRESULT WINAPI isaxxmlreader_getFeature( + ISAXXMLReader* iface, + const WCHAR *pFeature, + VARIANT_BOOL *pValue) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return IVBSAXXMLReader_getFeature( + (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, + pFeature, pValue); +} + +static HRESULT WINAPI isaxxmlreader_putFeature( + ISAXXMLReader* iface, + const WCHAR *pFeature, + VARIANT_BOOL vfValue) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return IVBSAXXMLReader_putFeature( + (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, + pFeature, vfValue); +} + +static HRESULT WINAPI isaxxmlreader_getProperty( + ISAXXMLReader* iface, + const WCHAR *pProp, + VARIANT *pValue) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return IVBSAXXMLReader_getProperty( + (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, + pProp, pValue); +} + +static HRESULT WINAPI isaxxmlreader_putProperty( + ISAXXMLReader* iface, + const WCHAR *pProp, + VARIANT value) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return IVBSAXXMLReader_putProperty( + (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, + pProp, value); +} + +static HRESULT WINAPI isaxxmlreader_getEntityResolver( + ISAXXMLReader* iface, + ISAXEntityResolver **ppEntityResolver) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_getEntityResolver(This, ppEntityResolver, FALSE); +} + +static HRESULT WINAPI isaxxmlreader_putEntityResolver( + ISAXXMLReader* iface, + ISAXEntityResolver *pEntityResolver) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_putEntityResolver(This, pEntityResolver, FALSE); +} + +static HRESULT WINAPI isaxxmlreader_getContentHandler( + ISAXXMLReader* iface, + ISAXContentHandler **pContentHandler) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_getContentHandler(This, pContentHandler, FALSE); +} + +static HRESULT WINAPI isaxxmlreader_putContentHandler( + ISAXXMLReader* iface, + ISAXContentHandler *contentHandler) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_putContentHandler(This, contentHandler, FALSE); +} + +static HRESULT WINAPI isaxxmlreader_getDTDHandler( + ISAXXMLReader* iface, + ISAXDTDHandler **pDTDHandler) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_getDTDHandler(This, pDTDHandler, FALSE); +} + +static HRESULT WINAPI isaxxmlreader_putDTDHandler( + ISAXXMLReader* iface, + ISAXDTDHandler *pDTDHandler) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_putDTDHandler(This, pDTDHandler, FALSE); +} + +static HRESULT WINAPI isaxxmlreader_getErrorHandler( + ISAXXMLReader* iface, + ISAXErrorHandler **pErrorHandler) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_getErrorHandler(This, pErrorHandler, FALSE); +} + +static HRESULT WINAPI isaxxmlreader_putErrorHandler( + ISAXXMLReader* iface, + ISAXErrorHandler *errorHandler) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_putErrorHandler(This, errorHandler, FALSE); +} + +static HRESULT WINAPI isaxxmlreader_getBaseURL( + ISAXXMLReader* iface, + const WCHAR **pBaseUrl) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return IVBSAXXMLReader_get_getBaseURL( + (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, + pBaseUrl); +} + +static HRESULT WINAPI isaxxmlreader_putBaseURL( + ISAXXMLReader* iface, + const WCHAR *pBaseUrl) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return IVBSAXXMLReader_put_putBaseURL( + (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, + pBaseUrl); +} + +static HRESULT WINAPI isaxxmlreader_getSecureBaseURL( + ISAXXMLReader* iface, + const WCHAR **pSecureBaseUrl) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return IVBSAXXMLReader_get_getSecureBaseURL( + (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, + pSecureBaseUrl); +} + +static HRESULT WINAPI isaxxmlreader_putSecureBaseURL( + ISAXXMLReader* iface, + const WCHAR *secureBaseUrl) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return IVBSAXXMLReader_put_putSecureBaseURL( + (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, + secureBaseUrl); +} + +static HRESULT WINAPI isaxxmlreader_parse( + ISAXXMLReader* iface, + VARIANT varInput) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_parse(This, varInput, FALSE); +} + +static HRESULT WINAPI isaxxmlreader_parseURL( + ISAXXMLReader* iface, + const WCHAR *url) +{ + saxreader *This = impl_from_ISAXXMLReader( iface ); + return internal_parseURL(This, url, FALSE); +} + +static const struct ISAXXMLReaderVtbl isaxreader_vtbl = +{ + isaxxmlreader_QueryInterface, + isaxxmlreader_AddRef, + isaxxmlreader_Release, + isaxxmlreader_getFeature, + isaxxmlreader_putFeature, + isaxxmlreader_getProperty, + isaxxmlreader_putProperty, + isaxxmlreader_getEntityResolver, + isaxxmlreader_putEntityResolver, + isaxxmlreader_getContentHandler, + isaxxmlreader_putContentHandler, + isaxxmlreader_getDTDHandler, + isaxxmlreader_putDTDHandler, + isaxxmlreader_getErrorHandler, + isaxxmlreader_putErrorHandler, + isaxxmlreader_getBaseURL, + isaxxmlreader_putBaseURL, + isaxxmlreader_getSecureBaseURL, + isaxxmlreader_putSecureBaseURL, + isaxxmlreader_parse, + isaxxmlreader_parseURL +}; + +HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj) +{ + saxreader *reader; + + TRACE("(%p,%p)\n", pUnkOuter, ppObj); + + reader = HeapAlloc( GetProcessHeap(), 0, sizeof (*reader) ); + if( !reader ) + return E_OUTOFMEMORY; + + reader->lpVBSAXXMLReaderVtbl = &saxreader_vtbl; + reader->lpSAXXMLReaderVtbl = &isaxreader_vtbl; + reader->ref = 1; + reader->contentHandler = NULL; + reader->vbcontentHandler = NULL; + reader->errorHandler = NULL; + reader->vberrorHandler = NULL; + + memset(&reader->sax, 0, sizeof(xmlSAXHandler)); + reader->sax.initialized = XML_SAX2_MAGIC; + reader->sax.startDocument = libxmlStartDocument; + reader->sax.endDocument = libxmlEndDocument; + reader->sax.startElementNs = libxmlStartElementNS; + reader->sax.endElementNs = libxmlEndElementNS; + reader->sax.characters = libxmlCharacters; + reader->sax.setDocumentLocator = libxmlSetDocumentLocator; + reader->sax.error = libxmlFatalError; + reader->sax.fatalError = libxmlFatalError; + + *ppObj = &reader->lpVBSAXXMLReaderVtbl; + + TRACE("returning iface %p\n", *ppObj); + + return S_OK; +} + +#else + +HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj) +{ + MESSAGE("This program tried to use a SAX XML Reader object, but\n" + "libxml2 support was not present at compile time.\n"); + return E_NOTIMPL; +} + +#endif