From 29dc01c8e295565f93eb97d9fa0b8002888aaf0f Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 4 Jan 2009 10:48:19 +0000 Subject: [PATCH] sync msxml3 with wine 1.1.12 (1/2) svn path=/trunk/; revision=38553 --- reactos/boot/bootdata/packages/reactos.dff | 1 + reactos/dll/win32/msxml3/attribute.c | 8 +- reactos/dll/win32/msxml3/bsc.c | 10 +- reactos/dll/win32/msxml3/cdata.c | 113 +++-- reactos/dll/win32/msxml3/comment.c | 18 +- reactos/dll/win32/msxml3/dispex.c | 36 +- reactos/dll/win32/msxml3/domdoc.c | 244 ++++++++-- reactos/dll/win32/msxml3/element.c | 17 +- reactos/dll/win32/msxml3/factory.c | 5 + reactos/dll/win32/msxml3/httprequest.c | 343 +++++++++++++ reactos/dll/win32/msxml3/main.c | 67 ++- reactos/dll/win32/msxml3/msxml3.rbuild | 1 + reactos/dll/win32/msxml3/msxml_private.h | 26 +- reactos/dll/win32/msxml3/node.c | 263 ++++++---- reactos/dll/win32/msxml3/nodemap.c | 47 +- reactos/dll/win32/msxml3/queryresult.c | 6 +- reactos/dll/win32/msxml3/regsvr.c | 3 +- reactos/dll/win32/msxml3/saxreader.c | 532 ++++++++++++++++----- reactos/dll/win32/msxml3/text.c | 116 ++--- reactos/dll/win32/msxml3/xmlelem.c | 4 +- reactos/include/psdk/msxml2.idl | 54 +++ 21 files changed, 1520 insertions(+), 394 deletions(-) create mode 100644 reactos/dll/win32/msxml3/httprequest.c diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index 95b5fc10cfc..64c65aa5e85 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -641,6 +641,7 @@ modules\rostests\winetests\mshtml\mshtml_winetest.exe 7 o modules\rostests\winetests\msi\msi_winetest.exe 7 optional modules\rostests\winetests\mstask\mstask_winetest.exe 7 optional modules\rostests\winetests\msvcrt\msvcrt_winetest.exe 7 optional +modules\rostests\winetests\msxml3\msxml3_winetest.exe 7 optional modules\rostests\winetests\netapi32\netapi32_winetest.exe 7 optional modules\rostests\winetests\ntdll\ntdll_winetest.exe 7 optional modules\rostests\winetests\odbccp32\odbccp32_winetest.exe 7 optional diff --git a/reactos/dll/win32/msxml3/attribute.c b/reactos/dll/win32/msxml3/attribute.c index 2681a76fab0..92cafad5367 100644 --- a/reactos/dll/win32/msxml3/attribute.c +++ b/reactos/dll/win32/msxml3/attribute.c @@ -482,16 +482,16 @@ static HRESULT WINAPI domattr_get_value( IXMLDOMAttribute *iface, VARIANT *var1) { - FIXME("\n"); - return E_NOTIMPL; + domattr *This = impl_from_IXMLDOMAttribute( iface ); + return IXMLDOMNode_get_nodeValue( This->node, var1 ); } static HRESULT WINAPI domattr_put_value( IXMLDOMAttribute *iface, VARIANT var1) { - FIXME("\n"); - return E_NOTIMPL; + domattr *This = impl_from_IXMLDOMAttribute( iface ); + return IXMLDOMNode_put_nodeValue( This->node, var1 ); } static const struct IXMLDOMAttributeVtbl domattr_vtbl = diff --git a/reactos/dll/win32/msxml3/bsc.c b/reactos/dll/win32/msxml3/bsc.c index bd29c318f00..1914ca88fa4 100644 --- a/reactos/dll/win32/msxml3/bsc.c +++ b/reactos/dll/win32/msxml3/bsc.c @@ -69,7 +69,7 @@ static HRESULT WINAPI bsc_QueryInterface( return S_OK; } - FIXME("interface %s not implemented\n", debugstr_guid(riid)); + TRACE("interface %s not implemented\n", debugstr_guid(riid)); return E_NOINTERFACE; } @@ -114,7 +114,7 @@ static HRESULT WINAPI bsc_OnStartBinding( TRACE("(%p)->(%x %p)\n", This, dwReserved, pib); This->binding = pib; - IBindStatusCallback_AddRef(pib); + IBinding_AddRef(pib); hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream); if(FAILED(hr)) @@ -296,6 +296,12 @@ HRESULT bind_url(LPCWSTR url, HRESULT (*onDataAvailable)(void*,char*,DWORD), voi IBindCtx_Release(pbc); } + if(FAILED(hr)) + { + IBindStatusCallback_Release((IBindStatusCallback*)&bsc->lpVtbl); + bsc = NULL; + } + *ret = bsc; return hr; } diff --git a/reactos/dll/win32/msxml3/cdata.c b/reactos/dll/win32/msxml3/cdata.c index 8cf39407b36..dc7399bf980 100644 --- a/reactos/dll/win32/msxml3/cdata.c +++ b/reactos/dll/win32/msxml3/cdata.c @@ -41,8 +41,8 @@ typedef struct _domcdata { const struct IXMLDOMCDATASectionVtbl *lpVtbl; LONG ref; - IUnknown *element_unk; - IXMLDOMCDATASection *element; + IUnknown *node_unk; + IXMLDOMNode *node; } domcdata; static inline domcdata *impl_from_IXMLDOMCDATASection( IXMLDOMCDATASection *iface ) @@ -65,10 +65,15 @@ static HRESULT WINAPI domcdata_QueryInterface( { *ppvObject = iface; } - else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) || + else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) ) + { + return IUnknown_QueryInterface(This->node_unk, riid, ppvObject); + } + else if ( IsEqualGUID( riid, &IID_IXMLDOMText ) || IsEqualGUID( riid, &IID_IXMLDOMElement ) ) { - return IUnknown_QueryInterface(This->element_unk, riid, ppvObject); + TRACE("Unsupported interface\n"); + return E_NOINTERFACE; } else { @@ -97,7 +102,7 @@ static ULONG WINAPI domcdata_Release( ref = InterlockedDecrement( &This->ref ); if ( ref == 0 ) { - IUnknown_Release( This->element_unk ); + IUnknown_Release( This->node_unk ); HeapFree( GetProcessHeap(), 0, This ); } @@ -186,7 +191,7 @@ static HRESULT WINAPI domcdata_get_nodeName( BSTR* p ) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_nodeName( This->element, p ); + return IXMLDOMNode_get_nodeName( This->node, p ); } static HRESULT WINAPI domcdata_get_nodeValue( @@ -194,7 +199,7 @@ static HRESULT WINAPI domcdata_get_nodeValue( VARIANT* var1 ) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_nodeValue( This->element, var1 ); + return IXMLDOMNode_get_nodeValue( This->node, var1 ); } static HRESULT WINAPI domcdata_put_nodeValue( @@ -202,7 +207,7 @@ static HRESULT WINAPI domcdata_put_nodeValue( VARIANT var1 ) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_put_nodeValue( This->element, var1 ); + return IXMLDOMNode_put_nodeValue( This->node, var1 ); } static HRESULT WINAPI domcdata_get_nodeType( @@ -210,7 +215,7 @@ static HRESULT WINAPI domcdata_get_nodeType( DOMNodeType* domNodeType ) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_nodeType( This->element, domNodeType ); + return IXMLDOMNode_get_nodeType( This->node, domNodeType ); } static HRESULT WINAPI domcdata_get_parentNode( @@ -218,7 +223,7 @@ static HRESULT WINAPI domcdata_get_parentNode( IXMLDOMNode** parent ) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_parentNode( This->element, parent ); + return IXMLDOMNode_get_parentNode( This->node, parent ); } static HRESULT WINAPI domcdata_get_childNodes( @@ -226,7 +231,7 @@ static HRESULT WINAPI domcdata_get_childNodes( IXMLDOMNodeList** outList) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_childNodes( This->element, outList ); + return IXMLDOMNode_get_childNodes( This->node, outList ); } static HRESULT WINAPI domcdata_get_firstChild( @@ -234,7 +239,7 @@ static HRESULT WINAPI domcdata_get_firstChild( IXMLDOMNode** domNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_firstChild( This->element, domNode ); + return IXMLDOMNode_get_firstChild( This->node, domNode ); } static HRESULT WINAPI domcdata_get_lastChild( @@ -242,7 +247,7 @@ static HRESULT WINAPI domcdata_get_lastChild( IXMLDOMNode** domNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_lastChild( This->element, domNode ); + return IXMLDOMNode_get_lastChild( This->node, domNode ); } static HRESULT WINAPI domcdata_get_previousSibling( @@ -250,7 +255,7 @@ static HRESULT WINAPI domcdata_get_previousSibling( IXMLDOMNode** domNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_previousSibling( This->element, domNode ); + return IXMLDOMNode_get_previousSibling( This->node, domNode ); } static HRESULT WINAPI domcdata_get_nextSibling( @@ -258,7 +263,7 @@ static HRESULT WINAPI domcdata_get_nextSibling( IXMLDOMNode** domNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_nextSibling( This->element, domNode ); + return IXMLDOMNode_get_nextSibling( This->node, domNode ); } static HRESULT WINAPI domcdata_get_attributes( @@ -266,7 +271,7 @@ static HRESULT WINAPI domcdata_get_attributes( IXMLDOMNamedNodeMap** attributeMap) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_attributes( This->element, attributeMap ); + return IXMLDOMNode_get_attributes( This->node, attributeMap ); } static HRESULT WINAPI domcdata_insertBefore( @@ -275,7 +280,7 @@ static HRESULT WINAPI domcdata_insertBefore( IXMLDOMNode** outOldNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_insertBefore( This->element, newNode, var1, outOldNode ); + return IXMLDOMNode_insertBefore( This->node, newNode, var1, outOldNode ); } static HRESULT WINAPI domcdata_replaceChild( @@ -285,7 +290,7 @@ static HRESULT WINAPI domcdata_replaceChild( IXMLDOMNode** outOldNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_replaceChild( This->element, newNode, oldNode, outOldNode ); + return IXMLDOMNode_replaceChild( This->node, newNode, oldNode, outOldNode ); } static HRESULT WINAPI domcdata_removeChild( @@ -293,7 +298,7 @@ static HRESULT WINAPI domcdata_removeChild( IXMLDOMNode* domNode, IXMLDOMNode** oldNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_removeChild( This->element, domNode, oldNode ); + return IXMLDOMNode_removeChild( This->node, domNode, oldNode ); } static HRESULT WINAPI domcdata_appendChild( @@ -301,7 +306,7 @@ static HRESULT WINAPI domcdata_appendChild( IXMLDOMNode* newNode, IXMLDOMNode** outNewNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_appendChild( This->element, newNode, outNewNode ); + return IXMLDOMNode_appendChild( This->node, newNode, outNewNode ); } static HRESULT WINAPI domcdata_hasChildNodes( @@ -309,7 +314,7 @@ static HRESULT WINAPI domcdata_hasChildNodes( VARIANT_BOOL* pbool) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_hasChildNodes( This->element, pbool ); + return IXMLDOMNode_hasChildNodes( This->node, pbool ); } static HRESULT WINAPI domcdata_get_ownerDocument( @@ -317,7 +322,7 @@ static HRESULT WINAPI domcdata_get_ownerDocument( IXMLDOMDocument** domDocument) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_ownerDocument( This->element, domDocument ); + return IXMLDOMNode_get_ownerDocument( This->node, domDocument ); } static HRESULT WINAPI domcdata_cloneNode( @@ -325,7 +330,7 @@ static HRESULT WINAPI domcdata_cloneNode( VARIANT_BOOL pbool, IXMLDOMNode** outNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_cloneNode( This->element, pbool, outNode ); + return IXMLDOMNode_cloneNode( This->node, pbool, outNode ); } static HRESULT WINAPI domcdata_get_nodeTypeString( @@ -333,7 +338,7 @@ static HRESULT WINAPI domcdata_get_nodeTypeString( BSTR* p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_nodeTypeString( This->element, p ); + return IXMLDOMNode_get_nodeTypeString( This->node, p ); } static HRESULT WINAPI domcdata_get_text( @@ -341,7 +346,7 @@ static HRESULT WINAPI domcdata_get_text( BSTR* p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_text( This->element, p ); + return IXMLDOMNode_get_text( This->node, p ); } static HRESULT WINAPI domcdata_put_text( @@ -349,7 +354,7 @@ static HRESULT WINAPI domcdata_put_text( BSTR p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_put_text( This->element, p ); + return IXMLDOMNode_put_text( This->node, p ); } static HRESULT WINAPI domcdata_get_specified( @@ -357,7 +362,7 @@ static HRESULT WINAPI domcdata_get_specified( VARIANT_BOOL* pbool) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_specified( This->element, pbool ); + return IXMLDOMNode_get_specified( This->node, pbool ); } static HRESULT WINAPI domcdata_get_definition( @@ -365,7 +370,7 @@ static HRESULT WINAPI domcdata_get_definition( IXMLDOMNode** domNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_definition( This->element, domNode ); + return IXMLDOMNode_get_definition( This->node, domNode ); } static HRESULT WINAPI domcdata_get_nodeTypedValue( @@ -373,7 +378,7 @@ static HRESULT WINAPI domcdata_get_nodeTypedValue( VARIANT* var1) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_nodeTypedValue( This->element, var1 ); + return IXMLDOMNode_get_nodeTypedValue( This->node, var1 ); } static HRESULT WINAPI domcdata_put_nodeTypedValue( @@ -381,7 +386,7 @@ static HRESULT WINAPI domcdata_put_nodeTypedValue( VARIANT var1) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_put_nodeTypedValue( This->element, var1 ); + return IXMLDOMNode_put_nodeTypedValue( This->node, var1 ); } static HRESULT WINAPI domcdata_get_dataType( @@ -389,7 +394,7 @@ static HRESULT WINAPI domcdata_get_dataType( VARIANT* var1) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_dataType( This->element, var1 ); + return IXMLDOMNode_get_dataType( This->node, var1 ); } static HRESULT WINAPI domcdata_put_dataType( @@ -397,7 +402,7 @@ static HRESULT WINAPI domcdata_put_dataType( BSTR p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_put_dataType( This->element, p ); + return IXMLDOMNode_put_dataType( This->node, p ); } static HRESULT WINAPI domcdata_get_xml( @@ -405,7 +410,7 @@ static HRESULT WINAPI domcdata_get_xml( BSTR* p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_xml( This->element, p ); + return IXMLDOMNode_get_xml( This->node, p ); } static HRESULT WINAPI domcdata_transformNode( @@ -413,7 +418,7 @@ static HRESULT WINAPI domcdata_transformNode( IXMLDOMNode* domNode, BSTR* p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_transformNode( This->element, domNode, p ); + return IXMLDOMNode_transformNode( This->node, domNode, p ); } static HRESULT WINAPI domcdata_selectNodes( @@ -421,7 +426,7 @@ static HRESULT WINAPI domcdata_selectNodes( BSTR p, IXMLDOMNodeList** outList) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_selectNodes( This->element, p, outList ); + return IXMLDOMNode_selectNodes( This->node, p, outList ); } static HRESULT WINAPI domcdata_selectSingleNode( @@ -429,7 +434,7 @@ static HRESULT WINAPI domcdata_selectSingleNode( BSTR p, IXMLDOMNode** outNode) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_selectSingleNode( This->element, p, outNode ); + return IXMLDOMNode_selectSingleNode( This->node, p, outNode ); } static HRESULT WINAPI domcdata_get_parsed( @@ -437,7 +442,7 @@ static HRESULT WINAPI domcdata_get_parsed( VARIANT_BOOL* pbool) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_parsed( This->element, pbool ); + return IXMLDOMNode_get_parsed( This->node, pbool ); } static HRESULT WINAPI domcdata_get_namespaceURI( @@ -445,7 +450,7 @@ static HRESULT WINAPI domcdata_get_namespaceURI( BSTR* p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_namespaceURI( This->element, p ); + return IXMLDOMNode_get_namespaceURI( This->node, p ); } static HRESULT WINAPI domcdata_get_prefix( @@ -453,7 +458,7 @@ static HRESULT WINAPI domcdata_get_prefix( BSTR* p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_prefix( This->element, p ); + return IXMLDOMNode_get_prefix( This->node, p ); } static HRESULT WINAPI domcdata_get_baseName( @@ -461,7 +466,7 @@ static HRESULT WINAPI domcdata_get_baseName( BSTR* p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_get_baseName( This->element, p ); + return IXMLDOMNode_get_baseName( This->node, p ); } static HRESULT WINAPI domcdata_transformNodeToObject( @@ -469,7 +474,7 @@ static HRESULT WINAPI domcdata_transformNodeToObject( IXMLDOMNode* domNode, VARIANT var1) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - return IXMLDOMNode_transformNodeToObject( This->element, domNode, var1 ); + return IXMLDOMNode_transformNodeToObject( This->node, domNode, var1 ); } static HRESULT WINAPI domcdata_get_data( @@ -483,7 +488,7 @@ static HRESULT WINAPI domcdata_get_data( if(!p) return E_INVALIDARG; - hr = IXMLDOMNode_get_nodeValue( This->element, &vRet ); + hr = IXMLDOMNode_get_nodeValue( This->node, &vRet ); if(hr == S_OK) { *p = V_BSTR(&vRet); @@ -505,7 +510,7 @@ static HRESULT WINAPI domcdata_put_data( V_VT(&val) = VT_BSTR; V_BSTR(&val) = data; - hr = IXMLDOMNode_put_nodeValue( This->element, val ); + hr = IXMLDOMNode_put_nodeValue( This->node, val ); return hr; } @@ -515,7 +520,7 @@ static HRESULT WINAPI domcdata_get_length( long *len) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->element ); + xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->node ); xmlChar *pContent; long nLength = 0; @@ -541,7 +546,7 @@ static HRESULT WINAPI domcdata_substringData( long offset, long count, BSTR *p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->element ); + xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->node ); xmlChar *pContent; long nLength = 0; HRESULT hr = S_FALSE; @@ -586,7 +591,7 @@ static HRESULT WINAPI domcdata_appendData( BSTR p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->element ); + xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->node ); xmlChar *pContent; HRESULT hr = S_FALSE; @@ -606,6 +611,7 @@ static HRESULT WINAPI domcdata_appendData( } else hr = E_FAIL; + HeapFree(GetProcessHeap(), 0, pContent); return hr; } @@ -615,7 +621,7 @@ static HRESULT WINAPI domcdata_insertData( long offset, BSTR p) { domcdata *This = impl_from_IXMLDOMCDATASection( iface ); - xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->element ); + xmlnode *pDOMNode = impl_from_IXMLDOMNode( (IXMLDOMNode*)This->node ); xmlChar *pXmlContent; BSTR sNewString; HRESULT hr = S_FALSE; @@ -667,6 +673,7 @@ static HRESULT WINAPI domcdata_insertData( xmlNodeSetContent(pDOMNode->node, str); hr = S_OK; } + HeapFree(GetProcessHeap(), 0, str); SysFreeString(sNewString); } @@ -772,22 +779,22 @@ IUnknown* create_cdata( xmlNodePtr text ) This->lpVtbl = &domcdata_vtbl; This->ref = 1; - This->element_unk = create_element( text, (IUnknown*)&This->lpVtbl ); - if(!This->element_unk) + This->node_unk = create_basic_node( text, (IUnknown*)&This->lpVtbl ); + if(!This->node_unk) { HeapFree(GetProcessHeap(), 0, This); return NULL; } - hr = IUnknown_QueryInterface(This->element_unk, &IID_IXMLDOMNode, (LPVOID*)&This->element); + hr = IUnknown_QueryInterface(This->node_unk, &IID_IXMLDOMNode, (LPVOID*)&This->node); if(FAILED(hr)) { - IUnknown_Release(This->element_unk); + IUnknown_Release(This->node_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); + /* The ref on This->node is actually looped back into this object, so release it */ + IXMLDOMNode_Release(This->node); return (IUnknown*) &This->lpVtbl; } diff --git a/reactos/dll/win32/msxml3/comment.c b/reactos/dll/win32/msxml3/comment.c index 1870b3bcd93..20781a13d3a 100644 --- a/reactos/dll/win32/msxml3/comment.c +++ b/reactos/dll/win32/msxml3/comment.c @@ -601,29 +601,22 @@ static HRESULT WINAPI domcomment_appendData( /* Older versions of libxml < 2.6.27 didn't correctly support xmlTextConcat on Comment nodes. Fallback to setting the contents directly if xmlTextConcat fails. - - NOTE: if xmlTextConcat fails, pContent is destroyed. */ if(xmlTextConcat(pDOMNode->node, pContent, SysStringLen(p) ) == 0) hr = S_OK; else { xmlChar *pNew; - pContent = xmlChar_from_wchar( (WCHAR*)p ); - if(pContent) + pNew = xmlStrcat(xmlNodeGetContent(pDOMNode->node), pContent); + if(pNew) { - pNew = xmlStrcat(xmlNodeGetContent(pDOMNode->node), pContent); - if(pNew) - { - xmlNodeSetContent(pDOMNode->node, pNew); - hr = S_OK; - } - else - hr = E_FAIL; + xmlNodeSetContent(pDOMNode->node, pNew); + hr = S_OK; } else hr = E_FAIL; } + HeapFree( GetProcessHeap(), 0, pContent ); } else hr = E_FAIL; @@ -688,6 +681,7 @@ static HRESULT WINAPI domcomment_insertData( xmlNodeSetContent(pDOMNode->node, str); hr = S_OK; } + HeapFree( GetProcessHeap(), 0, str ); SysFreeString(sNewString); } diff --git a/reactos/dll/win32/msxml3/dispex.c b/reactos/dll/win32/msxml3/dispex.c index 0ccda74bca2..ab9d909035e 100644 --- a/reactos/dll/win32/msxml3/dispex.c +++ b/reactos/dll/win32/msxml3/dispex.c @@ -94,6 +94,7 @@ static REFIID tid_ids[] = { &IID_IXMLDOMText, &IID_IXMLElement, &IID_IXMLDOMDocument, + &IID_IXMLHTTPRequest, &IID_IVBSAXAttributes, &IID_IVBSAXContentHandler, &IID_IVBSAXDeclHandler, @@ -435,18 +436,37 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW } if(grfdex & fdexNameEnsure) { + dispex_dynamic_data_t *dynamic_data; + 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); + if(This->dynamic_data) { + dynamic_data = This->dynamic_data; + }else { + dynamic_data = This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t)); + if(!dynamic_data) + return E_OUTOFMEMORY; } - 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++; + if(!dynamic_data->buf_size) { + dynamic_data->props = heap_alloc(sizeof(dynamic_prop_t)*4); + if(!dynamic_data->props) + return E_OUTOFMEMORY; + dynamic_data->buf_size = 4; + }else if(dynamic_data->buf_size == dynamic_data->prop_cnt) { + dynamic_prop_t *new_props; + + new_props = heap_realloc(dynamic_data->props, sizeof(dynamic_prop_t)*(dynamic_data->buf_size<<1)); + if(!new_props) + return E_OUTOFMEMORY; + + dynamic_data->props = new_props; + dynamic_data->buf_size <<= 1; + } + + dynamic_data->props[dynamic_data->prop_cnt].name = heap_strdupW(bstrName); + VariantInit(&dynamic_data->props[dynamic_data->prop_cnt].var); + *pid = DISPID_DYNPROP_0 + dynamic_data->prop_cnt++; return S_OK; } diff --git a/reactos/dll/win32/msxml3/domdoc.c b/reactos/dll/win32/msxml3/domdoc.c index 3c5aedef483..a24f16fa97e 100644 --- a/reactos/dll/win32/msxml3/domdoc.c +++ b/reactos/dll/win32/msxml3/domdoc.c @@ -39,6 +39,7 @@ #include "dispex.h" #include "wine/debug.h" +#include "wine/list.h" #include "msxml_private.h" @@ -56,6 +57,7 @@ typedef struct _domdoc const struct IPersistStreamVtbl *lpvtblIPersistStream; const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite; const struct IObjectSafetyVtbl *lpvtblIObjectSafety; + const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo; LONG ref; VARIANT_BOOL async; VARIANT_BOOL validating; @@ -81,6 +83,57 @@ typedef struct _domdoc DispatchEx dispex; } domdoc; +/* + In native windows, the whole lifetime management of XMLDOMNodes is + managed automatically using reference counts. Wine emulates that by + maintaining a reference count to the document that is increased for + each IXMLDOMNode pointer passed out for this document. If all these + pointers are gone, the document is unreachable and gets freed, that + is, all nodes in the tree of the document get freed. + + You are able to create nodes that are associated to a document (in + fact, in msxml's XMLDOM model, all nodes are associated to a document), + but not in the tree of that document, for example using the createFoo + functions from IXMLDOMDocument. These nodes do not get cleaned up + by libxml, so we have to do it ourselves. + + To catch these nodes, a list of "orphan nodes" is introduced. + It contains pointers to all roots of node trees that are + associated with the document without being part of the document + tree. All nodes with parent==NULL (except for the document root nodes) + should be in the orphan node list of their document. All orphan nodes + get freed together with the document itself. + */ + +typedef struct _xmldoc_priv { + LONG refs; + struct list orphans; +} xmldoc_priv; + +typedef struct _orphan_entry { + struct list entry; + xmlNode * node; +} orphan_entry; + +static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc) +{ + return doc->_private; +} + +static xmldoc_priv * create_priv(void) +{ + xmldoc_priv *priv; + priv = HeapAlloc( GetProcessHeap(), 0, sizeof (*priv) ); + + if(priv) + { + priv->refs = 0; + list_init( &priv->orphans ); + } + + return priv; +} + static xmlDocPtr doparse( char *ptr, int len ) { #ifdef HAVE_XMLREADMEMORY @@ -97,24 +150,80 @@ static xmlDocPtr doparse( char *ptr, int len ) LONG xmldoc_add_ref(xmlDocPtr doc) { - LONG ref = InterlockedIncrement((LONG*)&doc->_private); + LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs); TRACE("%d\n", ref); return ref; } LONG xmldoc_release(xmlDocPtr doc) { - LONG ref = InterlockedDecrement((LONG*)&doc->_private); + xmldoc_priv *priv = priv_from_xmlDocPtr(doc); + LONG ref = InterlockedDecrement(&priv->refs); TRACE("%d\n", ref); if(ref == 0) { + orphan_entry *orphan, *orphan2; TRACE("freeing docptr %p\n", doc); + + LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry ) + { + xmlFreeNode( orphan->node ); + HeapFree( GetProcessHeap(), 0, orphan ); + } + HeapFree(GetProcessHeap(), 0, doc->_private); + xmlFreeDoc(doc); } return ref; } +HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node) +{ + xmldoc_priv *priv = priv_from_xmlDocPtr(doc); + orphan_entry *entry; + + entry = HeapAlloc( GetProcessHeap(), 0, sizeof (*entry) ); + if(!entry) + return E_OUTOFMEMORY; + + entry->node = node; + list_add_head( &priv->orphans, &entry->entry ); + return S_OK; +} + +HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node) +{ + xmldoc_priv *priv = priv_from_xmlDocPtr(doc); + orphan_entry *entry, *entry2; + + LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry ) + { + if( entry->node == node ) + { + list_remove( &entry->entry ); + HeapFree( GetProcessHeap(), 0, entry ); + return S_OK; + } + } + + return S_FALSE; +} + +static HRESULT attach_xmldoc( IXMLDOMNode *node, xmlDocPtr xml ) +{ + xmlnode *This = impl_from_IXMLDOMNode( node ); + + if(This->node) + xmldoc_release(This->node->doc); + + This->node = (xmlNodePtr) xml; + if(This->node) + xmldoc_add_ref(This->node->doc); + + return S_OK; +} + static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface ) { return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl)); @@ -140,6 +249,10 @@ static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface) return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety)); } +static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface) +{ + return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo)); +} /************************************************************************ * xmldoc implementation of IPersistStream. @@ -236,9 +349,9 @@ static HRESULT WINAPI xmldoc_IPersistStream_Load( return E_FAIL; } - attach_xmlnode( This->node, (xmlNodePtr)xmldoc ); + xmldoc->_private = create_priv(); - return S_OK; + return attach_xmldoc( This->node, xmldoc ); } static HRESULT WINAPI xmldoc_IPersistStream_Save( @@ -267,6 +380,46 @@ static const IPersistStreamVtbl xmldoc_IPersistStream_VTable = xmldoc_IPersistStream_GetSizeMax, }; +/* ISupportErrorInfo interface */ +static HRESULT WINAPI support_error_QueryInterface( + ISupportErrorInfo *iface, + REFIID riid, void** ppvObj ) +{ + domdoc *This = impl_from_ISupportErrorInfo(iface); + return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj); +} + +static ULONG WINAPI support_error_AddRef( + ISupportErrorInfo *iface ) +{ + domdoc *This = impl_from_ISupportErrorInfo(iface); + return IXMLDocument_AddRef((IXMLDocument *)This); +} + +static ULONG WINAPI support_error_Release( + ISupportErrorInfo *iface ) +{ + domdoc *This = impl_from_ISupportErrorInfo(iface); + return IXMLDocument_Release((IXMLDocument *)This); +} + +static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo( + ISupportErrorInfo *iface, + REFIID riid ) +{ + FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid)); + return S_FALSE; +} + +static const struct ISupportErrorInfoVtbl support_error_vtbl = +{ + support_error_QueryInterface, + support_error_AddRef, + support_error_Release, + support_error_InterfaceSupportsErrorInfo +}; + +/* IXMLDOMDocument2 interface */ static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject ) { domdoc *This = impl_from_IXMLDOMDocument2( iface ); @@ -294,6 +447,10 @@ static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID rii { *ppvObject = (IObjectWithSite*)&(This->lpvtblIObjectWithSite); } + else if( IsEqualGUID( riid, &IID_ISupportErrorInfo )) + { + *ppvObject = &This->lpvtblISupportErrorInfo; + } else if(dispex_query_interface(&This->dispex, riid, ppvObject)) { return *ppvObject ? S_OK : E_NOINTERFACE; @@ -827,6 +984,7 @@ static HRESULT WINAPI domdoc_put_documentElement( { domdoc *This = impl_from_IXMLDOMDocument2( iface ); IXMLDOMNode *elementNode; + xmlNodePtr oldRoot; xmlnode *xmlNode; HRESULT hr; @@ -837,9 +995,17 @@ static HRESULT WINAPI domdoc_put_documentElement( return hr; xmlNode = impl_from_IXMLDOMNode( elementNode ); - xmlDocSetRootElement( get_doc(This), xmlNode->node); + + if(!xmlNode->node->parent) + if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK) + WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node); + + oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node); IXMLDOMNode_Release( elementNode ); + if(oldRoot) + xmldoc_add_orphan(oldRoot->doc, oldRoot); + return S_OK; } @@ -859,6 +1025,7 @@ static HRESULT WINAPI domdoc_createElement( xml_name = xmlChar_from_wchar((WCHAR*)tagname); xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL); + xmldoc_add_orphan(xmlnode->doc, xmlnode); TRACE("created xmlptr %p\n", xmlnode); elem_unk = create_element(xmlnode, NULL); @@ -890,8 +1057,7 @@ static HRESULT WINAPI domdoc_createDocumentFragment( if(!xmlnode) return E_FAIL; - xmlnode->doc = get_doc( This ); - + xmldoc_add_orphan(xmlnode->doc, xmlnode); *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode); return S_OK; @@ -922,6 +1088,7 @@ static HRESULT WINAPI domdoc_createTextNode( return E_FAIL; xmlnode->doc = get_doc( This ); + xmldoc_add_orphan(xmlnode->doc, xmlnode); *text = (IXMLDOMText*)create_text(xmlnode); @@ -953,6 +1120,7 @@ static HRESULT WINAPI domdoc_createComment( return E_FAIL; xmlnode->doc = get_doc( This ); + xmldoc_add_orphan(xmlnode->doc, xmlnode); *comment = (IXMLDOMComment*)create_comment(xmlnode); @@ -984,6 +1152,7 @@ static HRESULT WINAPI domdoc_createCDATASection( return E_FAIL; xmlnode->doc = get_doc( This ); + xmldoc_add_orphan(xmlnode->doc, xmlnode); *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode); @@ -1014,6 +1183,7 @@ static HRESULT WINAPI domdoc_createProcessingInstruction( xml_content = xmlChar_from_wchar((WCHAR*)data); xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content); + xmldoc_add_orphan(xmlnode->doc, xmlnode); TRACE("created xmlptr %p\n", xmlnode); *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode); @@ -1052,6 +1222,7 @@ static HRESULT WINAPI domdoc_createAttribute( return E_FAIL; xmlnode->doc = get_doc( This ); + xmldoc_add_orphan(xmlnode->doc, xmlnode); *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode); @@ -1083,6 +1254,7 @@ static HRESULT WINAPI domdoc_createEntityReference( return E_FAIL; xmlnode->doc = get_doc( This ); + xmldoc_add_orphan(xmlnode->doc, xmlnode); *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode); @@ -1110,13 +1282,19 @@ static HRESULT WINAPI domdoc_getElementsByTagName( return hr; } -static DOMNodeType get_node_type(VARIANT Type) +static HRESULT get_node_type(VARIANT Type, DOMNodeType * type) { - if(V_VT(&Type) == VT_I4) - return V_I4(&Type); + VARIANT tmp; + HRESULT hr; - FIXME("Unsupported variant type %x\n", V_VT(&Type)); - return 0; + VariantInit(&tmp); + hr = VariantChangeType(&tmp, &Type, 0, VT_I4); + if(FAILED(hr)) + return E_INVALIDARG; + + *type = V_I4(&tmp); + + return S_OK; } static HRESULT WINAPI domdoc_createNode( @@ -1130,10 +1308,14 @@ static HRESULT WINAPI domdoc_createNode( DOMNodeType node_type; xmlNodePtr xmlnode = NULL; xmlChar *xml_name; + HRESULT hr; TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node); - node_type = get_node_type(Type); + hr = get_node_type(Type, &node_type); + if(FAILED(hr)) + return hr; + TRACE("node_type %d\n", node_type); xml_name = xmlChar_from_wchar((WCHAR*)name); @@ -1165,7 +1347,10 @@ static HRESULT WINAPI domdoc_createNode( HeapFree(GetProcessHeap(), 0, xml_name); if(xmlnode && *node) + { + xmldoc_add_orphan(xmlnode->doc, xmlnode); return S_OK; + } return E_FAIL; } @@ -1186,8 +1371,8 @@ static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len) xmldoc = doparse( ptr, len ); if(xmldoc) { - xmldoc->_private = 0; - attach_xmlnode(This->node, (xmlNodePtr) xmldoc); + xmldoc->_private = create_priv(); + return attach_xmldoc(This->node, xmldoc); } return S_OK; @@ -1227,8 +1412,6 @@ static HRESULT WINAPI domdoc_load( assert( This->node ); - attach_xmlnode(This->node, NULL); - switch( V_VT(&xmlSource) ) { case VT_BSTR: @@ -1242,11 +1425,12 @@ static HRESULT WINAPI domdoc_load( { domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc ); xmldoc = xmlCopyDoc(get_doc(newDoc), 1); - attach_xmlnode(This->node, (xmlNodePtr) xmldoc); + hr = attach_xmldoc(This->node, xmldoc); - *isSuccessful = VARIANT_TRUE; + if(SUCCEEDED(hr)) + *isSuccessful = VARIANT_TRUE; - return S_OK; + return hr; } } hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream); @@ -1302,9 +1486,10 @@ static HRESULT WINAPI domdoc_load( if(!filename || FAILED(hr)) { xmldoc = xmlNewDoc(NULL); - xmldoc->_private = 0; - attach_xmlnode(This->node, (xmlNodePtr) xmldoc); - hr = S_FALSE; + xmldoc->_private = create_priv(); + hr = attach_xmldoc(This->node, xmldoc); + if(SUCCEEDED(hr)) + hr = S_FALSE; } TRACE("ret (%d)\n", hr); @@ -1406,14 +1591,12 @@ static HRESULT WINAPI domdoc_loadXML( xmlDocPtr xmldoc = NULL; char *str; int len; - HRESULT hr = S_FALSE; + HRESULT hr = S_FALSE, hr2; TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful ); assert ( This->node ); - attach_xmlnode( This->node, NULL ); - if ( isSuccessful ) { *isSuccessful = VARIANT_FALSE; @@ -1434,8 +1617,10 @@ static HRESULT WINAPI domdoc_loadXML( if(!xmldoc) xmldoc = xmlNewDoc(NULL); - xmldoc->_private = 0; - attach_xmlnode( This->node, (xmlNodePtr) xmldoc ); + xmldoc->_private = create_priv(); + hr2 = attach_xmldoc( This->node, xmldoc ); + if( FAILED(hr2) ) + hr = hr2; return hr; } @@ -2002,6 +2187,7 @@ HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **docu doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable; doc->lpvtblIObjectWithSite = &domdocObjectSite; doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl; + doc->lpvtblISupportErrorInfo = &support_error_vtbl; doc->ref = 1; doc->async = 0; doc->validating = 0; @@ -2052,7 +2238,7 @@ HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj) if(!xmldoc) return E_OUTOFMEMORY; - xmldoc->_private = 0; + xmldoc->_private = create_priv(); hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj); if(FAILED(hr)) diff --git a/reactos/dll/win32/msxml3/element.c b/reactos/dll/win32/msxml3/element.c index 4b9bf6cae04..f4793958f8a 100644 --- a/reactos/dll/win32/msxml3/element.c +++ b/reactos/dll/win32/msxml3/element.c @@ -478,7 +478,7 @@ static HRESULT WINAPI domelem_get_tagName( len = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) element->name, -1, NULL, 0 ); if (element->ns) len += MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) element->ns->prefix, -1, NULL, 0 ); - str = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) ); + str = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) ); if ( !str ) return E_OUTOFMEMORY; if (element->ns) @@ -587,23 +587,32 @@ static HRESULT WINAPI domelem_getAttributeNode( xmlNodePtr element; xmlAttrPtr attr; IUnknown *unk; - HRESULT hr = E_FAIL; + HRESULT hr = S_FALSE; TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), attributeNode); + if(!attributeNode) + return E_FAIL; + + *attributeNode = NULL; + element = get_element( This ); if ( !element ) return E_FAIL; xml_name = xmlChar_from_wchar(p); + if(!xmlValidateNameValue(xml_name)) + { + HeapFree(GetProcessHeap(), 0, xml_name); + return E_FAIL; + } + attr = xmlHasProp(element, xml_name); if(attr) { unk = create_attribute((xmlNodePtr)attr); hr = IUnknown_QueryInterface(unk, &IID_IXMLDOMAttribute, (void**)attributeNode); IUnknown_Release(unk); - }else { - *attributeNode = NULL; } HeapFree(GetProcessHeap(), 0, xml_name); diff --git a/reactos/dll/win32/msxml3/factory.c b/reactos/dll/win32/msxml3/factory.c index beb5bbcf8b2..37dfe01afcc 100644 --- a/reactos/dll/win32/msxml3/factory.c +++ b/reactos/dll/win32/msxml3/factory.c @@ -134,6 +134,7 @@ static xmlcf domdoccf = { &xmlcf_vtbl, DOMDocument_create }; static xmlcf schemacf = { &xmlcf_vtbl, SchemaCache_create }; static xmlcf xmldoccf = { &xmlcf_vtbl, XMLDocument_create }; static xmlcf saxreadcf = { &xmlcf_vtbl, SAXXMLReader_create }; +static xmlcf httpreqcf = { &xmlcf_vtbl, XMLHTTPRequest_create }; /****************************************************************** * DllGetClassObject (MSXML3.@) @@ -169,6 +170,10 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID iid, LPVOID *ppv ) { cf = (IClassFactory*) &saxreadcf.lpVtbl; } + else if( IsEqualCLSID( rclsid, &CLSID_XMLHTTPRequest)) + { + cf = (IClassFactory*) &httpreqcf.lpVtbl; + } if ( !cf ) return CLASS_E_CLASSNOTAVAILABLE; diff --git a/reactos/dll/win32/msxml3/httprequest.c b/reactos/dll/win32/msxml3/httprequest.c new file mode 100644 index 00000000000..c5395738427 --- /dev/null +++ b/reactos/dll/win32/msxml3/httprequest.c @@ -0,0 +1,343 @@ +/* + * IXMLHTTPRequest implementation + * + * Copyright 2008 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 _httprequest +{ + const struct IXMLHTTPRequestVtbl *lpVtbl; + LONG ref; +} httprequest; + +static inline httprequest *impl_from_IXMLHTTPRequest( IXMLHTTPRequest *iface ) +{ + return (httprequest *)((char*)iface - FIELD_OFFSET(httprequest, lpVtbl)); +} + +static HRESULT WINAPI httprequest_QueryInterface(IXMLHTTPRequest *iface, REFIID riid, void **ppvObject) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); + + if ( IsEqualGUID( riid, &IID_IXMLHTTPRequest) || + IsEqualGUID( riid, &IID_IDispatch) || + IsEqualGUID( riid, &IID_IUnknown) ) + { + *ppvObject = iface; + } + else + { + FIXME("Unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } + + IXMLHTTPRequest_AddRef( iface ); + + return S_OK; +} + +static ULONG WINAPI httprequest_AddRef(IXMLHTTPRequest *iface) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + return InterlockedIncrement( &This->ref ); +} + +static ULONG WINAPI httprequest_Release(IXMLHTTPRequest *iface) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + ULONG ref; + + ref = InterlockedDecrement( &This->ref ); + if ( ref == 0 ) + { + HeapFree( GetProcessHeap(), 0, This ); + } + + return ref; +} + +static HRESULT WINAPI httprequest_GetTypeInfoCount(IXMLHTTPRequest *iface, UINT *pctinfo) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + TRACE("(%p)->(%p)\n", This, pctinfo); + + *pctinfo = 1; + + return S_OK; +} + +static HRESULT WINAPI httprequest_GetTypeInfo(IXMLHTTPRequest *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + HRESULT hr; + + TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + + hr = get_typeinfo(IXMLHTTPRequest_tid, ppTInfo); + + return hr; +} + +static HRESULT WINAPI httprequest_GetIDsOfNames(IXMLHTTPRequest *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + httprequest *This = impl_from_IXMLHTTPRequest( 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(IXMLHTTPRequest_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI httprequest_Invoke(IXMLHTTPRequest *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + httprequest *This = impl_from_IXMLHTTPRequest( 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(IXMLHTTPRequest_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 httprequest_open(IXMLHTTPRequest *iface, BSTR bstrMethod, BSTR bstrUrl, + VARIANT varAsync, VARIANT bstrUser, VARIANT bstrPassword) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub (%p)\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_setRequestHeader(IXMLHTTPRequest *iface, BSTR bstrHeader, BSTR bstrValue) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub (%p) %s %s\n", This, debugstr_w(bstrHeader), debugstr_w(bstrValue)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_getResponseHeader(IXMLHTTPRequest *iface, BSTR bstrHeader, BSTR *pbstrValue) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub (%p) %s %p\n", This, debugstr_w(bstrHeader), pbstrValue); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_getAllResponseHeaders(IXMLHTTPRequest *iface, BSTR *pbstrHeaders) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub (%p) %p\n", This, pbstrHeaders); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_send(IXMLHTTPRequest *iface, VARIANT varBody) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub (%p)\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_abort(IXMLHTTPRequest *iface) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub (%p)\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_get_status(IXMLHTTPRequest *iface, long *plStatus) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub %p %p\n", This, plStatus); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_get_statusText(IXMLHTTPRequest *iface, BSTR *pbstrStatus) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub %p %p\n", This, pbstrStatus); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_get_responseXML(IXMLHTTPRequest *iface, IDispatch **ppBody) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub %p %p\n", This, ppBody); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_get_responseText(IXMLHTTPRequest *iface, BSTR *pbstrBody) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub %p %p\n", This, pbstrBody); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_get_responseBody(IXMLHTTPRequest *iface, VARIANT *pvarBody) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub %p %p\n", This, pvarBody); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_get_responseStream(IXMLHTTPRequest *iface, VARIANT *pvarBody) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub %p %p\n", This, pvarBody); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_get_readyState(IXMLHTTPRequest *iface, long *plState) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub %p %p\n", This, plState); + + return E_NOTIMPL; +} + +static HRESULT WINAPI httprequest_put_onreadystatechange(IXMLHTTPRequest *iface, IDispatch *pReadyStateSink) +{ + httprequest *This = impl_from_IXMLHTTPRequest( iface ); + + FIXME("stub %p %p\n", This, pReadyStateSink); + + return E_NOTIMPL; +} + +static const struct IXMLHTTPRequestVtbl dimimpl_vtbl = +{ + httprequest_QueryInterface, + httprequest_AddRef, + httprequest_Release, + httprequest_GetTypeInfoCount, + httprequest_GetTypeInfo, + httprequest_GetIDsOfNames, + httprequest_Invoke, + httprequest_open, + httprequest_setRequestHeader, + httprequest_getResponseHeader, + httprequest_getAllResponseHeaders, + httprequest_send, + httprequest_abort, + httprequest_get_status, + httprequest_get_statusText, + httprequest_get_responseXML, + httprequest_get_responseText, + httprequest_get_responseBody, + httprequest_get_responseStream, + httprequest_get_readyState, + httprequest_put_onreadystatechange +}; + +HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, LPVOID *ppObj) +{ + httprequest *req; + HRESULT hr = S_OK; + + TRACE("(%p,%p)\n", pUnkOuter, ppObj); + + req = HeapAlloc( GetProcessHeap(), 0, sizeof (*req) ); + if( !req ) + return E_OUTOFMEMORY; + + req->lpVtbl = &dimimpl_vtbl; + req->ref = 1; + + *ppObj = &req->lpVtbl; + + TRACE("returning iface %p\n", *ppObj); + + return hr; +} + +#else + +HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, LPVOID *ppObj) +{ + MESSAGE("This program tried to use a XMLHTTPRequest object, but\n" + "libxml2 support was not present at compile time.\n"); + return E_NOTIMPL; +} + +#endif diff --git a/reactos/dll/win32/msxml3/main.c b/reactos/dll/win32/msxml3/main.c index b301ab75239..358a5cb3af1 100644 --- a/reactos/dll/win32/msxml3/main.c +++ b/reactos/dll/win32/msxml3/main.c @@ -20,6 +20,7 @@ */ #include "config.h" +#include "wine/port.h" #define COBJMACROS @@ -32,13 +33,10 @@ #include "msxml2.h" #include "wine/debug.h" +#include "wine/library.h" #include "msxml_private.h" -#ifdef HAVE_LIBXSLT -#include -#endif - WINE_DEFAULT_DEBUG_CHANNEL(msxml); HRESULT WINAPI DllCanUnloadNow(void) @@ -47,6 +45,45 @@ HRESULT WINAPI DllCanUnloadNow(void) return S_FALSE; } + +void* libxslt_handle = NULL; +#ifdef SONAME_LIBXSLT +# define DECL_FUNCPTR(f) typeof(f) * p##f = NULL +DECL_FUNCPTR(xsltApplyStylesheet); +DECL_FUNCPTR(xsltCleanupGlobals); +DECL_FUNCPTR(xsltFreeStylesheet); +DECL_FUNCPTR(xsltParseStylesheetDoc); +# undef MAKE_FUNCPTR +#endif + +static void init_libxslt(void) +{ +#ifdef SONAME_LIBXSLT + void (*pxsltInit)(void); /* Missing in libxslt <= 1.1.14 */ + + libxslt_handle = wine_dlopen(SONAME_LIBXSLT, RTLD_NOW, NULL, 0); + if (!libxslt_handle) + return; + +#define LOAD_FUNCPTR(f, needed) if ((p##f = wine_dlsym(libxslt_handle, #f, NULL, 0)) == NULL && needed) { WARN("Can't find symbol %s\n", #f); goto sym_not_found; } + LOAD_FUNCPTR(xsltInit, 0); + LOAD_FUNCPTR(xsltApplyStylesheet, 1); + LOAD_FUNCPTR(xsltCleanupGlobals, 1); + LOAD_FUNCPTR(xsltFreeStylesheet, 1); + LOAD_FUNCPTR(xsltParseStylesheetDoc, 1); +#undef LOAD_FUNCPTR + + if (pxsltInit) + pxsltInit(); + return; + + sym_not_found: + wine_dlclose(libxslt_handle, NULL, 0); + libxslt_handle = NULL; +#endif +} + + BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { switch(fdwReason) @@ -55,22 +92,22 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) #ifdef HAVE_LIBXML2 xmlInitParser(); - /* Set the default indent character to a single tab. */ + /* Set the default indent character to a single tab, + for this thread and as default for new threads */ + xmlTreeIndentString = "\t"; xmlThrDefTreeIndentString("\t"); #endif -#ifdef HAVE_XSLTINIT - xsltInit(); -#endif - -#ifdef HAVE_LIBXML2 - /* Set the current ident to the default */ - xmlTreeIndentString = "\t"; -#endif + init_libxslt(); DisableThreadLibraryCalls(hInstDLL); break; case DLL_PROCESS_DETACH: -#ifdef HAVE_LIBXSLT - xsltCleanupGlobals(); +#ifdef SONAME_LIBXSLT + if (libxslt_handle) + { + pxsltCleanupGlobals(); + wine_dlclose(libxslt_handle, NULL, 0); + libxslt_handle = NULL; + } #endif #ifdef HAVE_LIBXML2 xmlCleanupParser(); diff --git a/reactos/dll/win32/msxml3/msxml3.rbuild b/reactos/dll/win32/msxml3/msxml3.rbuild index e5553f42abf..ab3dedb5567 100644 --- a/reactos/dll/win32/msxml3/msxml3.rbuild +++ b/reactos/dll/win32/msxml3/msxml3.rbuild @@ -33,6 +33,7 @@ element.c factory.c main.c + httprequest.c node.c nodelist.c nodemap.c diff --git a/reactos/dll/win32/msxml3/msxml_private.h b/reactos/dll/win32/msxml3/msxml_private.h index 55b84dfa1d8..917543de706 100644 --- a/reactos/dll/win32/msxml3/msxml_private.h +++ b/reactos/dll/win32/msxml3/msxml_private.h @@ -54,8 +54,6 @@ extern IUnknown *create_doc_entity_ref( xmlNodePtr entity ); extern HRESULT queryresult_create( xmlNodePtr, LPWSTR, IXMLDOMNodeList ** ); -extern void attach_xmlnode( IXMLDOMNode *node, xmlNodePtr xmlnode ); - /* data accessors */ xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type ); @@ -65,9 +63,10 @@ extern BSTR bstr_from_xmlChar( const xmlChar *buf ); extern LONG xmldoc_add_ref( xmlDocPtr doc ); extern LONG xmldoc_release( xmlDocPtr doc ); +extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node ); +extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node ); extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj ); -extern HRESULT XMLElementCollection_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj ); extern xmlDocPtr parse_xml(char *ptr, int len); @@ -90,12 +89,32 @@ extern HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 #endif +void* libxslt_handle; +#ifdef SONAME_LIBXSLT +# ifdef HAVE_LIBXSLT_PATTERN_H +# include +# endif +# ifdef HAVE_LIBXSLT_TRANSFORM_H +# include +# endif +# include +# include + +# define MAKE_FUNCPTR(f) extern typeof(f) * p##f +MAKE_FUNCPTR(xsltApplyStylesheet); +MAKE_FUNCPTR(xsltCleanupGlobals); +MAKE_FUNCPTR(xsltFreeStylesheet); +MAKE_FUNCPTR(xsltParseStylesheetDoc); +# undef MAKE_FUNCPTR +#endif + extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText, LONG line, LONG linepos, LONG filepos ); extern HRESULT DOMDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj ); extern HRESULT SchemaCache_create( IUnknown *pUnkOuter, LPVOID *ppObj ); extern HRESULT XMLDocument_create( IUnknown *pUnkOuter, LPVOID *ppObj ); extern HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj ); +extern HRESULT XMLHTTPRequest_create(IUnknown *pUnkOuter, LPVOID *ppObj); typedef struct bsc_t bsc_t; @@ -122,6 +141,7 @@ typedef enum tid_t { IXMLDOMText_tid, IXMLElement_tid, IXMLDocument_tid, + IXMLHTTPRequest_tid, IVBSAXAttributes_tid, IVBSAXContentHandler_tid, IVBSAXDeclHandler_tid, diff --git a/reactos/dll/win32/msxml3/node.c b/reactos/dll/win32/msxml3/node.c index ee409c46c05..69601e39733 100644 --- a/reactos/dll/win32/msxml3/node.c +++ b/reactos/dll/win32/msxml3/node.c @@ -33,17 +33,6 @@ #include "msxml_private.h" -#ifdef HAVE_LIBXSLT -# ifdef HAVE_LIBXSLT_PATTERN_H -# include -# endif -# ifdef HAVE_LIBXSLT_TRANSFORM_H -# include -# endif -# include -# include -#endif - #ifdef HAVE_LIBXML2 # include #endif @@ -96,20 +85,6 @@ xmlNodePtr xmlNodePtr_from_domnode( IXMLDOMNode *iface, xmlElementType type ) return This->node; } -void attach_xmlnode( IXMLDOMNode *node, xmlNodePtr xml ) -{ - xmlnode *This = impl_from_IXMLDOMNode( node ); - - if(This->node) - xmldoc_release(This->node->doc); - - This->node = xml; - if(This->node) - xmldoc_add_ref(This->node->doc); - - return; -} - static HRESULT WINAPI xmlnode_QueryInterface( IXMLDOMNode *iface, REFIID riid, @@ -282,7 +257,7 @@ BSTR bstr_from_xmlChar( const xmlChar *buf ) return NULL; len = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) buf, -1, NULL, 0 ); - str = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) ); + str = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) ); if ( !str ) return NULL; MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) buf, -1, str, len ); @@ -344,11 +319,22 @@ static HRESULT WINAPI xmlnode_put_nodeValue( VARIANT value) { xmlnode *This = impl_from_IXMLDOMNode( iface ); - HRESULT hr = S_FALSE; + HRESULT hr; xmlChar *str = NULL; + VARIANT string_value; TRACE("%p type(%d)\n", This, This->node->type); + VariantInit(&string_value); + hr = VariantChangeType(&string_value, &value, 0, VT_BSTR); + if(FAILED(hr)) + { + VariantClear(&string_value); + WARN("Couldn't convert to VT_BSTR\n"); + return hr; + } + + hr = S_FALSE; /* Document, Document Fragment, Document Type, Element, Entity, Entity Reference, Notation aren't supported. */ switch ( This->node->type ) @@ -359,9 +345,9 @@ static HRESULT WINAPI xmlnode_put_nodeValue( case XML_PI_NODE: case XML_TEXT_NODE: { - str = xmlChar_from_wchar((WCHAR*)V_BSTR(&value)); - + str = xmlChar_from_wchar((WCHAR*)V_BSTR(&string_value)); xmlNodeSetContent(This->node, str); + HeapFree(GetProcessHeap(),0,str); hr = S_OK; break; } @@ -370,6 +356,8 @@ static HRESULT WINAPI xmlnode_put_nodeValue( break; } + VariantClear(&string_value); + return hr; } @@ -583,6 +571,10 @@ static HRESULT WINAPI xmlnode_insertBefore( new_child_node = impl_from_IXMLDOMNode(new)->node; TRACE("new_child_node %p This->node %p\n", new_child_node, This->node); + if(!new_child_node->parent) + if(xmldoc_remove_orphan(new_child_node->doc, new_child_node) != S_OK) + WARN("%p is not an orphan of %p\n", new_child_node, new_child_node->doc); + if(before) { before_node = impl_from_IXMLDOMNode(before)->node; @@ -609,8 +601,65 @@ static HRESULT WINAPI xmlnode_replaceChild( IXMLDOMNode* oldChild, IXMLDOMNode** outOldChild) { - FIXME("\n"); - return E_NOTIMPL; + xmlnode *This = impl_from_IXMLDOMNode( iface ); + xmlNode *old_child_ptr, *new_child_ptr; + xmlDocPtr leaving_doc; + xmlNode *my_ancestor; + IXMLDOMNode *realOldChild; + HRESULT hr; + + TRACE("%p->(%p,%p,%p)\n",This,newChild,oldChild,outOldChild); + + /* Do not believe any documentation telling that newChild == NULL + means removal. It does certainly *not* apply to msxml3! */ + if(!newChild || !oldChild) + return E_INVALIDARG; + + if(outOldChild) + *outOldChild = NULL; + + hr = IXMLDOMNode_QueryInterface(oldChild,&IID_IXMLDOMNode,(LPVOID*)&realOldChild); + if(FAILED(hr)) + return hr; + + old_child_ptr = impl_from_IXMLDOMNode(realOldChild)->node; + IXMLDOMNode_Release(realOldChild); + if(old_child_ptr->parent != This->node) + { + WARN("childNode %p is not a child of %p\n", oldChild, iface); + return E_INVALIDARG; + } + + new_child_ptr = impl_from_IXMLDOMNode(newChild)->node; + my_ancestor = This->node; + while(my_ancestor) + { + if(my_ancestor == new_child_ptr) + { + WARN("tried to create loop\n"); + return E_FAIL; + } + my_ancestor = my_ancestor->parent; + } + + if(!new_child_ptr->parent) + if(xmldoc_remove_orphan(new_child_ptr->doc, new_child_ptr) != S_OK) + WARN("%p is not an orphan of %p\n", new_child_ptr, new_child_ptr->doc); + + leaving_doc = new_child_ptr->doc; + xmldoc_add_ref(old_child_ptr->doc); + xmlReplaceNode(old_child_ptr, new_child_ptr); + xmldoc_release(leaving_doc); + + xmldoc_add_orphan(old_child_ptr->doc, old_child_ptr); + + if(outOldChild) + { + IXMLDOMNode_AddRef(oldChild); + *outOldChild = oldChild; + } + + return S_OK; } static HRESULT WINAPI xmlnode_removeChild( @@ -619,29 +668,23 @@ static HRESULT WINAPI xmlnode_removeChild( IXMLDOMNode** oldChild) { xmlnode *This = impl_from_IXMLDOMNode( iface ); - xmlNode *ancestor, *child_node_ptr; + xmlNode *child_node_ptr; HRESULT hr; IXMLDOMNode *child; TRACE("%p->(%p, %p)\n", This, childNode, oldChild); + if(!childNode) return E_INVALIDARG; + if(oldChild) *oldChild = NULL; - if(!childNode) return E_INVALIDARG; - hr = IXMLDOMNode_QueryInterface(childNode, &IID_IXMLDOMNode, (LPVOID)&child); if(FAILED(hr)) return hr; - child_node_ptr = ancestor = impl_from_IXMLDOMNode(child)->node; - while(ancestor->parent) - { - if(ancestor->parent == This->node) - break; - ancestor = ancestor->parent; - } - if(!ancestor->parent) + child_node_ptr = impl_from_IXMLDOMNode(child)->node; + if(child_node_ptr->parent != This->node) { WARN("childNode %p is not a child of %p\n", childNode, iface); IXMLDOMNode_Release(child); @@ -732,6 +775,7 @@ static HRESULT WINAPI xmlnode_cloneNode( if(pClone) { pClone->doc = This->node->doc; + xmldoc_add_orphan(pClone->doc, pClone); pNode = create_node(pClone); if(!pNode) @@ -820,32 +864,18 @@ static HRESULT WINAPI xmlnode_get_text( { xmlnode *This = impl_from_IXMLDOMNode( iface ); BSTR str = NULL; + xmlChar *pContent; - TRACE("%p\n", This); + TRACE("%p type %d\n", This, This->node->type); if ( !text ) return E_INVALIDARG; - switch(This->node->type) + pContent = xmlNodeGetContent((xmlNodePtr)This->node); + if(pContent) { - case XML_ELEMENT_NODE: - case XML_ATTRIBUTE_NODE: - { - xmlNodePtr child = This->node->children; - if ( child && child->type == XML_TEXT_NODE ) - str = bstr_from_xmlChar( child->content ); - break; - } - - case XML_TEXT_NODE: - case XML_CDATA_SECTION_NODE: - case XML_PI_NODE: - case XML_COMMENT_NODE: - str = bstr_from_xmlChar( This->node->content ); - break; - - default: - FIXME("Unhandled node type %d\n", This->node->type); + str = bstr_from_xmlChar(pContent); + xmlFree(pContent); } /* Always return a string. */ @@ -862,7 +892,7 @@ static HRESULT WINAPI xmlnode_put_text( BSTR text) { xmlnode *This = impl_from_IXMLDOMNode( iface ); - xmlChar *str = NULL; + xmlChar *str, *str2; TRACE("%p\n", This); @@ -877,11 +907,11 @@ static HRESULT WINAPI xmlnode_put_text( str = xmlChar_from_wchar((WCHAR*)text); /* Escape the string. */ - str = xmlEncodeEntitiesReentrant(This->node->doc, str); - str = xmlEncodeSpecialChars(This->node->doc, str); + str2 = xmlEncodeEntitiesReentrant(This->node->doc, str); + HeapFree(GetProcessHeap(), 0, str); - xmlNodeSetContent(This->node, str); - xmlFree(str); + xmlNodeSetContent(This->node, str2); + xmlFree(str2); return S_OK; } @@ -906,8 +936,32 @@ static HRESULT WINAPI xmlnode_get_nodeTypedValue( IXMLDOMNode *iface, VARIANT* typedValue) { - FIXME("ignoring data type\n"); - return xmlnode_get_nodeValue(iface, typedValue); + xmlnode *This = impl_from_IXMLDOMNode( iface ); + HRESULT r = S_FALSE; + + FIXME("ignoring data type %p %p\n", This, typedValue); + + if(!typedValue) + return E_INVALIDARG; + + V_VT(typedValue) = VT_NULL; + + switch ( This->node->type ) + { + case XML_ELEMENT_NODE: + { + xmlChar *content = xmlNodeGetContent(This->node); + V_VT(typedValue) = VT_BSTR; + V_BSTR(typedValue) = bstr_from_xmlChar( content ); + xmlFree(content); + r = S_OK; + break; + } + default: + r = xmlnode_get_nodeValue(iface, typedValue); + } + + return r; } static HRESULT WINAPI xmlnode_put_nodeTypedValue( @@ -1034,6 +1088,7 @@ static HRESULT WINAPI xmlnode_put_dataType( else ERR("Failed to Create Namepsace\n"); } + HeapFree( GetProcessHeap(), 0, str ); } return hr; @@ -1085,6 +1140,37 @@ static BSTR EnsureCorrectEOL(BSTR sInput) return sNew; } +/* Removes encoding information and last character (nullbyte) */ +static BSTR EnsureNoEncoding(BSTR sInput) +{ + static const WCHAR wszEncoding[] = {'e','n','c','o','d','i','n','g','='}; + BSTR sNew; + WCHAR *pBeg, *pEnd; + + pBeg = sInput; + while(*pBeg != '\n' && memcmp(pBeg, wszEncoding, sizeof(wszEncoding))) + pBeg++; + + if(*pBeg == '\n') + { + SysReAllocStringLen(&sInput, sInput, SysStringLen(sInput)-1); + return sInput; + } + pBeg--; + + pEnd = pBeg + sizeof(wszEncoding)/sizeof(WCHAR) + 2; + while(*pEnd != '\"') pEnd++; + pEnd++; + + sNew = SysAllocStringLen(NULL, + pBeg-sInput + SysStringLen(sInput)-(pEnd-sInput)-1); + memcpy(sNew, sInput, (pBeg-sInput)*sizeof(WCHAR)); + memcpy(&sNew[pBeg-sInput], pEnd, (SysStringLen(sInput)-(pEnd-sInput)-1)*sizeof(WCHAR)); + + SysFreeString(sInput); + return sNew; +} + /* * We are trying to replicate the same behaviour as msxml by converting * line endings to \r\n and using idents as \t. The problem is that msxml @@ -1123,7 +1209,18 @@ static HRESULT WINAPI xmlnode_get_xml( else bstrContent = bstr_from_xmlChar(pContent); - *xmlString = This->node->type == XML_ELEMENT_NODE ? EnsureCorrectEOL(bstrContent) : bstrContent; + switch(This->node->type) + { + case XML_ELEMENT_NODE: + *xmlString = EnsureCorrectEOL(bstrContent); + break; + case XML_DOCUMENT_NODE: + *xmlString = EnsureCorrectEOL(bstrContent); + *xmlString = EnsureNoEncoding(*xmlString); + break; + default: + *xmlString = bstrContent; + } } xmlBufferFree(pXmlBuf); @@ -1140,7 +1237,7 @@ static HRESULT WINAPI xmlnode_transformNode( IXMLDOMNode* styleSheet, BSTR* xmlString) { -#ifdef HAVE_LIBXSLT +#ifdef SONAME_LIBXSLT xmlnode *This = impl_from_IXMLDOMNode( iface ); xmlnode *pStyleSheet = NULL; xsltStylesheetPtr xsltSS = NULL; @@ -1149,6 +1246,8 @@ static HRESULT WINAPI xmlnode_transformNode( TRACE("%p %p %p\n", This, styleSheet, xmlString); + if (!libxslt_handle) + return E_NOTIMPL; if(!styleSheet || !xmlString) return E_INVALIDARG; @@ -1158,10 +1257,10 @@ static HRESULT WINAPI xmlnode_transformNode( { pStyleSheet = impl_from_IXMLDOMNode( ssNew ); - xsltSS = xsltParseStylesheetDoc( pStyleSheet->node->doc); + xsltSS = pxsltParseStylesheetDoc( pStyleSheet->node->doc); if(xsltSS) { - result = xsltApplyStylesheet(xsltSS, This->node->doc, NULL); + result = pxsltApplyStylesheet(xsltSS, This->node->doc, NULL); if(result) { const xmlChar *pContent; @@ -1172,12 +1271,8 @@ static HRESULT WINAPI xmlnode_transformNode( if(pOutput) { htmlDocContentDumpOutput(pOutput, result->doc, NULL); - if(pOutput) - { - pContent = xmlBufferContent(pOutput->buffer); - *xmlString = bstr_from_xmlChar(pContent); - } - + pContent = xmlBufferContent(pOutput->buffer); + *xmlString = bstr_from_xmlChar(pContent); xmlOutputBufferClose(pOutput); } } @@ -1194,12 +1289,16 @@ static HRESULT WINAPI xmlnode_transformNode( { pContent = xmlBufferContent(pXmlBuf); *xmlString = bstr_from_xmlChar(pContent); - - xmlBufferFree(pXmlBuf); } + xmlBufferFree(pXmlBuf); } } + xmlFreeDoc(result); } + /* libxslt "helpfully" frees the XML document the stylesheet was + generated from, too */ + xsltSS->doc = NULL; + pxsltFreeStylesheet(xsltSS); } IXMLDOMNode_Release(ssNew); @@ -1276,6 +1375,7 @@ static HRESULT WINAPI xmlnode_get_namespaceURI( { *namespaceURI = bstr_from_xmlChar( pNSList[0]->href ); + xmlFree( pNSList ); hr = S_OK; } @@ -1302,6 +1402,7 @@ static HRESULT WINAPI xmlnode_get_prefix( { *prefixString = bstr_from_xmlChar( pNSList[0]->prefix ); + xmlFree(pNSList); hr = S_OK; } diff --git a/reactos/dll/win32/msxml3/nodemap.c b/reactos/dll/win32/msxml3/nodemap.c index f41df2f7d08..8c7c1d01f59 100644 --- a/reactos/dll/win32/msxml3/nodemap.c +++ b/reactos/dll/win32/msxml3/nodemap.c @@ -265,6 +265,10 @@ static HRESULT WINAPI xmlnodemap_setNamedItem( return E_FAIL; } + if(!ThisNew->node->parent) + if(xmldoc_remove_orphan(ThisNew->node->doc, ThisNew->node) != S_OK) + WARN("%p is not an orphan of %p\n", ThisNew->node, ThisNew->node->doc); + nodeNew = xmlAddChild(node, ThisNew->node); if(namedItem) @@ -283,8 +287,44 @@ static HRESULT WINAPI xmlnodemap_removeNamedItem( BSTR name, IXMLDOMNode** namedItem) { - FIXME("\n"); - return E_NOTIMPL; + xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); + xmlChar *element_name; + xmlAttrPtr attr; + xmlNodePtr node; + + TRACE("%p %s %p\n", This, debugstr_w(name), namedItem ); + + if ( !name) + return E_INVALIDARG; + + node = xmlNodePtr_from_domnode( This->node, 0 ); + if ( !node ) + return E_FAIL; + + element_name = xmlChar_from_wchar( name ); + attr = xmlHasNsProp( node, element_name, NULL ); + HeapFree( GetProcessHeap(), 0, element_name ); + + if ( !attr ) + { + if( namedItem ) + *namedItem = NULL; + return S_FALSE; + } + + if ( namedItem ) + { + xmlUnlinkNode( (xmlNodePtr) attr ); + xmldoc_add_orphan( attr->doc, (xmlNodePtr) attr ); + *namedItem = create_node( (xmlNodePtr) attr ); + } + else + { + if( xmlRemoveProp( attr ) == -1 ) + ERR("xmlRemoveProp failed\n"); + } + + return S_OK; } static HRESULT WINAPI xmlnodemap_get_item( @@ -332,6 +372,9 @@ static HRESULT WINAPI xmlnodemap_get_length( TRACE("%p\n", This); + if( !listLength ) + return E_INVALIDARG; + node = xmlNodePtr_from_domnode( This->node, 0 ); if ( !node ) return E_FAIL; diff --git a/reactos/dll/win32/msxml3/queryresult.c b/reactos/dll/win32/msxml3/queryresult.c index 56c1a537674..e0367bca537 100644 --- a/reactos/dll/win32/msxml3/queryresult.c +++ b/reactos/dll/win32/msxml3/queryresult.c @@ -308,7 +308,7 @@ static HRESULT queryresult_get_dispid(IUnknown *iface, BSTR name, DWORD flags, D { queryresult *This = impl_from_IXMLDOMNodeList( (IXMLDOMNodeList*)iface ); WCHAR *ptr; - DWORD idx=0; + int idx = 0; for(ptr = name; *ptr && isdigitW(*ptr); ptr++) idx = idx*10 + (*ptr-'0'); @@ -340,7 +340,7 @@ static HRESULT queryresult_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fl IXMLDOMNode *disp = NULL; queryresult_get_item(XMLQUERYRES(This), id - MSXML_DISPID_CUSTOM_MIN, &disp); - V_DISPATCH(res) = (IDispatch*)&disp; + V_DISPATCH(res) = (IDispatch*)disp; break; } default: @@ -350,6 +350,8 @@ static HRESULT queryresult_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fl } } + TRACE("ret %p\n", V_DISPATCH(res)); + return S_OK; } diff --git a/reactos/dll/win32/msxml3/regsvr.c b/reactos/dll/win32/msxml3/regsvr.c index 320d51e280d..a6ed0ee72d2 100644 --- a/reactos/dll/win32/msxml3/regsvr.c +++ b/reactos/dll/win32/msxml3/regsvr.c @@ -45,6 +45,7 @@ #include "msxml_private.h" #include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -180,7 +181,7 @@ static HRESULT register_interfaces(struct regsvr_interface const *list) KEY_READ | KEY_WRITE, NULL, &key, NULL); if (res != ERROR_SUCCESS) goto error_close_iid_key; - wsprintfW(buf, fmt, list->num_methods); + sprintfW(buf, fmt, list->num_methods); res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)buf, (lstrlenW(buf) + 1) * sizeof(WCHAR)); diff --git a/reactos/dll/win32/msxml3/saxreader.c b/reactos/dll/win32/msxml3/saxreader.c index 6af9201f8d1..17a333419f3 100644 --- a/reactos/dll/win32/msxml3/saxreader.c +++ b/reactos/dll/win32/msxml3/saxreader.c @@ -55,7 +55,12 @@ typedef struct _saxreader struct IVBSAXContentHandler *vbcontentHandler; struct ISAXErrorHandler *errorHandler; struct IVBSAXErrorHandler *vberrorHandler; + struct ISAXLexicalHandler *lexicalHandler; + struct IVBSAXLexicalHandler *vblexicalHandler; + struct ISAXDeclHandler *declHandler; + struct IVBSAXDeclHandler *vbdeclHandler; xmlSAXHandler sax; + BOOL isParsing; } saxreader; typedef struct _saxlocator @@ -70,7 +75,9 @@ typedef struct _saxlocator WCHAR *systemId; xmlChar *lastCur; int line; + int realLine; int column; + int realColumn; BOOL vbInterface; int nsStackSize; int nsStackLast; @@ -154,7 +161,7 @@ static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len) dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0); if(len != -1) dLen++; - str = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, dLen * sizeof (WCHAR)); + str = HeapAlloc(GetProcessHeap(), 0, dLen * sizeof (WCHAR)); if (!str) return NULL; MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, str, dLen); @@ -225,14 +232,21 @@ 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; + This->realLine = 1; + This->realColumn = 1; } else if(This->lastCur < This->pParserCtxt->input->base) { This->lastCur = (xmlChar*)This->pParserCtxt->input->base; - This->line = 1; - This->column = 1; + This->realLine = 1; + This->realColumn = 1; + } + + if(This->pParserCtxt->input->curlastCur) + { + This->lastCur = (xmlChar*)This->pParserCtxt->input->base; + This->realLine -= 1; + This->realColumn = 1; } if(!end) end = (xmlChar*)This->pParserCtxt->input->cur; @@ -241,18 +255,26 @@ static void update_position(saxlocator *This, xmlChar *end) { if(*(This->lastCur) == '\n') { - This->line++; - This->column = 1; + This->realLine++; + This->realColumn = 1; } - else if(*(This->lastCur) == '\r' && (This->lastCur==This->pParserCtxt->input->end || *(This->lastCur+1)!='\n')) + else if(*(This->lastCur) == '\r' && + (This->lastCur==This->pParserCtxt->input->end || + *(This->lastCur+1)!='\n')) { - This->line++; - This->column = 1; + This->realLine++; + This->realColumn = 1; } - else This->column++; + else This->realColumn++; This->lastCur++; + + /* Count multibyte UTF8 encoded characters once */ + while((*(This->lastCur)&0xC0) == 0x80) This->lastCur++; } + + This->line = This->realLine; + This->column = This->realColumn; } /*** IVBSAXAttributes interface ***/ @@ -1018,7 +1040,10 @@ static void libxmlStartElementNS( saxattributes *attr; int index; - update_position(This, (xmlChar*)This->pParserCtxt->input->cur+1); + if(*(This->pParserCtxt->input->cur) == '/') + update_position(This, (xmlChar*)This->pParserCtxt->input->cur+2); + else + update_position(This, (xmlChar*)This->pParserCtxt->input->cur+1); hr = namespacePush(This, nb_namespaces); if(hr==S_OK && ((This->vbInterface && This->saxreader->vbcontentHandler) @@ -1093,9 +1118,11 @@ static void libxmlEndElementNS( xmlChar *end; int nsNr, index; - end = This->lastCur; - while(*end != '<' && *(end+1) != '/') end++; - update_position(This, end+2); + end = (xmlChar*)This->pParserCtxt->input->cur; + if(*(end-1) != '>' || *(end-2) != '/') + while(*(end-2)!='<' && *(end-1)!='/') end--; + + update_position(This, end); nsNr = namespacePop(This); @@ -1141,8 +1168,17 @@ static void libxmlEndElementNS( Prefix, SysStringLen(Prefix)); SysFreeString(Prefix); + + if(hr != S_OK) + { + format_error_message_from_id(This, hr); + return; + } + } } + + update_position(This, NULL); } static void libxmlCharacters( @@ -1150,84 +1186,71 @@ static void libxmlCharacters( const xmlChar *ch, int len) { - BSTR Chars; saxlocator *This = ctx; + BSTR Chars; HRESULT hr; + xmlChar *cur; xmlChar *end; - xmlChar *lastCurCopy; - xmlChar *chEnd; - int columnCopy; - int lineCopy; + BOOL lastEvent = FALSE; - if(*(This->lastCur-1) != '>' && *(This->lastCur-1) != '/') return; + if((This->vbInterface && !This->saxreader->vbcontentHandler) + || (!This->vbInterface && !This->saxreader->contentHandler)) + return; - if(*(This->lastCur-1) != '>') + cur = (xmlChar*)ch; + if(*(ch-1)=='\r') cur--; + end = cur; + + if(chpParserCtxt->input->base || ch>This->pParserCtxt->input->end) + This->column++; + + while(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) + while(end-chlastCur; - 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; + end--; + lastEvent = TRUE; } - This->lastCur = lastCurCopy; - This->column = columnCopy; - This->line = lineCopy; - update_position(This, chEnd); + if(!lastEvent) *end = '\n'; + + Chars = bstr_from_xmlCharN(cur, end-cur+1); + if(This->vbInterface) + hr = IVBSAXContentHandler_characters( + This->saxreader->vbcontentHandler, &Chars); + else + hr = ISAXContentHandler_characters( + This->saxreader->contentHandler, + Chars, SysStringLen(Chars)); + SysFreeString(Chars); + + if(hr != S_OK) + { + format_error_message_from_id(This, hr); + return; + } + + This->column += end-cur+1; + + if(lastEvent) + break; + + *end = '\r'; + end++; + if(*end == '\n') + { + end++; + This->column++; + } + cur = end; + + if(end-ch == len) break; } + + if(chpParserCtxt->input->base || ch>This->pParserCtxt->input->end) + This->column = This->realColumn + +This->pParserCtxt->input->cur-This->lastCur; } static void libxmlSetDocumentLocator( @@ -1250,7 +1273,38 @@ static void libxmlSetDocumentLocator( format_error_message_from_id(This, hr); } -void libxmlFatalError(void *ctx, const char *msg, ...) +static void libxmlComment(void *ctx, const xmlChar *value) +{ + saxlocator *This = ctx; + BSTR bValue; + HRESULT hr; + xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur; + + while(memcmp(beg-4, "