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;
928 TRACE("(%p)->(%p)\n", This, DOMElement);
930 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
934 xmlNode = impl_from_IXMLDOMNode( elementNode );
935 xmlDocSetRootElement( get_doc(This), xmlNode->node);
936 IXMLDOMNode_Release( elementNode );
942 static HRESULT WINAPI domdoc_createElement(
943 IXMLDOMDocument2 *iface,
945 IXMLDOMElement** element )
948 domdoc *This = impl_from_IXMLDOMDocument2( iface );
953 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
955 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
956 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
957 xmldoc_add_orphan(xmlnode->doc, xmlnode);
959 TRACE("created xmlptr %p\n", xmlnode);
960 elem_unk = create_element(xmlnode, NULL);
961 HeapFree(GetProcessHeap(), 0, xml_name);
963 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
964 IUnknown_Release(elem_unk);
965 TRACE("returning %p\n", *element);
970 static HRESULT WINAPI domdoc_createDocumentFragment(
971 IXMLDOMDocument2 *iface,
972 IXMLDOMDocumentFragment** docFrag )
974 domdoc *This = impl_from_IXMLDOMDocument2( iface );
977 TRACE("%p\n", iface);
984 xmlnode = xmlNewDocFragment(get_doc( This ) );
989 xmldoc_add_orphan(xmlnode->doc, xmlnode);
990 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
996 static HRESULT WINAPI domdoc_createTextNode(
997 IXMLDOMDocument2 *iface,
1001 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1003 xmlChar *xml_content;
1005 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1008 return E_INVALIDARG;
1012 xml_content = xmlChar_from_wchar((WCHAR*)data);
1013 xmlnode = xmlNewText(xml_content);
1014 HeapFree(GetProcessHeap(), 0, xml_content);
1019 xmlnode->doc = get_doc( This );
1020 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1022 *text = (IXMLDOMText*)create_text(xmlnode);
1028 static HRESULT WINAPI domdoc_createComment(
1029 IXMLDOMDocument2 *iface,
1031 IXMLDOMComment** comment )
1033 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1035 xmlChar *xml_content;
1037 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1040 return E_INVALIDARG;
1044 xml_content = xmlChar_from_wchar((WCHAR*)data);
1045 xmlnode = xmlNewComment(xml_content);
1046 HeapFree(GetProcessHeap(), 0, xml_content);
1051 xmlnode->doc = get_doc( This );
1052 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1054 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1060 static HRESULT WINAPI domdoc_createCDATASection(
1061 IXMLDOMDocument2 *iface,
1063 IXMLDOMCDATASection** cdata )
1065 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1067 xmlChar *xml_content;
1069 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1072 return E_INVALIDARG;
1076 xml_content = xmlChar_from_wchar((WCHAR*)data);
1077 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1078 HeapFree(GetProcessHeap(), 0, xml_content);
1083 xmlnode->doc = get_doc( This );
1084 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1086 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1092 static HRESULT WINAPI domdoc_createProcessingInstruction(
1093 IXMLDOMDocument2 *iface,
1096 IXMLDOMProcessingInstruction** pi )
1098 #ifdef HAVE_XMLNEWDOCPI
1100 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1101 xmlChar *xml_target, *xml_content;
1103 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1106 return E_INVALIDARG;
1108 if(!target || lstrlenW(target) == 0)
1111 xml_target = xmlChar_from_wchar((WCHAR*)target);
1112 xml_content = xmlChar_from_wchar((WCHAR*)data);
1114 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1115 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1116 TRACE("created xmlptr %p\n", xmlnode);
1117 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1119 HeapFree(GetProcessHeap(), 0, xml_content);
1120 HeapFree(GetProcessHeap(), 0, xml_target);
1124 FIXME("Libxml 2.6.15 or greater required.\n");
1130 static HRESULT WINAPI domdoc_createAttribute(
1131 IXMLDOMDocument2 *iface,
1133 IXMLDOMAttribute** attribute )
1135 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1139 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1142 return E_INVALIDARG;
1146 xml_name = xmlChar_from_wchar((WCHAR*)name);
1147 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1148 HeapFree(GetProcessHeap(), 0, xml_name);
1153 xmlnode->doc = get_doc( This );
1154 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1156 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1162 static HRESULT WINAPI domdoc_createEntityReference(
1163 IXMLDOMDocument2 *iface,
1165 IXMLDOMEntityReference** entityRef )
1167 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1171 TRACE("%p\n", iface);
1174 return E_INVALIDARG;
1178 xml_name = xmlChar_from_wchar((WCHAR*)name);
1179 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1180 HeapFree(GetProcessHeap(), 0, xml_name);
1185 xmlnode->doc = get_doc( This );
1186 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1188 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1194 static HRESULT WINAPI domdoc_getElementsByTagName(
1195 IXMLDOMDocument2 *iface,
1197 IXMLDOMNodeList** resultList )
1199 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1202 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1204 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1205 szPattern[0] = szPattern[1] = '/';
1206 lstrcpyW(szPattern + 2, tagName);
1208 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1209 HeapFree(GetProcessHeap(), 0, szPattern);
1214 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1220 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1222 return E_INVALIDARG;
1229 static HRESULT WINAPI domdoc_createNode(
1230 IXMLDOMDocument2 *iface,
1234 IXMLDOMNode** node )
1236 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1237 DOMNodeType node_type;
1238 xmlNodePtr xmlnode = NULL;
1242 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1244 hr = get_node_type(Type, &node_type);
1248 TRACE("node_type %d\n", node_type);
1250 xml_name = xmlChar_from_wchar((WCHAR*)name);
1255 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1256 *node = create_node(xmlnode);
1257 TRACE("created %p\n", xmlnode);
1259 case NODE_ATTRIBUTE:
1260 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1263 xmlnode->doc = get_doc( This );
1265 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1268 TRACE("created %p\n", xmlnode);
1272 FIXME("unhandled node type %d\n", node_type);
1276 HeapFree(GetProcessHeap(), 0, xml_name);
1278 if(xmlnode && *node)
1280 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1287 static HRESULT WINAPI domdoc_nodeFromID(
1288 IXMLDOMDocument2 *iface,
1290 IXMLDOMNode** node )
1296 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1301 xmldoc = doparse( ptr, len );
1303 xmldoc->_private = create_priv();
1304 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1310 static HRESULT doread( domdoc *This, LPWSTR filename )
1315 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1320 detach_bsc(This->bsc);
1326 static HRESULT WINAPI domdoc_load(
1327 IXMLDOMDocument2 *iface,
1329 VARIANT_BOOL* isSuccessful )
1331 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1332 LPWSTR filename = NULL;
1333 HRESULT hr = S_FALSE;
1334 IXMLDOMDocument2 *pNewDoc = NULL;
1335 IStream *pStream = NULL;
1338 TRACE("type %d\n", V_VT(&xmlSource) );
1340 *isSuccessful = VARIANT_FALSE;
1342 assert( This->node );
1344 attach_xmlnode(This->node, NULL);
1346 switch( V_VT(&xmlSource) )
1349 filename = V_BSTR(&xmlSource);
1352 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1357 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1358 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1359 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1361 *isSuccessful = VARIANT_TRUE;
1366 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1369 IPersistStream *pDocStream;
1370 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1373 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1374 IStream_Release(pStream);
1377 *isSuccessful = VARIANT_TRUE;
1379 TRACE("Using ID_IStream to load Document\n");
1384 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1389 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1394 /* ISequentialStream */
1395 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1399 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1402 TRACE("filename (%s)\n", debugstr_w(filename));
1406 hr = doread( This, filename );
1409 This->error = E_FAIL;
1412 hr = This->error = S_OK;
1413 *isSuccessful = VARIANT_TRUE;
1417 if(!filename || FAILED(hr)) {
1418 xmldoc = xmlNewDoc(NULL);
1419 xmldoc->_private = create_priv();
1420 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1424 TRACE("ret (%d)\n", hr);
1430 static HRESULT WINAPI domdoc_get_readyState(
1431 IXMLDOMDocument2 *iface,
1439 static HRESULT WINAPI domdoc_get_parseError(
1440 IXMLDOMDocument2 *iface,
1441 IXMLDOMParseError** errorObj )
1443 BSTR error_string = NULL;
1444 static const WCHAR err[] = {'e','r','r','o','r',0};
1445 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1447 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1450 error_string = SysAllocString(err);
1452 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1453 if(!*errorObj) return E_OUTOFMEMORY;
1458 static HRESULT WINAPI domdoc_get_url(
1459 IXMLDOMDocument2 *iface,
1467 static HRESULT WINAPI domdoc_get_async(
1468 IXMLDOMDocument2 *iface,
1469 VARIANT_BOOL* isAsync )
1471 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1473 TRACE("%p <- %d\n", isAsync, This->async);
1474 *isAsync = This->async;
1479 static HRESULT WINAPI domdoc_put_async(
1480 IXMLDOMDocument2 *iface,
1481 VARIANT_BOOL isAsync )
1483 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1485 TRACE("%d\n", isAsync);
1486 This->async = isAsync;
1491 static HRESULT WINAPI domdoc_abort(
1492 IXMLDOMDocument2 *iface )
1499 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1501 UINT len, blen = SysStringLen( bstr );
1504 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1505 str = HeapAlloc( GetProcessHeap(), 0, len );
1508 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1514 static HRESULT WINAPI domdoc_loadXML(
1515 IXMLDOMDocument2 *iface,
1517 VARIANT_BOOL* isSuccessful )
1519 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1520 xmlDocPtr xmldoc = NULL;
1523 HRESULT hr = S_FALSE;
1525 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1527 assert ( This->node );
1529 attach_xmlnode( This->node, NULL );
1533 *isSuccessful = VARIANT_FALSE;
1535 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1537 xmldoc = doparse( str, len );
1538 HeapFree( GetProcessHeap(), 0, str );
1540 This->error = E_FAIL;
1543 hr = This->error = S_OK;
1544 *isSuccessful = VARIANT_TRUE;
1549 xmldoc = xmlNewDoc(NULL);
1551 xmldoc->_private = create_priv();
1552 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1558 static HRESULT WINAPI domdoc_save(
1559 IXMLDOMDocument2 *iface,
1560 VARIANT destination )
1562 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1569 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1570 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1572 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1574 FIXME("Unhandled vt %d\n", V_VT(&destination));
1578 if(V_VT(&destination) == VT_UNKNOWN)
1580 IUnknown *pUnk = V_UNKNOWN(&destination);
1581 IXMLDOMDocument *pDocument;
1583 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1587 VARIANT_BOOL bSuccessful;
1589 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1592 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1594 SysFreeString(bXML);
1597 IXMLDOMDocument_Release(pDocument);
1600 TRACE("ret %d\n", ret);
1605 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1606 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1607 if( handle == INVALID_HANDLE_VALUE )
1609 WARN("failed to create file\n");
1613 xmlDocDumpMemory(get_doc(This), &mem, &size);
1616 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1617 * MSXML adds XML declaration only for processing instruction nodes.
1618 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1621 if(size > 2 && p[0] == '<' && p[1] == '?') {
1622 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1625 while(p < mem+size && isspace(*p))
1630 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1632 WARN("write error\n");
1637 CloseHandle(handle);
1641 static HRESULT WINAPI domdoc_get_validateOnParse(
1642 IXMLDOMDocument2 *iface,
1643 VARIANT_BOOL* isValidating )
1645 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1647 TRACE("%p <- %d\n", isValidating, This->validating);
1648 *isValidating = This->validating;
1653 static HRESULT WINAPI domdoc_put_validateOnParse(
1654 IXMLDOMDocument2 *iface,
1655 VARIANT_BOOL isValidating )
1657 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1659 TRACE("%d\n", isValidating);
1660 This->validating = isValidating;
1665 static HRESULT WINAPI domdoc_get_resolveExternals(
1666 IXMLDOMDocument2 *iface,
1667 VARIANT_BOOL* isResolving )
1669 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1671 TRACE("%p <- %d\n", isResolving, This->resolving);
1672 *isResolving = This->resolving;
1677 static HRESULT WINAPI domdoc_put_resolveExternals(
1678 IXMLDOMDocument2 *iface,
1679 VARIANT_BOOL isResolving )
1681 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1683 TRACE("%d\n", isResolving);
1684 This->resolving = isResolving;
1689 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1690 IXMLDOMDocument2 *iface,
1691 VARIANT_BOOL* isPreserving )
1693 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1695 TRACE("%p <- %d\n", isPreserving, This->preserving);
1696 *isPreserving = This->preserving;
1701 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1702 IXMLDOMDocument2 *iface,
1703 VARIANT_BOOL isPreserving )
1705 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1707 TRACE("%d\n", isPreserving);
1708 This->preserving = isPreserving;
1713 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1714 IXMLDOMDocument2 *iface,
1715 VARIANT readyStateChangeSink )
1722 static HRESULT WINAPI domdoc_put_onDataAvailable(
1723 IXMLDOMDocument2 *iface,
1724 VARIANT onDataAvailableSink )
1730 static HRESULT WINAPI domdoc_put_onTransformNode(
1731 IXMLDOMDocument2 *iface,
1732 VARIANT onTransformNodeSink )
1738 static HRESULT WINAPI domdoc_get_namespaces(
1739 IXMLDOMDocument2* iface,
1740 IXMLDOMSchemaCollection** schemaCollection )
1746 static HRESULT WINAPI domdoc_get_schemas(
1747 IXMLDOMDocument2* iface,
1750 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1751 HRESULT hr = S_FALSE;
1752 IXMLDOMSchemaCollection *cur_schema = This->schema;
1754 TRACE("(%p)->(%p)\n", This, var1);
1756 VariantInit(var1); /* Test shows we don't call VariantClear here */
1757 V_VT(var1) = VT_NULL;
1761 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1763 V_VT(var1) = VT_DISPATCH;
1768 static HRESULT WINAPI domdoc_putref_schemas(
1769 IXMLDOMDocument2* iface,
1772 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1773 HRESULT hr = E_FAIL;
1774 IXMLDOMSchemaCollection *new_schema = NULL;
1776 FIXME("(%p): semi-stub\n", This);
1780 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1784 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1793 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1798 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1799 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1805 static HRESULT WINAPI domdoc_validate(
1806 IXMLDOMDocument2* iface,
1807 IXMLDOMParseError** err)
1813 static HRESULT WINAPI domdoc_setProperty(
1814 IXMLDOMDocument2* iface,
1818 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1820 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1826 V_VT(&varStr) = VT_EMPTY;
1827 if (V_VT(&var) != VT_BSTR)
1829 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1831 bstr = V_BSTR(&varStr);
1834 bstr = V_BSTR(&var);
1837 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1838 This->bUseXPath = TRUE;
1839 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1840 This->bUseXPath = FALSE;
1844 VariantClear(&varStr);
1848 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1852 static HRESULT WINAPI domdoc_getProperty(
1853 IXMLDOMDocument2* iface,
1857 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1860 return E_INVALIDARG;
1861 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1863 V_VT(var) = VT_BSTR;
1864 if (This->bUseXPath)
1865 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1867 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1871 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1875 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1877 domdoc_QueryInterface,
1880 domdoc_GetTypeInfoCount,
1882 domdoc_GetIDsOfNames,
1884 domdoc_get_nodeName,
1885 domdoc_get_nodeValue,
1886 domdoc_put_nodeValue,
1887 domdoc_get_nodeType,
1888 domdoc_get_parentNode,
1889 domdoc_get_childNodes,
1890 domdoc_get_firstChild,
1891 domdoc_get_lastChild,
1892 domdoc_get_previousSibling,
1893 domdoc_get_nextSibling,
1894 domdoc_get_attributes,
1895 domdoc_insertBefore,
1896 domdoc_replaceChild,
1899 domdoc_hasChildNodes,
1900 domdoc_get_ownerDocument,
1902 domdoc_get_nodeTypeString,
1905 domdoc_get_specified,
1906 domdoc_get_definition,
1907 domdoc_get_nodeTypedValue,
1908 domdoc_put_nodeTypedValue,
1909 domdoc_get_dataType,
1910 domdoc_put_dataType,
1912 domdoc_transformNode,
1914 domdoc_selectSingleNode,
1916 domdoc_get_namespaceURI,
1918 domdoc_get_baseName,
1919 domdoc_transformNodeToObject,
1921 domdoc_get_implementation,
1922 domdoc_get_documentElement,
1923 domdoc_put_documentElement,
1924 domdoc_createElement,
1925 domdoc_createDocumentFragment,
1926 domdoc_createTextNode,
1927 domdoc_createComment,
1928 domdoc_createCDATASection,
1929 domdoc_createProcessingInstruction,
1930 domdoc_createAttribute,
1931 domdoc_createEntityReference,
1932 domdoc_getElementsByTagName,
1936 domdoc_get_readyState,
1937 domdoc_get_parseError,
1944 domdoc_get_validateOnParse,
1945 domdoc_put_validateOnParse,
1946 domdoc_get_resolveExternals,
1947 domdoc_put_resolveExternals,
1948 domdoc_get_preserveWhiteSpace,
1949 domdoc_put_preserveWhiteSpace,
1950 domdoc_put_onReadyStateChange,
1951 domdoc_put_onDataAvailable,
1952 domdoc_put_onTransformNode,
1953 domdoc_get_namespaces,
1955 domdoc_putref_schemas,
1961 /* xmldoc implementation of IObjectWithSite */
1962 static HRESULT WINAPI
1963 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
1965 domdoc *This = impl_from_IObjectWithSite(iface);
1966 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
1970 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
1972 domdoc *This = impl_from_IObjectWithSite(iface);
1973 return IXMLDocument_AddRef((IXMLDocument *)This);
1977 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
1979 domdoc *This = impl_from_IObjectWithSite(iface);
1980 return IXMLDocument_Release((IXMLDocument *)This);
1983 static HRESULT WINAPI
1984 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
1986 domdoc *This = impl_from_IObjectWithSite(iface);
1988 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
1993 return IUnknown_QueryInterface( This->site, iid, ppvSite );
1996 static HRESULT WINAPI
1997 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
1999 domdoc *This = impl_from_IObjectWithSite(iface);
2001 TRACE("%p %p\n", iface, punk);
2007 IUnknown_Release( This->site );
2015 IUnknown_AddRef( punk );
2018 IUnknown_Release( This->site );
2025 static const IObjectWithSiteVtbl domdocObjectSite =
2027 xmldoc_ObjectWithSite_QueryInterface,
2028 xmldoc_ObjectWithSite_AddRef,
2029 xmldoc_ObjectWithSite_Release,
2034 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2036 domdoc *This = impl_from_IObjectSafety(iface);
2037 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2040 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2042 domdoc *This = impl_from_IObjectSafety(iface);
2043 return IXMLDocument_AddRef((IXMLDocument *)This);
2046 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2048 domdoc *This = impl_from_IObjectSafety(iface);
2049 return IXMLDocument_Release((IXMLDocument *)This);
2052 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2054 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2055 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2057 domdoc *This = impl_from_IObjectSafety(iface);
2059 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2061 if(!pdwSupportedOptions || !pdwEnabledOptions)
2064 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2065 *pdwEnabledOptions = This->safeopt;
2070 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2071 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2073 domdoc *This = impl_from_IObjectSafety(iface);
2075 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2077 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2080 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2084 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2085 xmldoc_Safety_QueryInterface,
2086 xmldoc_Safety_AddRef,
2087 xmldoc_Safety_Release,
2088 xmldoc_Safety_GetInterfaceSafetyOptions,
2089 xmldoc_Safety_SetInterfaceSafetyOptions
2093 static const tid_t domdoc_iface_tids[] = {
2095 IXMLDOMDocument_tid,
2096 IXMLDOMDocument2_tid,
2099 static dispex_static_data_t domdoc_dispex = {
2101 IXMLDOMDocument2_tid,
2106 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2111 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2113 return E_OUTOFMEMORY;
2115 doc->lpVtbl = &domdoc_vtbl;
2116 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2117 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2118 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2121 doc->validating = 0;
2123 doc->preserving = 0;
2124 doc->bUseXPath = FALSE;
2132 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2135 HeapFree(GetProcessHeap(), 0, doc);
2139 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2142 IUnknown_Release(doc->node_unk);
2143 HeapFree( GetProcessHeap(), 0, doc );
2147 init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2149 /* The ref on doc->node is actually looped back into this object, so release it */
2150 IXMLDOMNode_Release(doc->node);
2152 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2154 TRACE("returning iface %p\n", *document);
2158 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2163 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2165 xmldoc = xmlNewDoc(NULL);
2167 return E_OUTOFMEMORY;
2169 xmldoc->_private = create_priv();
2171 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2178 IUnknown* create_domdoc( xmlNodePtr document )
2183 TRACE("(%p)\n", document);
2185 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2189 return (IUnknown*)pObj;
2194 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2196 MESSAGE("This program tried to use a DOMDocument object, but\n"
2197 "libxml2 support was not present at compile time.\n");