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;
62 VARIANT_BOOL validating;
63 VARIANT_BOOL resolving;
64 VARIANT_BOOL preserving;
68 IXMLDOMSchemaCollection *schema;
86 In native windows, the whole lifetime management of XMLDOMNodes is
87 managed automatically using reference counts. Wine emulates that by
88 maintaining a reference count to the document that is increased for
89 each IXMLDOMNode pointer passed out for this document. If all these
90 pointers are gone, the document is unreachable and gets freed, that
91 is, all nodes in the tree of the document get freed.
93 You are able to create nodes that are associated to a document (in
94 fact, in msxml's XMLDOM model, all nodes are associated to a document),
95 but not in the tree of that document, for example using the createFoo
96 functions from IXMLDOMDocument. These nodes do not get cleaned up
97 by libxml, so we have to do it ourselves.
99 To catch these nodes, a list of "orphan nodes" is introduced.
100 It contains pointers to all roots of node trees that are
101 associated with the document without being part of the document
102 tree. All nodes with parent==NULL (except for the document root nodes)
103 should be in the orphan node list of their document. All orphan nodes
104 get freed together with the document itself.
107 typedef struct _xmldoc_priv {
112 typedef struct _orphan_entry {
117 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
119 return doc->_private;
122 static xmldoc_priv * create_priv(void)
125 priv = HeapAlloc( GetProcessHeap(), 0, sizeof (*priv) );
130 list_init( &priv->orphans );
136 static xmlDocPtr doparse( char *ptr, int len )
138 #ifdef HAVE_XMLREADMEMORY
140 * use xmlReadMemory if possible so we can suppress
141 * writing errors to stderr
143 return xmlReadMemory( ptr, len, NULL, NULL,
144 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
146 return xmlParseMemory( ptr, len );
150 LONG xmldoc_add_ref(xmlDocPtr doc)
152 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
157 LONG xmldoc_release(xmlDocPtr doc)
159 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
160 LONG ref = InterlockedDecrement(&priv->refs);
164 orphan_entry *orphan, *orphan2;
165 TRACE("freeing docptr %p\n", doc);
167 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
169 xmlFreeNode( orphan->node );
170 HeapFree( GetProcessHeap(), 0, orphan );
172 HeapFree(GetProcessHeap(), 0, doc->_private);
180 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
182 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
185 entry = HeapAlloc( GetProcessHeap(), 0, sizeof (*entry) );
187 return E_OUTOFMEMORY;
190 list_add_head( &priv->orphans, &entry->entry );
194 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
196 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
197 orphan_entry *entry, *entry2;
199 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
201 if( entry->node == node )
203 list_remove( &entry->entry );
204 HeapFree( GetProcessHeap(), 0, entry );
212 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
214 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
217 static inline xmlDocPtr get_doc( domdoc *This )
219 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
222 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
224 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
227 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
229 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
232 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
234 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
238 /************************************************************************
239 * xmldoc implementation of IPersistStream.
241 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
242 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
244 domdoc *this = impl_from_IPersistStream(iface);
245 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
248 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
249 IPersistStream *iface)
251 domdoc *this = impl_from_IPersistStream(iface);
252 return IXMLDocument_AddRef((IXMLDocument *)this);
255 static ULONG WINAPI xmldoc_IPersistStream_Release(
256 IPersistStream *iface)
258 domdoc *this = impl_from_IPersistStream(iface);
259 return IXMLDocument_Release((IXMLDocument *)this);
262 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
263 IPersistStream *iface, CLSID *classid)
265 TRACE("(%p,%p): stub!\n", iface, classid);
270 *classid = CLSID_DOMDocument2;
275 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
276 IPersistStream *iface)
278 domdoc *This = impl_from_IPersistStream(iface);
280 FIXME("(%p->%p): stub!\n", iface, This);
285 static HRESULT WINAPI xmldoc_IPersistStream_Load(
286 IPersistStream *iface, LPSTREAM pStm)
288 domdoc *This = impl_from_IPersistStream(iface);
291 DWORD read, written, len;
294 xmlDocPtr xmldoc = NULL;
296 TRACE("(%p, %p)\n", iface, pStm);
301 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
307 IStream_Read(pStm, buf, sizeof(buf), &read);
308 hr = IStream_Write(This->stream, buf, read, &written);
309 } while(SUCCEEDED(hr) && written != 0 && read != 0);
313 ERR("Failed to copy stream\n");
317 hr = GetHGlobalFromStream(This->stream, &hglobal);
321 len = GlobalSize(hglobal);
322 ptr = GlobalLock(hglobal);
324 xmldoc = parse_xml(ptr, len);
325 GlobalUnlock(hglobal);
329 ERR("Failed to parse xml\n");
333 xmldoc->_private = create_priv();
334 attach_xmlnode( This->node, (xmlNodePtr)xmldoc );
339 static HRESULT WINAPI xmldoc_IPersistStream_Save(
340 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
342 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
346 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
347 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
349 TRACE("(%p, %p): stub!\n", iface, pcbSize);
353 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
355 xmldoc_IPersistStream_QueryInterface,
356 xmldoc_IPersistStream_AddRef,
357 xmldoc_IPersistStream_Release,
358 xmldoc_IPersistStream_GetClassID,
359 xmldoc_IPersistStream_IsDirty,
360 xmldoc_IPersistStream_Load,
361 xmldoc_IPersistStream_Save,
362 xmldoc_IPersistStream_GetSizeMax,
365 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
367 domdoc *This = impl_from_IXMLDOMDocument2( iface );
369 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
373 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
374 IsEqualGUID( riid, &IID_IDispatch ) ||
375 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
376 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
380 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
382 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
384 else if (IsEqualGUID(&IID_IPersistStream, riid))
386 *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
388 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
390 *ppvObject = (IObjectWithSite*)&(This->lpvtblIObjectWithSite);
392 else if(dispex_query_interface(&This->dispex, riid, ppvObject))
394 return *ppvObject ? S_OK : E_NOINTERFACE;
396 else if(IsEqualGUID(&IID_IRunnableObject, riid))
398 TRACE("IID_IRunnableObject not supported returning NULL\n");
399 return E_NOINTERFACE;
403 FIXME("interface %s not implemented\n", debugstr_guid(riid));
404 return E_NOINTERFACE;
407 IXMLDOMDocument_AddRef( iface );
413 static ULONG WINAPI domdoc_AddRef(
414 IXMLDOMDocument2 *iface )
416 domdoc *This = impl_from_IXMLDOMDocument2( iface );
417 TRACE("%p\n", This );
418 return InterlockedIncrement( &This->ref );
422 static ULONG WINAPI domdoc_Release(
423 IXMLDOMDocument2 *iface )
425 domdoc *This = impl_from_IXMLDOMDocument2( iface );
428 TRACE("%p\n", This );
430 ref = InterlockedDecrement( &This->ref );
434 detach_bsc(This->bsc);
437 IUnknown_Release( This->site );
438 IUnknown_Release( This->node_unk );
439 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
440 if (This->stream) IStream_Release(This->stream);
441 HeapFree( GetProcessHeap(), 0, This );
447 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
449 domdoc *This = impl_from_IXMLDOMDocument2( iface );
451 TRACE("(%p)->(%p)\n", This, pctinfo);
458 static HRESULT WINAPI domdoc_GetTypeInfo(
459 IXMLDOMDocument2 *iface,
460 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
462 domdoc *This = impl_from_IXMLDOMDocument2( iface );
465 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
467 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
472 static HRESULT WINAPI domdoc_GetIDsOfNames(
473 IXMLDOMDocument2 *iface,
480 domdoc *This = impl_from_IXMLDOMDocument2( iface );
484 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
487 if(!rgszNames || cNames == 0 || !rgDispId)
490 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
493 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
494 ITypeInfo_Release(typeinfo);
501 static HRESULT WINAPI domdoc_Invoke(
502 IXMLDOMDocument2 *iface,
507 DISPPARAMS* pDispParams,
509 EXCEPINFO* pExcepInfo,
512 domdoc *This = impl_from_IXMLDOMDocument2( iface );
516 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
517 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
519 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
522 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
523 pVarResult, pExcepInfo, puArgErr);
524 ITypeInfo_Release(typeinfo);
531 static HRESULT WINAPI domdoc_get_nodeName(
532 IXMLDOMDocument2 *iface,
535 domdoc *This = impl_from_IXMLDOMDocument2( iface );
536 return IXMLDOMNode_get_nodeName( This->node, name );
540 static HRESULT WINAPI domdoc_get_nodeValue(
541 IXMLDOMDocument2 *iface,
544 domdoc *This = impl_from_IXMLDOMDocument2( iface );
545 return IXMLDOMNode_get_nodeValue( This->node, value );
549 static HRESULT WINAPI domdoc_put_nodeValue(
550 IXMLDOMDocument2 *iface,
553 domdoc *This = impl_from_IXMLDOMDocument2( iface );
554 return IXMLDOMNode_put_nodeValue( This->node, value );
558 static HRESULT WINAPI domdoc_get_nodeType(
559 IXMLDOMDocument2 *iface,
562 domdoc *This = impl_from_IXMLDOMDocument2( iface );
563 return IXMLDOMNode_get_nodeType( This->node, type );
567 static HRESULT WINAPI domdoc_get_parentNode(
568 IXMLDOMDocument2 *iface,
569 IXMLDOMNode** parent )
571 domdoc *This = impl_from_IXMLDOMDocument2( iface );
572 return IXMLDOMNode_get_parentNode( This->node, parent );
576 static HRESULT WINAPI domdoc_get_childNodes(
577 IXMLDOMDocument2 *iface,
578 IXMLDOMNodeList** childList )
580 domdoc *This = impl_from_IXMLDOMDocument2( iface );
581 return IXMLDOMNode_get_childNodes( This->node, childList );
585 static HRESULT WINAPI domdoc_get_firstChild(
586 IXMLDOMDocument2 *iface,
587 IXMLDOMNode** firstChild )
589 domdoc *This = impl_from_IXMLDOMDocument2( iface );
590 return IXMLDOMNode_get_firstChild( This->node, firstChild );
594 static HRESULT WINAPI domdoc_get_lastChild(
595 IXMLDOMDocument2 *iface,
596 IXMLDOMNode** lastChild )
598 domdoc *This = impl_from_IXMLDOMDocument2( iface );
599 return IXMLDOMNode_get_lastChild( This->node, lastChild );
603 static HRESULT WINAPI domdoc_get_previousSibling(
604 IXMLDOMDocument2 *iface,
605 IXMLDOMNode** previousSibling )
607 domdoc *This = impl_from_IXMLDOMDocument2( iface );
608 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
612 static HRESULT WINAPI domdoc_get_nextSibling(
613 IXMLDOMDocument2 *iface,
614 IXMLDOMNode** nextSibling )
616 domdoc *This = impl_from_IXMLDOMDocument2( iface );
617 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
621 static HRESULT WINAPI domdoc_get_attributes(
622 IXMLDOMDocument2 *iface,
623 IXMLDOMNamedNodeMap** attributeMap )
625 domdoc *This = impl_from_IXMLDOMDocument2( iface );
626 return IXMLDOMNode_get_attributes( This->node, attributeMap );
630 static HRESULT WINAPI domdoc_insertBefore(
631 IXMLDOMDocument2 *iface,
632 IXMLDOMNode* newChild,
634 IXMLDOMNode** outNewChild )
636 domdoc *This = impl_from_IXMLDOMDocument2( iface );
637 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
641 static HRESULT WINAPI domdoc_replaceChild(
642 IXMLDOMDocument2 *iface,
643 IXMLDOMNode* newChild,
644 IXMLDOMNode* oldChild,
645 IXMLDOMNode** outOldChild)
647 domdoc *This = impl_from_IXMLDOMDocument2( iface );
648 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
652 static HRESULT WINAPI domdoc_removeChild(
653 IXMLDOMDocument2 *iface,
654 IXMLDOMNode* childNode,
655 IXMLDOMNode** oldChild)
657 domdoc *This = impl_from_IXMLDOMDocument2( iface );
658 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
662 static HRESULT WINAPI domdoc_appendChild(
663 IXMLDOMDocument2 *iface,
664 IXMLDOMNode* newChild,
665 IXMLDOMNode** outNewChild)
667 domdoc *This = impl_from_IXMLDOMDocument2( iface );
668 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
672 static HRESULT WINAPI domdoc_hasChildNodes(
673 IXMLDOMDocument2 *iface,
674 VARIANT_BOOL* hasChild)
676 domdoc *This = impl_from_IXMLDOMDocument2( iface );
677 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
681 static HRESULT WINAPI domdoc_get_ownerDocument(
682 IXMLDOMDocument2 *iface,
683 IXMLDOMDocument** DOMDocument)
685 domdoc *This = impl_from_IXMLDOMDocument2( iface );
686 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
690 static HRESULT WINAPI domdoc_cloneNode(
691 IXMLDOMDocument2 *iface,
693 IXMLDOMNode** cloneRoot)
695 domdoc *This = impl_from_IXMLDOMDocument2( iface );
696 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
700 static HRESULT WINAPI domdoc_get_nodeTypeString(
701 IXMLDOMDocument2 *iface,
704 domdoc *This = impl_from_IXMLDOMDocument2( iface );
705 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
709 static HRESULT WINAPI domdoc_get_text(
710 IXMLDOMDocument2 *iface,
713 domdoc *This = impl_from_IXMLDOMDocument2( iface );
714 return IXMLDOMNode_get_text( This->node, text );
718 static HRESULT WINAPI domdoc_put_text(
719 IXMLDOMDocument2 *iface,
722 domdoc *This = impl_from_IXMLDOMDocument2( iface );
723 return IXMLDOMNode_put_text( This->node, text );
727 static HRESULT WINAPI domdoc_get_specified(
728 IXMLDOMDocument2 *iface,
729 VARIANT_BOOL* isSpecified )
731 domdoc *This = impl_from_IXMLDOMDocument2( iface );
732 return IXMLDOMNode_get_specified( This->node, isSpecified );
736 static HRESULT WINAPI domdoc_get_definition(
737 IXMLDOMDocument2 *iface,
738 IXMLDOMNode** definitionNode )
740 domdoc *This = impl_from_IXMLDOMDocument2( iface );
741 return IXMLDOMNode_get_definition( This->node, definitionNode );
745 static HRESULT WINAPI domdoc_get_nodeTypedValue(
746 IXMLDOMDocument2 *iface,
747 VARIANT* typedValue )
749 domdoc *This = impl_from_IXMLDOMDocument2( iface );
750 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
753 static HRESULT WINAPI domdoc_put_nodeTypedValue(
754 IXMLDOMDocument2 *iface,
757 domdoc *This = impl_from_IXMLDOMDocument2( iface );
758 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
762 static HRESULT WINAPI domdoc_get_dataType(
763 IXMLDOMDocument2 *iface,
764 VARIANT* dataTypeName )
766 domdoc *This = impl_from_IXMLDOMDocument2( iface );
767 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
771 static HRESULT WINAPI domdoc_put_dataType(
772 IXMLDOMDocument2 *iface,
775 domdoc *This = impl_from_IXMLDOMDocument2( iface );
776 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
780 static HRESULT WINAPI domdoc_get_xml(
781 IXMLDOMDocument2 *iface,
784 domdoc *This = impl_from_IXMLDOMDocument2( iface );
785 return IXMLDOMNode_get_xml( This->node, xmlString );
789 static HRESULT WINAPI domdoc_transformNode(
790 IXMLDOMDocument2 *iface,
791 IXMLDOMNode* styleSheet,
794 domdoc *This = impl_from_IXMLDOMDocument2( iface );
795 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
799 static HRESULT WINAPI domdoc_selectNodes(
800 IXMLDOMDocument2 *iface,
802 IXMLDOMNodeList** resultList )
804 domdoc *This = impl_from_IXMLDOMDocument2( iface );
805 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
809 static HRESULT WINAPI domdoc_selectSingleNode(
810 IXMLDOMDocument2 *iface,
812 IXMLDOMNode** resultNode )
814 domdoc *This = impl_from_IXMLDOMDocument2( iface );
815 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
819 static HRESULT WINAPI domdoc_get_parsed(
820 IXMLDOMDocument2 *iface,
821 VARIANT_BOOL* isParsed )
823 domdoc *This = impl_from_IXMLDOMDocument2( iface );
824 return IXMLDOMNode_get_parsed( This->node, isParsed );
828 static HRESULT WINAPI domdoc_get_namespaceURI(
829 IXMLDOMDocument2 *iface,
832 domdoc *This = impl_from_IXMLDOMDocument2( iface );
833 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
837 static HRESULT WINAPI domdoc_get_prefix(
838 IXMLDOMDocument2 *iface,
841 domdoc *This = impl_from_IXMLDOMDocument2( iface );
842 return IXMLDOMNode_get_prefix( This->node, prefixString );
846 static HRESULT WINAPI domdoc_get_baseName(
847 IXMLDOMDocument2 *iface,
850 domdoc *This = impl_from_IXMLDOMDocument2( iface );
851 return IXMLDOMNode_get_baseName( This->node, nameString );
855 static HRESULT WINAPI domdoc_transformNodeToObject(
856 IXMLDOMDocument2 *iface,
857 IXMLDOMNode* stylesheet,
858 VARIANT outputObject)
860 domdoc *This = impl_from_IXMLDOMDocument2( iface );
861 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
865 static HRESULT WINAPI domdoc_get_doctype(
866 IXMLDOMDocument2 *iface,
867 IXMLDOMDocumentType** documentType )
874 static HRESULT WINAPI domdoc_get_implementation(
875 IXMLDOMDocument2 *iface,
876 IXMLDOMImplementation** impl )
881 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
886 static HRESULT WINAPI domdoc_get_documentElement(
887 IXMLDOMDocument2 *iface,
888 IXMLDOMElement** DOMElement )
890 domdoc *This = impl_from_IXMLDOMDocument2( iface );
891 xmlDocPtr xmldoc = NULL;
892 xmlNodePtr root = NULL;
893 IXMLDOMNode *element_node;
896 TRACE("%p %p\n", This, This->node);
903 xmldoc = get_doc( This );
905 root = xmlDocGetRootElement( xmldoc );
909 element_node = create_node( root );
910 if(!element_node) return S_FALSE;
912 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
913 IXMLDOMNode_Release(element_node);
919 static HRESULT WINAPI domdoc_put_documentElement(
920 IXMLDOMDocument2 *iface,
921 IXMLDOMElement* DOMElement )
923 domdoc *This = impl_from_IXMLDOMDocument2( iface );
924 IXMLDOMNode *elementNode;
929 TRACE("(%p)->(%p)\n", This, DOMElement);
931 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
935 xmlNode = impl_from_IXMLDOMNode( elementNode );
937 if(!xmlNode->node->parent)
938 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
939 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
941 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
942 IXMLDOMNode_Release( elementNode );
945 xmldoc_add_orphan(oldRoot->doc, oldRoot);
951 static HRESULT WINAPI domdoc_createElement(
952 IXMLDOMDocument2 *iface,
954 IXMLDOMElement** element )
957 domdoc *This = impl_from_IXMLDOMDocument2( iface );
962 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
964 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
965 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
966 xmldoc_add_orphan(xmlnode->doc, xmlnode);
968 TRACE("created xmlptr %p\n", xmlnode);
969 elem_unk = create_element(xmlnode, NULL);
970 HeapFree(GetProcessHeap(), 0, xml_name);
972 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
973 IUnknown_Release(elem_unk);
974 TRACE("returning %p\n", *element);
979 static HRESULT WINAPI domdoc_createDocumentFragment(
980 IXMLDOMDocument2 *iface,
981 IXMLDOMDocumentFragment** docFrag )
983 domdoc *This = impl_from_IXMLDOMDocument2( iface );
986 TRACE("%p\n", iface);
993 xmlnode = xmlNewDocFragment(get_doc( This ) );
998 xmldoc_add_orphan(xmlnode->doc, xmlnode);
999 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1005 static HRESULT WINAPI domdoc_createTextNode(
1006 IXMLDOMDocument2 *iface,
1008 IXMLDOMText** text )
1010 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1012 xmlChar *xml_content;
1014 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1017 return E_INVALIDARG;
1021 xml_content = xmlChar_from_wchar((WCHAR*)data);
1022 xmlnode = xmlNewText(xml_content);
1023 HeapFree(GetProcessHeap(), 0, xml_content);
1028 xmlnode->doc = get_doc( This );
1029 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1031 *text = (IXMLDOMText*)create_text(xmlnode);
1037 static HRESULT WINAPI domdoc_createComment(
1038 IXMLDOMDocument2 *iface,
1040 IXMLDOMComment** comment )
1042 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1044 xmlChar *xml_content;
1046 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1049 return E_INVALIDARG;
1053 xml_content = xmlChar_from_wchar((WCHAR*)data);
1054 xmlnode = xmlNewComment(xml_content);
1055 HeapFree(GetProcessHeap(), 0, xml_content);
1060 xmlnode->doc = get_doc( This );
1061 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1063 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1069 static HRESULT WINAPI domdoc_createCDATASection(
1070 IXMLDOMDocument2 *iface,
1072 IXMLDOMCDATASection** cdata )
1074 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1076 xmlChar *xml_content;
1078 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1081 return E_INVALIDARG;
1085 xml_content = xmlChar_from_wchar((WCHAR*)data);
1086 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1087 HeapFree(GetProcessHeap(), 0, xml_content);
1092 xmlnode->doc = get_doc( This );
1093 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1095 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1101 static HRESULT WINAPI domdoc_createProcessingInstruction(
1102 IXMLDOMDocument2 *iface,
1105 IXMLDOMProcessingInstruction** pi )
1107 #ifdef HAVE_XMLNEWDOCPI
1109 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1110 xmlChar *xml_target, *xml_content;
1112 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1115 return E_INVALIDARG;
1117 if(!target || lstrlenW(target) == 0)
1120 xml_target = xmlChar_from_wchar((WCHAR*)target);
1121 xml_content = xmlChar_from_wchar((WCHAR*)data);
1123 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1124 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1125 TRACE("created xmlptr %p\n", xmlnode);
1126 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1128 HeapFree(GetProcessHeap(), 0, xml_content);
1129 HeapFree(GetProcessHeap(), 0, xml_target);
1133 FIXME("Libxml 2.6.15 or greater required.\n");
1139 static HRESULT WINAPI domdoc_createAttribute(
1140 IXMLDOMDocument2 *iface,
1142 IXMLDOMAttribute** attribute )
1144 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1148 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1151 return E_INVALIDARG;
1155 xml_name = xmlChar_from_wchar((WCHAR*)name);
1156 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1157 HeapFree(GetProcessHeap(), 0, xml_name);
1162 xmlnode->doc = get_doc( This );
1163 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1165 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1171 static HRESULT WINAPI domdoc_createEntityReference(
1172 IXMLDOMDocument2 *iface,
1174 IXMLDOMEntityReference** entityRef )
1176 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1180 TRACE("%p\n", iface);
1183 return E_INVALIDARG;
1187 xml_name = xmlChar_from_wchar((WCHAR*)name);
1188 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1189 HeapFree(GetProcessHeap(), 0, xml_name);
1194 xmlnode->doc = get_doc( This );
1195 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1197 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1203 static HRESULT WINAPI domdoc_getElementsByTagName(
1204 IXMLDOMDocument2 *iface,
1206 IXMLDOMNodeList** resultList )
1208 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1211 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1213 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1214 szPattern[0] = szPattern[1] = '/';
1215 lstrcpyW(szPattern + 2, tagName);
1217 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1218 HeapFree(GetProcessHeap(), 0, szPattern);
1223 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1229 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1231 return E_INVALIDARG;
1238 static HRESULT WINAPI domdoc_createNode(
1239 IXMLDOMDocument2 *iface,
1243 IXMLDOMNode** node )
1245 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1246 DOMNodeType node_type;
1247 xmlNodePtr xmlnode = NULL;
1251 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1253 hr = get_node_type(Type, &node_type);
1257 TRACE("node_type %d\n", node_type);
1259 xml_name = xmlChar_from_wchar((WCHAR*)name);
1264 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1265 *node = create_node(xmlnode);
1266 TRACE("created %p\n", xmlnode);
1268 case NODE_ATTRIBUTE:
1269 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1272 xmlnode->doc = get_doc( This );
1274 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1277 TRACE("created %p\n", xmlnode);
1281 FIXME("unhandled node type %d\n", node_type);
1285 HeapFree(GetProcessHeap(), 0, xml_name);
1287 if(xmlnode && *node)
1289 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1296 static HRESULT WINAPI domdoc_nodeFromID(
1297 IXMLDOMDocument2 *iface,
1299 IXMLDOMNode** node )
1305 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1310 xmldoc = doparse( ptr, len );
1312 xmldoc->_private = create_priv();
1313 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1319 static HRESULT doread( domdoc *This, LPWSTR filename )
1324 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1329 detach_bsc(This->bsc);
1335 static HRESULT WINAPI domdoc_load(
1336 IXMLDOMDocument2 *iface,
1338 VARIANT_BOOL* isSuccessful )
1340 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1341 LPWSTR filename = NULL;
1342 HRESULT hr = S_FALSE;
1343 IXMLDOMDocument2 *pNewDoc = NULL;
1344 IStream *pStream = NULL;
1347 TRACE("type %d\n", V_VT(&xmlSource) );
1349 *isSuccessful = VARIANT_FALSE;
1351 assert( This->node );
1353 attach_xmlnode(This->node, NULL);
1355 switch( V_VT(&xmlSource) )
1358 filename = V_BSTR(&xmlSource);
1361 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1366 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1367 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1368 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1370 *isSuccessful = VARIANT_TRUE;
1375 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1378 IPersistStream *pDocStream;
1379 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1382 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1383 IStream_Release(pStream);
1386 *isSuccessful = VARIANT_TRUE;
1388 TRACE("Using ID_IStream to load Document\n");
1393 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1398 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1403 /* ISequentialStream */
1404 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1408 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1411 TRACE("filename (%s)\n", debugstr_w(filename));
1415 hr = doread( This, filename );
1418 This->error = E_FAIL;
1421 hr = This->error = S_OK;
1422 *isSuccessful = VARIANT_TRUE;
1426 if(!filename || FAILED(hr)) {
1427 xmldoc = xmlNewDoc(NULL);
1428 xmldoc->_private = create_priv();
1429 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1433 TRACE("ret (%d)\n", hr);
1439 static HRESULT WINAPI domdoc_get_readyState(
1440 IXMLDOMDocument2 *iface,
1448 static HRESULT WINAPI domdoc_get_parseError(
1449 IXMLDOMDocument2 *iface,
1450 IXMLDOMParseError** errorObj )
1452 BSTR error_string = NULL;
1453 static const WCHAR err[] = {'e','r','r','o','r',0};
1454 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1456 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1459 error_string = SysAllocString(err);
1461 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1462 if(!*errorObj) return E_OUTOFMEMORY;
1467 static HRESULT WINAPI domdoc_get_url(
1468 IXMLDOMDocument2 *iface,
1476 static HRESULT WINAPI domdoc_get_async(
1477 IXMLDOMDocument2 *iface,
1478 VARIANT_BOOL* isAsync )
1480 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1482 TRACE("%p <- %d\n", isAsync, This->async);
1483 *isAsync = This->async;
1488 static HRESULT WINAPI domdoc_put_async(
1489 IXMLDOMDocument2 *iface,
1490 VARIANT_BOOL isAsync )
1492 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1494 TRACE("%d\n", isAsync);
1495 This->async = isAsync;
1500 static HRESULT WINAPI domdoc_abort(
1501 IXMLDOMDocument2 *iface )
1508 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1510 UINT len, blen = SysStringLen( bstr );
1513 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1514 str = HeapAlloc( GetProcessHeap(), 0, len );
1517 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1523 static HRESULT WINAPI domdoc_loadXML(
1524 IXMLDOMDocument2 *iface,
1526 VARIANT_BOOL* isSuccessful )
1528 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1529 xmlDocPtr xmldoc = NULL;
1532 HRESULT hr = S_FALSE;
1534 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1536 assert ( This->node );
1538 attach_xmlnode( This->node, NULL );
1542 *isSuccessful = VARIANT_FALSE;
1544 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1546 xmldoc = doparse( str, len );
1547 HeapFree( GetProcessHeap(), 0, str );
1549 This->error = E_FAIL;
1552 hr = This->error = S_OK;
1553 *isSuccessful = VARIANT_TRUE;
1558 xmldoc = xmlNewDoc(NULL);
1560 xmldoc->_private = create_priv();
1561 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1567 static HRESULT WINAPI domdoc_save(
1568 IXMLDOMDocument2 *iface,
1569 VARIANT destination )
1571 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1578 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1579 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1581 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1583 FIXME("Unhandled vt %d\n", V_VT(&destination));
1587 if(V_VT(&destination) == VT_UNKNOWN)
1589 IUnknown *pUnk = V_UNKNOWN(&destination);
1590 IXMLDOMDocument *pDocument;
1592 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1596 VARIANT_BOOL bSuccessful;
1598 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1601 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1603 SysFreeString(bXML);
1606 IXMLDOMDocument_Release(pDocument);
1609 TRACE("ret %d\n", ret);
1614 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1615 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1616 if( handle == INVALID_HANDLE_VALUE )
1618 WARN("failed to create file\n");
1622 xmlDocDumpMemory(get_doc(This), &mem, &size);
1625 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1626 * MSXML adds XML declaration only for processing instruction nodes.
1627 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1630 if(size > 2 && p[0] == '<' && p[1] == '?') {
1631 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1634 while(p < mem+size && isspace(*p))
1639 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1641 WARN("write error\n");
1646 CloseHandle(handle);
1650 static HRESULT WINAPI domdoc_get_validateOnParse(
1651 IXMLDOMDocument2 *iface,
1652 VARIANT_BOOL* isValidating )
1654 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1656 TRACE("%p <- %d\n", isValidating, This->validating);
1657 *isValidating = This->validating;
1662 static HRESULT WINAPI domdoc_put_validateOnParse(
1663 IXMLDOMDocument2 *iface,
1664 VARIANT_BOOL isValidating )
1666 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1668 TRACE("%d\n", isValidating);
1669 This->validating = isValidating;
1674 static HRESULT WINAPI domdoc_get_resolveExternals(
1675 IXMLDOMDocument2 *iface,
1676 VARIANT_BOOL* isResolving )
1678 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1680 TRACE("%p <- %d\n", isResolving, This->resolving);
1681 *isResolving = This->resolving;
1686 static HRESULT WINAPI domdoc_put_resolveExternals(
1687 IXMLDOMDocument2 *iface,
1688 VARIANT_BOOL isResolving )
1690 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1692 TRACE("%d\n", isResolving);
1693 This->resolving = isResolving;
1698 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1699 IXMLDOMDocument2 *iface,
1700 VARIANT_BOOL* isPreserving )
1702 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1704 TRACE("%p <- %d\n", isPreserving, This->preserving);
1705 *isPreserving = This->preserving;
1710 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1711 IXMLDOMDocument2 *iface,
1712 VARIANT_BOOL isPreserving )
1714 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1716 TRACE("%d\n", isPreserving);
1717 This->preserving = isPreserving;
1722 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1723 IXMLDOMDocument2 *iface,
1724 VARIANT readyStateChangeSink )
1731 static HRESULT WINAPI domdoc_put_onDataAvailable(
1732 IXMLDOMDocument2 *iface,
1733 VARIANT onDataAvailableSink )
1739 static HRESULT WINAPI domdoc_put_onTransformNode(
1740 IXMLDOMDocument2 *iface,
1741 VARIANT onTransformNodeSink )
1747 static HRESULT WINAPI domdoc_get_namespaces(
1748 IXMLDOMDocument2* iface,
1749 IXMLDOMSchemaCollection** schemaCollection )
1755 static HRESULT WINAPI domdoc_get_schemas(
1756 IXMLDOMDocument2* iface,
1759 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1760 HRESULT hr = S_FALSE;
1761 IXMLDOMSchemaCollection *cur_schema = This->schema;
1763 TRACE("(%p)->(%p)\n", This, var1);
1765 VariantInit(var1); /* Test shows we don't call VariantClear here */
1766 V_VT(var1) = VT_NULL;
1770 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1772 V_VT(var1) = VT_DISPATCH;
1777 static HRESULT WINAPI domdoc_putref_schemas(
1778 IXMLDOMDocument2* iface,
1781 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1782 HRESULT hr = E_FAIL;
1783 IXMLDOMSchemaCollection *new_schema = NULL;
1785 FIXME("(%p): semi-stub\n", This);
1789 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1793 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1802 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1807 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1808 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1814 static HRESULT WINAPI domdoc_validate(
1815 IXMLDOMDocument2* iface,
1816 IXMLDOMParseError** err)
1822 static HRESULT WINAPI domdoc_setProperty(
1823 IXMLDOMDocument2* iface,
1827 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1829 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1835 V_VT(&varStr) = VT_EMPTY;
1836 if (V_VT(&var) != VT_BSTR)
1838 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1840 bstr = V_BSTR(&varStr);
1843 bstr = V_BSTR(&var);
1846 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1847 This->bUseXPath = TRUE;
1848 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1849 This->bUseXPath = FALSE;
1853 VariantClear(&varStr);
1857 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1861 static HRESULT WINAPI domdoc_getProperty(
1862 IXMLDOMDocument2* iface,
1866 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1869 return E_INVALIDARG;
1870 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1872 V_VT(var) = VT_BSTR;
1873 if (This->bUseXPath)
1874 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1876 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1880 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1884 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1886 domdoc_QueryInterface,
1889 domdoc_GetTypeInfoCount,
1891 domdoc_GetIDsOfNames,
1893 domdoc_get_nodeName,
1894 domdoc_get_nodeValue,
1895 domdoc_put_nodeValue,
1896 domdoc_get_nodeType,
1897 domdoc_get_parentNode,
1898 domdoc_get_childNodes,
1899 domdoc_get_firstChild,
1900 domdoc_get_lastChild,
1901 domdoc_get_previousSibling,
1902 domdoc_get_nextSibling,
1903 domdoc_get_attributes,
1904 domdoc_insertBefore,
1905 domdoc_replaceChild,
1908 domdoc_hasChildNodes,
1909 domdoc_get_ownerDocument,
1911 domdoc_get_nodeTypeString,
1914 domdoc_get_specified,
1915 domdoc_get_definition,
1916 domdoc_get_nodeTypedValue,
1917 domdoc_put_nodeTypedValue,
1918 domdoc_get_dataType,
1919 domdoc_put_dataType,
1921 domdoc_transformNode,
1923 domdoc_selectSingleNode,
1925 domdoc_get_namespaceURI,
1927 domdoc_get_baseName,
1928 domdoc_transformNodeToObject,
1930 domdoc_get_implementation,
1931 domdoc_get_documentElement,
1932 domdoc_put_documentElement,
1933 domdoc_createElement,
1934 domdoc_createDocumentFragment,
1935 domdoc_createTextNode,
1936 domdoc_createComment,
1937 domdoc_createCDATASection,
1938 domdoc_createProcessingInstruction,
1939 domdoc_createAttribute,
1940 domdoc_createEntityReference,
1941 domdoc_getElementsByTagName,
1945 domdoc_get_readyState,
1946 domdoc_get_parseError,
1953 domdoc_get_validateOnParse,
1954 domdoc_put_validateOnParse,
1955 domdoc_get_resolveExternals,
1956 domdoc_put_resolveExternals,
1957 domdoc_get_preserveWhiteSpace,
1958 domdoc_put_preserveWhiteSpace,
1959 domdoc_put_onReadyStateChange,
1960 domdoc_put_onDataAvailable,
1961 domdoc_put_onTransformNode,
1962 domdoc_get_namespaces,
1964 domdoc_putref_schemas,
1970 /* xmldoc implementation of IObjectWithSite */
1971 static HRESULT WINAPI
1972 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
1974 domdoc *This = impl_from_IObjectWithSite(iface);
1975 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
1979 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
1981 domdoc *This = impl_from_IObjectWithSite(iface);
1982 return IXMLDocument_AddRef((IXMLDocument *)This);
1986 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
1988 domdoc *This = impl_from_IObjectWithSite(iface);
1989 return IXMLDocument_Release((IXMLDocument *)This);
1992 static HRESULT WINAPI
1993 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
1995 domdoc *This = impl_from_IObjectWithSite(iface);
1997 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2002 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2005 static HRESULT WINAPI
2006 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2008 domdoc *This = impl_from_IObjectWithSite(iface);
2010 TRACE("%p %p\n", iface, punk);
2016 IUnknown_Release( This->site );
2024 IUnknown_AddRef( punk );
2027 IUnknown_Release( This->site );
2034 static const IObjectWithSiteVtbl domdocObjectSite =
2036 xmldoc_ObjectWithSite_QueryInterface,
2037 xmldoc_ObjectWithSite_AddRef,
2038 xmldoc_ObjectWithSite_Release,
2043 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2045 domdoc *This = impl_from_IObjectSafety(iface);
2046 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2049 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2051 domdoc *This = impl_from_IObjectSafety(iface);
2052 return IXMLDocument_AddRef((IXMLDocument *)This);
2055 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2057 domdoc *This = impl_from_IObjectSafety(iface);
2058 return IXMLDocument_Release((IXMLDocument *)This);
2061 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2063 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2064 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2066 domdoc *This = impl_from_IObjectSafety(iface);
2068 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2070 if(!pdwSupportedOptions || !pdwEnabledOptions)
2073 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2074 *pdwEnabledOptions = This->safeopt;
2079 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2080 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2082 domdoc *This = impl_from_IObjectSafety(iface);
2084 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2086 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2089 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2093 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2094 xmldoc_Safety_QueryInterface,
2095 xmldoc_Safety_AddRef,
2096 xmldoc_Safety_Release,
2097 xmldoc_Safety_GetInterfaceSafetyOptions,
2098 xmldoc_Safety_SetInterfaceSafetyOptions
2102 static const tid_t domdoc_iface_tids[] = {
2104 IXMLDOMDocument_tid,
2105 IXMLDOMDocument2_tid,
2108 static dispex_static_data_t domdoc_dispex = {
2110 IXMLDOMDocument2_tid,
2115 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2120 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2122 return E_OUTOFMEMORY;
2124 doc->lpVtbl = &domdoc_vtbl;
2125 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2126 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2127 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2130 doc->validating = 0;
2132 doc->preserving = 0;
2133 doc->bUseXPath = FALSE;
2141 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2144 HeapFree(GetProcessHeap(), 0, doc);
2148 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2151 IUnknown_Release(doc->node_unk);
2152 HeapFree( GetProcessHeap(), 0, doc );
2156 init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2158 /* The ref on doc->node is actually looped back into this object, so release it */
2159 IXMLDOMNode_Release(doc->node);
2161 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2163 TRACE("returning iface %p\n", *document);
2167 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2172 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2174 xmldoc = xmlNewDoc(NULL);
2176 return E_OUTOFMEMORY;
2178 xmldoc->_private = create_priv();
2180 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2187 IUnknown* create_domdoc( xmlNodePtr document )
2192 TRACE("(%p)\n", document);
2194 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2198 return (IUnknown*)pObj;
2203 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2205 MESSAGE("This program tried to use a DOMDocument object, but\n"
2206 "libxml2 support was not present at compile time.\n");