2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 #include "msxml_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
50 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
51 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
52 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
54 typedef struct _domdoc
56 const struct IXMLDOMDocument2Vtbl *lpVtbl;
57 const struct IPersistStreamVtbl *lpvtblIPersistStream;
58 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
59 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
60 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
63 VARIANT_BOOL validating;
64 VARIANT_BOOL resolving;
65 VARIANT_BOOL preserving;
69 IXMLDOMSchemaCollection *schema;
87 In native windows, the whole lifetime management of XMLDOMNodes is
88 managed automatically using reference counts. Wine emulates that by
89 maintaining a reference count to the document that is increased for
90 each IXMLDOMNode pointer passed out for this document. If all these
91 pointers are gone, the document is unreachable and gets freed, that
92 is, all nodes in the tree of the document get freed.
94 You are able to create nodes that are associated to a document (in
95 fact, in msxml's XMLDOM model, all nodes are associated to a document),
96 but not in the tree of that document, for example using the createFoo
97 functions from IXMLDOMDocument. These nodes do not get cleaned up
98 by libxml, so we have to do it ourselves.
100 To catch these nodes, a list of "orphan nodes" is introduced.
101 It contains pointers to all roots of node trees that are
102 associated with the document without being part of the document
103 tree. All nodes with parent==NULL (except for the document root nodes)
104 should be in the orphan node list of their document. All orphan nodes
105 get freed together with the document itself.
108 typedef struct _xmldoc_priv {
113 typedef struct _orphan_entry {
118 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
120 return doc->_private;
123 static xmldoc_priv * create_priv(void)
126 priv = HeapAlloc( GetProcessHeap(), 0, sizeof (*priv) );
131 list_init( &priv->orphans );
137 static xmlDocPtr doparse( char *ptr, int len )
139 #ifdef HAVE_XMLREADMEMORY
141 * use xmlReadMemory if possible so we can suppress
142 * writing errors to stderr
144 return xmlReadMemory( ptr, len, NULL, NULL,
145 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
147 return xmlParseMemory( ptr, len );
151 LONG xmldoc_add_ref(xmlDocPtr doc)
153 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
158 LONG xmldoc_release(xmlDocPtr doc)
160 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
161 LONG ref = InterlockedDecrement(&priv->refs);
165 orphan_entry *orphan, *orphan2;
166 TRACE("freeing docptr %p\n", doc);
168 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
170 xmlFreeNode( orphan->node );
171 HeapFree( GetProcessHeap(), 0, orphan );
173 HeapFree(GetProcessHeap(), 0, doc->_private);
181 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
183 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
186 entry = HeapAlloc( GetProcessHeap(), 0, sizeof (*entry) );
188 return E_OUTOFMEMORY;
191 list_add_head( &priv->orphans, &entry->entry );
195 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
197 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
198 orphan_entry *entry, *entry2;
200 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
202 if( entry->node == node )
204 list_remove( &entry->entry );
205 HeapFree( GetProcessHeap(), 0, entry );
213 static HRESULT attach_xmldoc( IXMLDOMNode *node, xmlDocPtr xml )
215 xmlnode *This = impl_from_IXMLDOMNode( node );
218 xmldoc_release(This->node->doc);
220 This->node = (xmlNodePtr) xml;
222 xmldoc_add_ref(This->node->doc);
227 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
229 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
232 static inline xmlDocPtr get_doc( domdoc *This )
234 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
237 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
239 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
242 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
244 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
247 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
249 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
252 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
254 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
257 /************************************************************************
258 * xmldoc implementation of IPersistStream.
260 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
261 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
263 domdoc *this = impl_from_IPersistStream(iface);
264 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
267 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
268 IPersistStream *iface)
270 domdoc *this = impl_from_IPersistStream(iface);
271 return IXMLDocument_AddRef((IXMLDocument *)this);
274 static ULONG WINAPI xmldoc_IPersistStream_Release(
275 IPersistStream *iface)
277 domdoc *this = impl_from_IPersistStream(iface);
278 return IXMLDocument_Release((IXMLDocument *)this);
281 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
282 IPersistStream *iface, CLSID *classid)
284 TRACE("(%p,%p): stub!\n", iface, classid);
289 *classid = CLSID_DOMDocument2;
294 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
295 IPersistStream *iface)
297 domdoc *This = impl_from_IPersistStream(iface);
299 FIXME("(%p->%p): stub!\n", iface, This);
304 static HRESULT WINAPI xmldoc_IPersistStream_Load(
305 IPersistStream *iface, LPSTREAM pStm)
307 domdoc *This = impl_from_IPersistStream(iface);
310 DWORD read, written, len;
313 xmlDocPtr xmldoc = NULL;
315 TRACE("(%p, %p)\n", iface, pStm);
320 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
326 IStream_Read(pStm, buf, sizeof(buf), &read);
327 hr = IStream_Write(This->stream, buf, read, &written);
328 } while(SUCCEEDED(hr) && written != 0 && read != 0);
332 ERR("Failed to copy stream\n");
336 hr = GetHGlobalFromStream(This->stream, &hglobal);
340 len = GlobalSize(hglobal);
341 ptr = GlobalLock(hglobal);
343 xmldoc = parse_xml(ptr, len);
344 GlobalUnlock(hglobal);
348 ERR("Failed to parse xml\n");
352 xmldoc->_private = create_priv();
354 return attach_xmldoc( This->node, xmldoc );
357 static HRESULT WINAPI xmldoc_IPersistStream_Save(
358 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
360 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
364 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
365 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
367 TRACE("(%p, %p): stub!\n", iface, pcbSize);
371 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
373 xmldoc_IPersistStream_QueryInterface,
374 xmldoc_IPersistStream_AddRef,
375 xmldoc_IPersistStream_Release,
376 xmldoc_IPersistStream_GetClassID,
377 xmldoc_IPersistStream_IsDirty,
378 xmldoc_IPersistStream_Load,
379 xmldoc_IPersistStream_Save,
380 xmldoc_IPersistStream_GetSizeMax,
383 /* ISupportErrorInfo interface */
384 static HRESULT WINAPI support_error_QueryInterface(
385 ISupportErrorInfo *iface,
386 REFIID riid, void** ppvObj )
388 domdoc *This = impl_from_ISupportErrorInfo(iface);
389 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
392 static ULONG WINAPI support_error_AddRef(
393 ISupportErrorInfo *iface )
395 domdoc *This = impl_from_ISupportErrorInfo(iface);
396 return IXMLDocument_AddRef((IXMLDocument *)This);
399 static ULONG WINAPI support_error_Release(
400 ISupportErrorInfo *iface )
402 domdoc *This = impl_from_ISupportErrorInfo(iface);
403 return IXMLDocument_Release((IXMLDocument *)This);
406 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
407 ISupportErrorInfo *iface,
410 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
414 static const struct ISupportErrorInfoVtbl support_error_vtbl =
416 support_error_QueryInterface,
417 support_error_AddRef,
418 support_error_Release,
419 support_error_InterfaceSupportsErrorInfo
422 /* IXMLDOMDocument2 interface */
423 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
425 domdoc *This = impl_from_IXMLDOMDocument2( iface );
427 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
431 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
432 IsEqualGUID( riid, &IID_IDispatch ) ||
433 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
434 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
438 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
440 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
442 else if (IsEqualGUID(&IID_IPersistStream, riid))
444 *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
446 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
448 *ppvObject = (IObjectWithSite*)&(This->lpvtblIObjectWithSite);
450 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
452 *ppvObject = &This->lpvtblISupportErrorInfo;
454 else if(dispex_query_interface(&This->dispex, riid, ppvObject))
456 return *ppvObject ? S_OK : E_NOINTERFACE;
458 else if(IsEqualGUID(&IID_IRunnableObject, riid))
460 TRACE("IID_IRunnableObject not supported returning NULL\n");
461 return E_NOINTERFACE;
465 FIXME("interface %s not implemented\n", debugstr_guid(riid));
466 return E_NOINTERFACE;
469 IXMLDOMDocument_AddRef( iface );
475 static ULONG WINAPI domdoc_AddRef(
476 IXMLDOMDocument2 *iface )
478 domdoc *This = impl_from_IXMLDOMDocument2( iface );
479 TRACE("%p\n", This );
480 return InterlockedIncrement( &This->ref );
484 static ULONG WINAPI domdoc_Release(
485 IXMLDOMDocument2 *iface )
487 domdoc *This = impl_from_IXMLDOMDocument2( iface );
490 TRACE("%p\n", This );
492 ref = InterlockedDecrement( &This->ref );
496 detach_bsc(This->bsc);
499 IUnknown_Release( This->site );
500 IUnknown_Release( This->node_unk );
501 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
502 if (This->stream) IStream_Release(This->stream);
503 HeapFree( GetProcessHeap(), 0, This );
509 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
511 domdoc *This = impl_from_IXMLDOMDocument2( iface );
513 TRACE("(%p)->(%p)\n", This, pctinfo);
520 static HRESULT WINAPI domdoc_GetTypeInfo(
521 IXMLDOMDocument2 *iface,
522 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
524 domdoc *This = impl_from_IXMLDOMDocument2( iface );
527 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
529 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
534 static HRESULT WINAPI domdoc_GetIDsOfNames(
535 IXMLDOMDocument2 *iface,
542 domdoc *This = impl_from_IXMLDOMDocument2( iface );
546 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
549 if(!rgszNames || cNames == 0 || !rgDispId)
552 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
555 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
556 ITypeInfo_Release(typeinfo);
563 static HRESULT WINAPI domdoc_Invoke(
564 IXMLDOMDocument2 *iface,
569 DISPPARAMS* pDispParams,
571 EXCEPINFO* pExcepInfo,
574 domdoc *This = impl_from_IXMLDOMDocument2( iface );
578 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
579 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
581 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
584 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
585 pVarResult, pExcepInfo, puArgErr);
586 ITypeInfo_Release(typeinfo);
593 static HRESULT WINAPI domdoc_get_nodeName(
594 IXMLDOMDocument2 *iface,
597 domdoc *This = impl_from_IXMLDOMDocument2( iface );
598 return IXMLDOMNode_get_nodeName( This->node, name );
602 static HRESULT WINAPI domdoc_get_nodeValue(
603 IXMLDOMDocument2 *iface,
606 domdoc *This = impl_from_IXMLDOMDocument2( iface );
607 return IXMLDOMNode_get_nodeValue( This->node, value );
611 static HRESULT WINAPI domdoc_put_nodeValue(
612 IXMLDOMDocument2 *iface,
615 domdoc *This = impl_from_IXMLDOMDocument2( iface );
616 return IXMLDOMNode_put_nodeValue( This->node, value );
620 static HRESULT WINAPI domdoc_get_nodeType(
621 IXMLDOMDocument2 *iface,
624 domdoc *This = impl_from_IXMLDOMDocument2( iface );
625 return IXMLDOMNode_get_nodeType( This->node, type );
629 static HRESULT WINAPI domdoc_get_parentNode(
630 IXMLDOMDocument2 *iface,
631 IXMLDOMNode** parent )
633 domdoc *This = impl_from_IXMLDOMDocument2( iface );
634 return IXMLDOMNode_get_parentNode( This->node, parent );
638 static HRESULT WINAPI domdoc_get_childNodes(
639 IXMLDOMDocument2 *iface,
640 IXMLDOMNodeList** childList )
642 domdoc *This = impl_from_IXMLDOMDocument2( iface );
643 return IXMLDOMNode_get_childNodes( This->node, childList );
647 static HRESULT WINAPI domdoc_get_firstChild(
648 IXMLDOMDocument2 *iface,
649 IXMLDOMNode** firstChild )
651 domdoc *This = impl_from_IXMLDOMDocument2( iface );
652 return IXMLDOMNode_get_firstChild( This->node, firstChild );
656 static HRESULT WINAPI domdoc_get_lastChild(
657 IXMLDOMDocument2 *iface,
658 IXMLDOMNode** lastChild )
660 domdoc *This = impl_from_IXMLDOMDocument2( iface );
661 return IXMLDOMNode_get_lastChild( This->node, lastChild );
665 static HRESULT WINAPI domdoc_get_previousSibling(
666 IXMLDOMDocument2 *iface,
667 IXMLDOMNode** previousSibling )
669 domdoc *This = impl_from_IXMLDOMDocument2( iface );
670 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
674 static HRESULT WINAPI domdoc_get_nextSibling(
675 IXMLDOMDocument2 *iface,
676 IXMLDOMNode** nextSibling )
678 domdoc *This = impl_from_IXMLDOMDocument2( iface );
679 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
683 static HRESULT WINAPI domdoc_get_attributes(
684 IXMLDOMDocument2 *iface,
685 IXMLDOMNamedNodeMap** attributeMap )
687 domdoc *This = impl_from_IXMLDOMDocument2( iface );
688 return IXMLDOMNode_get_attributes( This->node, attributeMap );
692 static HRESULT WINAPI domdoc_insertBefore(
693 IXMLDOMDocument2 *iface,
694 IXMLDOMNode* newChild,
696 IXMLDOMNode** outNewChild )
698 domdoc *This = impl_from_IXMLDOMDocument2( iface );
699 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
703 static HRESULT WINAPI domdoc_replaceChild(
704 IXMLDOMDocument2 *iface,
705 IXMLDOMNode* newChild,
706 IXMLDOMNode* oldChild,
707 IXMLDOMNode** outOldChild)
709 domdoc *This = impl_from_IXMLDOMDocument2( iface );
710 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
714 static HRESULT WINAPI domdoc_removeChild(
715 IXMLDOMDocument2 *iface,
716 IXMLDOMNode* childNode,
717 IXMLDOMNode** oldChild)
719 domdoc *This = impl_from_IXMLDOMDocument2( iface );
720 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
724 static HRESULT WINAPI domdoc_appendChild(
725 IXMLDOMDocument2 *iface,
726 IXMLDOMNode* newChild,
727 IXMLDOMNode** outNewChild)
729 domdoc *This = impl_from_IXMLDOMDocument2( iface );
730 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
734 static HRESULT WINAPI domdoc_hasChildNodes(
735 IXMLDOMDocument2 *iface,
736 VARIANT_BOOL* hasChild)
738 domdoc *This = impl_from_IXMLDOMDocument2( iface );
739 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
743 static HRESULT WINAPI domdoc_get_ownerDocument(
744 IXMLDOMDocument2 *iface,
745 IXMLDOMDocument** DOMDocument)
747 domdoc *This = impl_from_IXMLDOMDocument2( iface );
748 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
752 static HRESULT WINAPI domdoc_cloneNode(
753 IXMLDOMDocument2 *iface,
755 IXMLDOMNode** cloneRoot)
757 domdoc *This = impl_from_IXMLDOMDocument2( iface );
758 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
762 static HRESULT WINAPI domdoc_get_nodeTypeString(
763 IXMLDOMDocument2 *iface,
766 domdoc *This = impl_from_IXMLDOMDocument2( iface );
767 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
771 static HRESULT WINAPI domdoc_get_text(
772 IXMLDOMDocument2 *iface,
775 domdoc *This = impl_from_IXMLDOMDocument2( iface );
776 return IXMLDOMNode_get_text( This->node, text );
780 static HRESULT WINAPI domdoc_put_text(
781 IXMLDOMDocument2 *iface,
784 domdoc *This = impl_from_IXMLDOMDocument2( iface );
785 return IXMLDOMNode_put_text( This->node, text );
789 static HRESULT WINAPI domdoc_get_specified(
790 IXMLDOMDocument2 *iface,
791 VARIANT_BOOL* isSpecified )
793 domdoc *This = impl_from_IXMLDOMDocument2( iface );
794 return IXMLDOMNode_get_specified( This->node, isSpecified );
798 static HRESULT WINAPI domdoc_get_definition(
799 IXMLDOMDocument2 *iface,
800 IXMLDOMNode** definitionNode )
802 domdoc *This = impl_from_IXMLDOMDocument2( iface );
803 return IXMLDOMNode_get_definition( This->node, definitionNode );
807 static HRESULT WINAPI domdoc_get_nodeTypedValue(
808 IXMLDOMDocument2 *iface,
809 VARIANT* typedValue )
811 domdoc *This = impl_from_IXMLDOMDocument2( iface );
812 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
815 static HRESULT WINAPI domdoc_put_nodeTypedValue(
816 IXMLDOMDocument2 *iface,
819 domdoc *This = impl_from_IXMLDOMDocument2( iface );
820 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
824 static HRESULT WINAPI domdoc_get_dataType(
825 IXMLDOMDocument2 *iface,
826 VARIANT* dataTypeName )
828 domdoc *This = impl_from_IXMLDOMDocument2( iface );
829 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
833 static HRESULT WINAPI domdoc_put_dataType(
834 IXMLDOMDocument2 *iface,
837 domdoc *This = impl_from_IXMLDOMDocument2( iface );
838 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
842 static HRESULT WINAPI domdoc_get_xml(
843 IXMLDOMDocument2 *iface,
846 domdoc *This = impl_from_IXMLDOMDocument2( iface );
847 return IXMLDOMNode_get_xml( This->node, xmlString );
851 static HRESULT WINAPI domdoc_transformNode(
852 IXMLDOMDocument2 *iface,
853 IXMLDOMNode* styleSheet,
856 domdoc *This = impl_from_IXMLDOMDocument2( iface );
857 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
861 static HRESULT WINAPI domdoc_selectNodes(
862 IXMLDOMDocument2 *iface,
864 IXMLDOMNodeList** resultList )
866 domdoc *This = impl_from_IXMLDOMDocument2( iface );
867 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
871 static HRESULT WINAPI domdoc_selectSingleNode(
872 IXMLDOMDocument2 *iface,
874 IXMLDOMNode** resultNode )
876 domdoc *This = impl_from_IXMLDOMDocument2( iface );
877 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
881 static HRESULT WINAPI domdoc_get_parsed(
882 IXMLDOMDocument2 *iface,
883 VARIANT_BOOL* isParsed )
885 domdoc *This = impl_from_IXMLDOMDocument2( iface );
886 return IXMLDOMNode_get_parsed( This->node, isParsed );
890 static HRESULT WINAPI domdoc_get_namespaceURI(
891 IXMLDOMDocument2 *iface,
894 domdoc *This = impl_from_IXMLDOMDocument2( iface );
895 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
899 static HRESULT WINAPI domdoc_get_prefix(
900 IXMLDOMDocument2 *iface,
903 domdoc *This = impl_from_IXMLDOMDocument2( iface );
904 return IXMLDOMNode_get_prefix( This->node, prefixString );
908 static HRESULT WINAPI domdoc_get_baseName(
909 IXMLDOMDocument2 *iface,
912 domdoc *This = impl_from_IXMLDOMDocument2( iface );
913 return IXMLDOMNode_get_baseName( This->node, nameString );
917 static HRESULT WINAPI domdoc_transformNodeToObject(
918 IXMLDOMDocument2 *iface,
919 IXMLDOMNode* stylesheet,
920 VARIANT outputObject)
922 domdoc *This = impl_from_IXMLDOMDocument2( iface );
923 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
927 static HRESULT WINAPI domdoc_get_doctype(
928 IXMLDOMDocument2 *iface,
929 IXMLDOMDocumentType** documentType )
936 static HRESULT WINAPI domdoc_get_implementation(
937 IXMLDOMDocument2 *iface,
938 IXMLDOMImplementation** impl )
943 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
948 static HRESULT WINAPI domdoc_get_documentElement(
949 IXMLDOMDocument2 *iface,
950 IXMLDOMElement** DOMElement )
952 domdoc *This = impl_from_IXMLDOMDocument2( iface );
953 xmlDocPtr xmldoc = NULL;
954 xmlNodePtr root = NULL;
955 IXMLDOMNode *element_node;
958 TRACE("%p %p\n", This, This->node);
965 xmldoc = get_doc( This );
967 root = xmlDocGetRootElement( xmldoc );
971 element_node = create_node( root );
972 if(!element_node) return S_FALSE;
974 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
975 IXMLDOMNode_Release(element_node);
981 static HRESULT WINAPI domdoc_put_documentElement(
982 IXMLDOMDocument2 *iface,
983 IXMLDOMElement* DOMElement )
985 domdoc *This = impl_from_IXMLDOMDocument2( iface );
986 IXMLDOMNode *elementNode;
991 TRACE("(%p)->(%p)\n", This, DOMElement);
993 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
997 xmlNode = impl_from_IXMLDOMNode( elementNode );
999 if(!xmlNode->node->parent)
1000 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1001 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1003 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1004 IXMLDOMNode_Release( elementNode );
1007 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1013 static HRESULT WINAPI domdoc_createElement(
1014 IXMLDOMDocument2 *iface,
1016 IXMLDOMElement** element )
1019 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1024 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1026 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
1027 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1028 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1030 TRACE("created xmlptr %p\n", xmlnode);
1031 elem_unk = create_element(xmlnode, NULL);
1032 HeapFree(GetProcessHeap(), 0, xml_name);
1034 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1035 IUnknown_Release(elem_unk);
1036 TRACE("returning %p\n", *element);
1041 static HRESULT WINAPI domdoc_createDocumentFragment(
1042 IXMLDOMDocument2 *iface,
1043 IXMLDOMDocumentFragment** docFrag )
1045 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1048 TRACE("%p\n", iface);
1051 return E_INVALIDARG;
1055 xmlnode = xmlNewDocFragment(get_doc( This ) );
1060 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1061 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1067 static HRESULT WINAPI domdoc_createTextNode(
1068 IXMLDOMDocument2 *iface,
1070 IXMLDOMText** text )
1072 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1074 xmlChar *xml_content;
1076 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1079 return E_INVALIDARG;
1083 xml_content = xmlChar_from_wchar((WCHAR*)data);
1084 xmlnode = xmlNewText(xml_content);
1085 HeapFree(GetProcessHeap(), 0, xml_content);
1090 xmlnode->doc = get_doc( This );
1091 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1093 *text = (IXMLDOMText*)create_text(xmlnode);
1099 static HRESULT WINAPI domdoc_createComment(
1100 IXMLDOMDocument2 *iface,
1102 IXMLDOMComment** comment )
1104 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1106 xmlChar *xml_content;
1108 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1111 return E_INVALIDARG;
1115 xml_content = xmlChar_from_wchar((WCHAR*)data);
1116 xmlnode = xmlNewComment(xml_content);
1117 HeapFree(GetProcessHeap(), 0, xml_content);
1122 xmlnode->doc = get_doc( This );
1123 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1125 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1131 static HRESULT WINAPI domdoc_createCDATASection(
1132 IXMLDOMDocument2 *iface,
1134 IXMLDOMCDATASection** cdata )
1136 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1138 xmlChar *xml_content;
1140 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1143 return E_INVALIDARG;
1147 xml_content = xmlChar_from_wchar((WCHAR*)data);
1148 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1149 HeapFree(GetProcessHeap(), 0, xml_content);
1154 xmlnode->doc = get_doc( This );
1155 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1157 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1163 static HRESULT WINAPI domdoc_createProcessingInstruction(
1164 IXMLDOMDocument2 *iface,
1167 IXMLDOMProcessingInstruction** pi )
1169 #ifdef HAVE_XMLNEWDOCPI
1171 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1172 xmlChar *xml_target, *xml_content;
1174 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1177 return E_INVALIDARG;
1179 if(!target || lstrlenW(target) == 0)
1182 xml_target = xmlChar_from_wchar((WCHAR*)target);
1183 xml_content = xmlChar_from_wchar((WCHAR*)data);
1185 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1186 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1187 TRACE("created xmlptr %p\n", xmlnode);
1188 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1190 HeapFree(GetProcessHeap(), 0, xml_content);
1191 HeapFree(GetProcessHeap(), 0, xml_target);
1195 FIXME("Libxml 2.6.15 or greater required.\n");
1201 static HRESULT WINAPI domdoc_createAttribute(
1202 IXMLDOMDocument2 *iface,
1204 IXMLDOMAttribute** attribute )
1206 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1210 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1213 return E_INVALIDARG;
1217 xml_name = xmlChar_from_wchar((WCHAR*)name);
1218 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1219 HeapFree(GetProcessHeap(), 0, xml_name);
1224 xmlnode->doc = get_doc( This );
1225 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1227 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1233 static HRESULT WINAPI domdoc_createEntityReference(
1234 IXMLDOMDocument2 *iface,
1236 IXMLDOMEntityReference** entityRef )
1238 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1242 TRACE("%p\n", iface);
1245 return E_INVALIDARG;
1249 xml_name = xmlChar_from_wchar((WCHAR*)name);
1250 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1251 HeapFree(GetProcessHeap(), 0, xml_name);
1256 xmlnode->doc = get_doc( This );
1257 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1259 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1265 static HRESULT WINAPI domdoc_getElementsByTagName(
1266 IXMLDOMDocument2 *iface,
1268 IXMLDOMNodeList** resultList )
1270 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1273 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1275 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1276 szPattern[0] = szPattern[1] = '/';
1277 lstrcpyW(szPattern + 2, tagName);
1279 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1280 HeapFree(GetProcessHeap(), 0, szPattern);
1285 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1291 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1293 return E_INVALIDARG;
1300 static HRESULT WINAPI domdoc_createNode(
1301 IXMLDOMDocument2 *iface,
1305 IXMLDOMNode** node )
1307 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1308 DOMNodeType node_type;
1309 xmlNodePtr xmlnode = NULL;
1313 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1315 if(namespaceURI && namespaceURI[0])
1316 FIXME("nodes with namespaces currently not supported.\n");
1318 hr = get_node_type(Type, &node_type);
1322 TRACE("node_type %d\n", node_type);
1324 xml_name = xmlChar_from_wchar((WCHAR*)name);
1329 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1330 *node = create_node(xmlnode);
1331 TRACE("created %p\n", xmlnode);
1333 case NODE_ATTRIBUTE:
1334 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1337 xmlnode->doc = get_doc( This );
1339 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1342 TRACE("created %p\n", xmlnode);
1346 FIXME("unhandled node type %d\n", node_type);
1350 HeapFree(GetProcessHeap(), 0, xml_name);
1352 if(xmlnode && *node)
1354 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1361 static HRESULT WINAPI domdoc_nodeFromID(
1362 IXMLDOMDocument2 *iface,
1364 IXMLDOMNode** node )
1370 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1375 xmldoc = doparse( ptr, len );
1377 xmldoc->_private = create_priv();
1378 return attach_xmldoc(This->node, xmldoc);
1384 static HRESULT doread( domdoc *This, LPWSTR filename )
1389 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1394 detach_bsc(This->bsc);
1400 static HRESULT WINAPI domdoc_load(
1401 IXMLDOMDocument2 *iface,
1403 VARIANT_BOOL* isSuccessful )
1405 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1406 LPWSTR filename = NULL;
1407 HRESULT hr = S_FALSE;
1408 IXMLDOMDocument2 *pNewDoc = NULL;
1409 IStream *pStream = NULL;
1412 TRACE("type %d\n", V_VT(&xmlSource) );
1414 *isSuccessful = VARIANT_FALSE;
1416 assert( This->node );
1418 switch( V_VT(&xmlSource) )
1421 filename = V_BSTR(&xmlSource);
1424 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1429 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1430 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1431 hr = attach_xmldoc(This->node, xmldoc);
1434 *isSuccessful = VARIANT_TRUE;
1439 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1442 IPersistStream *pDocStream;
1443 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1446 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1447 IStream_Release(pStream);
1450 *isSuccessful = VARIANT_TRUE;
1452 TRACE("Using ID_IStream to load Document\n");
1457 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1462 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1467 /* ISequentialStream */
1468 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1472 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1475 TRACE("filename (%s)\n", debugstr_w(filename));
1479 hr = doread( This, filename );
1482 This->error = E_FAIL;
1485 hr = This->error = S_OK;
1486 *isSuccessful = VARIANT_TRUE;
1490 if(!filename || FAILED(hr)) {
1491 xmldoc = xmlNewDoc(NULL);
1492 xmldoc->_private = create_priv();
1493 hr = attach_xmldoc(This->node, xmldoc);
1498 TRACE("ret (%d)\n", hr);
1504 static HRESULT WINAPI domdoc_get_readyState(
1505 IXMLDOMDocument2 *iface,
1513 static HRESULT WINAPI domdoc_get_parseError(
1514 IXMLDOMDocument2 *iface,
1515 IXMLDOMParseError** errorObj )
1517 BSTR error_string = NULL;
1518 static const WCHAR err[] = {'e','r','r','o','r',0};
1519 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1521 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1524 error_string = SysAllocString(err);
1526 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1527 if(!*errorObj) return E_OUTOFMEMORY;
1532 static HRESULT WINAPI domdoc_get_url(
1533 IXMLDOMDocument2 *iface,
1541 static HRESULT WINAPI domdoc_get_async(
1542 IXMLDOMDocument2 *iface,
1543 VARIANT_BOOL* isAsync )
1545 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1547 TRACE("%p <- %d\n", isAsync, This->async);
1548 *isAsync = This->async;
1553 static HRESULT WINAPI domdoc_put_async(
1554 IXMLDOMDocument2 *iface,
1555 VARIANT_BOOL isAsync )
1557 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1559 TRACE("%d\n", isAsync);
1560 This->async = isAsync;
1565 static HRESULT WINAPI domdoc_abort(
1566 IXMLDOMDocument2 *iface )
1573 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1575 UINT len, blen = SysStringLen( bstr );
1578 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1579 str = HeapAlloc( GetProcessHeap(), 0, len );
1582 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1588 static HRESULT WINAPI domdoc_loadXML(
1589 IXMLDOMDocument2 *iface,
1591 VARIANT_BOOL* isSuccessful )
1593 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1594 xmlDocPtr xmldoc = NULL;
1597 HRESULT hr = S_FALSE, hr2;
1599 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1601 assert ( This->node );
1605 *isSuccessful = VARIANT_FALSE;
1607 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1609 xmldoc = doparse( str, len );
1610 HeapFree( GetProcessHeap(), 0, str );
1612 This->error = E_FAIL;
1615 hr = This->error = S_OK;
1616 *isSuccessful = VARIANT_TRUE;
1621 xmldoc = xmlNewDoc(NULL);
1623 xmldoc->_private = create_priv();
1624 hr2 = attach_xmldoc( This->node, xmldoc );
1632 static HRESULT WINAPI domdoc_save(
1633 IXMLDOMDocument2 *iface,
1634 VARIANT destination )
1636 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1643 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1644 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1646 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1648 FIXME("Unhandled vt %d\n", V_VT(&destination));
1652 if(V_VT(&destination) == VT_UNKNOWN)
1654 IUnknown *pUnk = V_UNKNOWN(&destination);
1655 IXMLDOMDocument *pDocument;
1657 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1661 VARIANT_BOOL bSuccessful;
1663 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1666 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1668 SysFreeString(bXML);
1671 IXMLDOMDocument_Release(pDocument);
1674 TRACE("ret %d\n", ret);
1679 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1680 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1681 if( handle == INVALID_HANDLE_VALUE )
1683 WARN("failed to create file\n");
1687 xmlDocDumpMemory(get_doc(This), &mem, &size);
1690 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1691 * MSXML adds XML declaration only for processing instruction nodes.
1692 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1695 if(size > 2 && p[0] == '<' && p[1] == '?') {
1696 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1699 while(p < mem+size && isspace(*p))
1704 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1706 WARN("write error\n");
1711 CloseHandle(handle);
1715 static HRESULT WINAPI domdoc_get_validateOnParse(
1716 IXMLDOMDocument2 *iface,
1717 VARIANT_BOOL* isValidating )
1719 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1721 TRACE("%p <- %d\n", isValidating, This->validating);
1722 *isValidating = This->validating;
1727 static HRESULT WINAPI domdoc_put_validateOnParse(
1728 IXMLDOMDocument2 *iface,
1729 VARIANT_BOOL isValidating )
1731 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1733 TRACE("%d\n", isValidating);
1734 This->validating = isValidating;
1739 static HRESULT WINAPI domdoc_get_resolveExternals(
1740 IXMLDOMDocument2 *iface,
1741 VARIANT_BOOL* isResolving )
1743 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1745 TRACE("%p <- %d\n", isResolving, This->resolving);
1746 *isResolving = This->resolving;
1751 static HRESULT WINAPI domdoc_put_resolveExternals(
1752 IXMLDOMDocument2 *iface,
1753 VARIANT_BOOL isResolving )
1755 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1757 TRACE("%d\n", isResolving);
1758 This->resolving = isResolving;
1763 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1764 IXMLDOMDocument2 *iface,
1765 VARIANT_BOOL* isPreserving )
1767 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1769 TRACE("%p <- %d\n", isPreserving, This->preserving);
1770 *isPreserving = This->preserving;
1775 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1776 IXMLDOMDocument2 *iface,
1777 VARIANT_BOOL isPreserving )
1779 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1781 TRACE("%d\n", isPreserving);
1782 This->preserving = isPreserving;
1787 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1788 IXMLDOMDocument2 *iface,
1789 VARIANT readyStateChangeSink )
1796 static HRESULT WINAPI domdoc_put_onDataAvailable(
1797 IXMLDOMDocument2 *iface,
1798 VARIANT onDataAvailableSink )
1804 static HRESULT WINAPI domdoc_put_onTransformNode(
1805 IXMLDOMDocument2 *iface,
1806 VARIANT onTransformNodeSink )
1812 static HRESULT WINAPI domdoc_get_namespaces(
1813 IXMLDOMDocument2* iface,
1814 IXMLDOMSchemaCollection** schemaCollection )
1820 static HRESULT WINAPI domdoc_get_schemas(
1821 IXMLDOMDocument2* iface,
1824 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1825 HRESULT hr = S_FALSE;
1826 IXMLDOMSchemaCollection *cur_schema = This->schema;
1828 TRACE("(%p)->(%p)\n", This, var1);
1830 VariantInit(var1); /* Test shows we don't call VariantClear here */
1831 V_VT(var1) = VT_NULL;
1835 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1837 V_VT(var1) = VT_DISPATCH;
1842 static HRESULT WINAPI domdoc_putref_schemas(
1843 IXMLDOMDocument2* iface,
1846 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1847 HRESULT hr = E_FAIL;
1848 IXMLDOMSchemaCollection *new_schema = NULL;
1850 FIXME("(%p): semi-stub\n", This);
1854 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1858 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1867 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1872 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1873 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1879 static HRESULT WINAPI domdoc_validate(
1880 IXMLDOMDocument2* iface,
1881 IXMLDOMParseError** err)
1887 static HRESULT WINAPI domdoc_setProperty(
1888 IXMLDOMDocument2* iface,
1892 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1894 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1900 V_VT(&varStr) = VT_EMPTY;
1901 if (V_VT(&var) != VT_BSTR)
1903 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1905 bstr = V_BSTR(&varStr);
1908 bstr = V_BSTR(&var);
1911 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1912 This->bUseXPath = TRUE;
1913 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1914 This->bUseXPath = FALSE;
1918 VariantClear(&varStr);
1922 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1926 static HRESULT WINAPI domdoc_getProperty(
1927 IXMLDOMDocument2* iface,
1931 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1934 return E_INVALIDARG;
1935 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1937 V_VT(var) = VT_BSTR;
1938 if (This->bUseXPath)
1939 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1941 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1945 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1949 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1951 domdoc_QueryInterface,
1954 domdoc_GetTypeInfoCount,
1956 domdoc_GetIDsOfNames,
1958 domdoc_get_nodeName,
1959 domdoc_get_nodeValue,
1960 domdoc_put_nodeValue,
1961 domdoc_get_nodeType,
1962 domdoc_get_parentNode,
1963 domdoc_get_childNodes,
1964 domdoc_get_firstChild,
1965 domdoc_get_lastChild,
1966 domdoc_get_previousSibling,
1967 domdoc_get_nextSibling,
1968 domdoc_get_attributes,
1969 domdoc_insertBefore,
1970 domdoc_replaceChild,
1973 domdoc_hasChildNodes,
1974 domdoc_get_ownerDocument,
1976 domdoc_get_nodeTypeString,
1979 domdoc_get_specified,
1980 domdoc_get_definition,
1981 domdoc_get_nodeTypedValue,
1982 domdoc_put_nodeTypedValue,
1983 domdoc_get_dataType,
1984 domdoc_put_dataType,
1986 domdoc_transformNode,
1988 domdoc_selectSingleNode,
1990 domdoc_get_namespaceURI,
1992 domdoc_get_baseName,
1993 domdoc_transformNodeToObject,
1995 domdoc_get_implementation,
1996 domdoc_get_documentElement,
1997 domdoc_put_documentElement,
1998 domdoc_createElement,
1999 domdoc_createDocumentFragment,
2000 domdoc_createTextNode,
2001 domdoc_createComment,
2002 domdoc_createCDATASection,
2003 domdoc_createProcessingInstruction,
2004 domdoc_createAttribute,
2005 domdoc_createEntityReference,
2006 domdoc_getElementsByTagName,
2010 domdoc_get_readyState,
2011 domdoc_get_parseError,
2018 domdoc_get_validateOnParse,
2019 domdoc_put_validateOnParse,
2020 domdoc_get_resolveExternals,
2021 domdoc_put_resolveExternals,
2022 domdoc_get_preserveWhiteSpace,
2023 domdoc_put_preserveWhiteSpace,
2024 domdoc_put_onReadyStateChange,
2025 domdoc_put_onDataAvailable,
2026 domdoc_put_onTransformNode,
2027 domdoc_get_namespaces,
2029 domdoc_putref_schemas,
2035 /* xmldoc implementation of IObjectWithSite */
2036 static HRESULT WINAPI
2037 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2039 domdoc *This = impl_from_IObjectWithSite(iface);
2040 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2044 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2046 domdoc *This = impl_from_IObjectWithSite(iface);
2047 return IXMLDocument_AddRef((IXMLDocument *)This);
2051 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2053 domdoc *This = impl_from_IObjectWithSite(iface);
2054 return IXMLDocument_Release((IXMLDocument *)This);
2057 static HRESULT WINAPI
2058 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2060 domdoc *This = impl_from_IObjectWithSite(iface);
2062 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2067 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2070 static HRESULT WINAPI
2071 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2073 domdoc *This = impl_from_IObjectWithSite(iface);
2075 TRACE("%p %p\n", iface, punk);
2081 IUnknown_Release( This->site );
2089 IUnknown_AddRef( punk );
2092 IUnknown_Release( This->site );
2099 static const IObjectWithSiteVtbl domdocObjectSite =
2101 xmldoc_ObjectWithSite_QueryInterface,
2102 xmldoc_ObjectWithSite_AddRef,
2103 xmldoc_ObjectWithSite_Release,
2108 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2110 domdoc *This = impl_from_IObjectSafety(iface);
2111 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2114 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2116 domdoc *This = impl_from_IObjectSafety(iface);
2117 return IXMLDocument_AddRef((IXMLDocument *)This);
2120 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2122 domdoc *This = impl_from_IObjectSafety(iface);
2123 return IXMLDocument_Release((IXMLDocument *)This);
2126 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2128 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2129 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2131 domdoc *This = impl_from_IObjectSafety(iface);
2133 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2135 if(!pdwSupportedOptions || !pdwEnabledOptions)
2138 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2139 *pdwEnabledOptions = This->safeopt;
2144 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2145 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2147 domdoc *This = impl_from_IObjectSafety(iface);
2149 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2151 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2154 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2158 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2159 xmldoc_Safety_QueryInterface,
2160 xmldoc_Safety_AddRef,
2161 xmldoc_Safety_Release,
2162 xmldoc_Safety_GetInterfaceSafetyOptions,
2163 xmldoc_Safety_SetInterfaceSafetyOptions
2167 static const tid_t domdoc_iface_tids[] = {
2169 IXMLDOMDocument_tid,
2170 IXMLDOMDocument2_tid,
2173 static dispex_static_data_t domdoc_dispex = {
2175 IXMLDOMDocument2_tid,
2180 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2185 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2187 return E_OUTOFMEMORY;
2189 doc->lpVtbl = &domdoc_vtbl;
2190 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2191 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2192 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2193 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2196 doc->validating = 0;
2198 doc->preserving = 0;
2199 doc->bUseXPath = FALSE;
2207 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2210 HeapFree(GetProcessHeap(), 0, doc);
2214 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2217 IUnknown_Release(doc->node_unk);
2218 HeapFree( GetProcessHeap(), 0, doc );
2222 init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2224 /* The ref on doc->node is actually looped back into this object, so release it */
2225 IXMLDOMNode_Release(doc->node);
2227 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2229 TRACE("returning iface %p\n", *document);
2233 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2238 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2240 xmldoc = xmlNewDoc(NULL);
2242 return E_OUTOFMEMORY;
2244 xmldoc->_private = create_priv();
2246 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2253 IUnknown* create_domdoc( xmlNodePtr document )
2258 TRACE("(%p)\n", document);
2260 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2264 return (IUnknown*)pObj;
2269 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2271 MESSAGE("This program tried to use a DOMDocument object, but\n"
2272 "libxml2 support was not present at compile time.\n");