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;
68 IXMLDOMSchemaCollection *schema;
83 In native windows, the whole lifetime management of XMLDOMNodes is
84 managed automatically using reference counts. Wine emulates that by
85 maintaining a reference count to the document that is increased for
86 each IXMLDOMNode pointer passed out for this document. If all these
87 pointers are gone, the document is unreachable and gets freed, that
88 is, all nodes in the tree of the document get freed.
90 You are able to create nodes that are associated to a document (in
91 fact, in msxml's XMLDOM model, all nodes are associated to a document),
92 but not in the tree of that document, for example using the createFoo
93 functions from IXMLDOMDocument. These nodes do not get cleaned up
94 by libxml, so we have to do it ourselves.
96 To catch these nodes, a list of "orphan nodes" is introduced.
97 It contains pointers to all roots of node trees that are
98 associated with the document without being part of the document
99 tree. All nodes with parent==NULL (except for the document root nodes)
100 should be in the orphan node list of their document. All orphan nodes
101 get freed together with the document itself.
104 typedef struct _xmldoc_priv {
109 typedef struct _orphan_entry {
114 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
116 return doc->_private;
119 static xmldoc_priv * create_priv(void)
122 priv = HeapAlloc( GetProcessHeap(), 0, sizeof (*priv) );
127 list_init( &priv->orphans );
133 static xmlDocPtr doparse( char *ptr, int len )
135 #ifdef HAVE_XMLREADMEMORY
137 * use xmlReadMemory if possible so we can suppress
138 * writing errors to stderr
140 return xmlReadMemory( ptr, len, NULL, NULL,
141 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
143 return xmlParseMemory( ptr, len );
147 LONG xmldoc_add_ref(xmlDocPtr doc)
149 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
154 LONG xmldoc_release(xmlDocPtr doc)
156 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
157 LONG ref = InterlockedDecrement(&priv->refs);
161 orphan_entry *orphan, *orphan2;
162 TRACE("freeing docptr %p\n", doc);
164 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
166 xmlFreeNode( orphan->node );
167 HeapFree( GetProcessHeap(), 0, orphan );
169 HeapFree(GetProcessHeap(), 0, doc->_private);
177 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
179 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
182 entry = HeapAlloc( GetProcessHeap(), 0, sizeof (*entry) );
184 return E_OUTOFMEMORY;
187 list_add_head( &priv->orphans, &entry->entry );
191 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
193 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
194 orphan_entry *entry, *entry2;
196 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
198 if( entry->node == node )
200 list_remove( &entry->entry );
201 HeapFree( GetProcessHeap(), 0, entry );
209 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
212 xmldoc_release(node->node->doc);
214 node->node = (xmlNodePtr) xml;
216 xmldoc_add_ref(node->node->doc);
221 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
223 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
226 static inline xmlDocPtr get_doc( domdoc *This )
228 return (xmlDocPtr)This->node->node;
231 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
233 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
236 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
238 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
241 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
243 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
246 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
248 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
251 /************************************************************************
252 * xmldoc implementation of IPersistStream.
254 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
255 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
257 domdoc *this = impl_from_IPersistStream(iface);
258 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
261 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
262 IPersistStream *iface)
264 domdoc *this = impl_from_IPersistStream(iface);
265 return IXMLDocument_AddRef((IXMLDocument *)this);
268 static ULONG WINAPI xmldoc_IPersistStream_Release(
269 IPersistStream *iface)
271 domdoc *this = impl_from_IPersistStream(iface);
272 return IXMLDocument_Release((IXMLDocument *)this);
275 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
276 IPersistStream *iface, CLSID *classid)
278 TRACE("(%p,%p): stub!\n", iface, classid);
283 *classid = CLSID_DOMDocument2;
288 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
289 IPersistStream *iface)
291 domdoc *This = impl_from_IPersistStream(iface);
293 FIXME("(%p->%p): stub!\n", iface, This);
298 static HRESULT WINAPI xmldoc_IPersistStream_Load(
299 IPersistStream *iface, LPSTREAM pStm)
301 domdoc *This = impl_from_IPersistStream(iface);
304 DWORD read, written, len;
307 xmlDocPtr xmldoc = NULL;
309 TRACE("(%p, %p)\n", iface, pStm);
314 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
320 IStream_Read(pStm, buf, sizeof(buf), &read);
321 hr = IStream_Write(This->stream, buf, read, &written);
322 } while(SUCCEEDED(hr) && written != 0 && read != 0);
326 ERR("Failed to copy stream\n");
330 hr = GetHGlobalFromStream(This->stream, &hglobal);
334 len = GlobalSize(hglobal);
335 ptr = GlobalLock(hglobal);
337 xmldoc = parse_xml(ptr, len);
338 GlobalUnlock(hglobal);
342 ERR("Failed to parse xml\n");
346 xmldoc->_private = create_priv();
348 return attach_xmldoc( This->node, xmldoc );
351 static HRESULT WINAPI xmldoc_IPersistStream_Save(
352 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
354 domdoc *This = impl_from_IPersistStream(iface);
358 TRACE("(%p, %p, %d)\n", iface, pStm, fClearDirty);
360 hr = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(This->node), &xmlString );
364 DWORD len = strlenW(xmlString) * sizeof(WCHAR);
366 hr = IStream_Write( pStm, xmlString, len, &count );
368 SysFreeString(xmlString);
371 TRACE("ret 0x%08x\n", hr);
376 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
377 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
379 TRACE("(%p, %p): stub!\n", iface, pcbSize);
383 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
385 xmldoc_IPersistStream_QueryInterface,
386 xmldoc_IPersistStream_AddRef,
387 xmldoc_IPersistStream_Release,
388 xmldoc_IPersistStream_GetClassID,
389 xmldoc_IPersistStream_IsDirty,
390 xmldoc_IPersistStream_Load,
391 xmldoc_IPersistStream_Save,
392 xmldoc_IPersistStream_GetSizeMax,
395 /* ISupportErrorInfo interface */
396 static HRESULT WINAPI support_error_QueryInterface(
397 ISupportErrorInfo *iface,
398 REFIID riid, void** ppvObj )
400 domdoc *This = impl_from_ISupportErrorInfo(iface);
401 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
404 static ULONG WINAPI support_error_AddRef(
405 ISupportErrorInfo *iface )
407 domdoc *This = impl_from_ISupportErrorInfo(iface);
408 return IXMLDocument_AddRef((IXMLDocument *)This);
411 static ULONG WINAPI support_error_Release(
412 ISupportErrorInfo *iface )
414 domdoc *This = impl_from_ISupportErrorInfo(iface);
415 return IXMLDocument_Release((IXMLDocument *)This);
418 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
419 ISupportErrorInfo *iface,
422 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
426 static const struct ISupportErrorInfoVtbl support_error_vtbl =
428 support_error_QueryInterface,
429 support_error_AddRef,
430 support_error_Release,
431 support_error_InterfaceSupportsErrorInfo
434 /* IXMLDOMDocument2 interface */
435 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
437 domdoc *This = impl_from_IXMLDOMDocument2( iface );
439 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
443 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
444 IsEqualGUID( riid, &IID_IDispatch ) ||
445 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
446 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
450 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
452 *ppvObject = IXMLDOMNode_from_impl(This->node);
454 else if (IsEqualGUID(&IID_IPersistStream, riid))
456 *ppvObject = &(This->lpvtblIPersistStream);
458 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
460 *ppvObject = &(This->lpvtblIObjectWithSite);
462 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
464 *ppvObject = &This->lpvtblISupportErrorInfo;
466 else if(dispex_query_interface(&This->node->dispex, riid, ppvObject))
468 return *ppvObject ? S_OK : E_NOINTERFACE;
470 else if(IsEqualGUID(&IID_IRunnableObject, riid))
472 TRACE("IID_IRunnableObject not supported returning NULL\n");
473 return E_NOINTERFACE;
477 FIXME("interface %s not implemented\n", debugstr_guid(riid));
478 return E_NOINTERFACE;
481 IUnknown_AddRef((IUnknown*)*ppvObject);
487 static ULONG WINAPI domdoc_AddRef(
488 IXMLDOMDocument2 *iface )
490 domdoc *This = impl_from_IXMLDOMDocument2( iface );
491 TRACE("%p\n", This );
492 return InterlockedIncrement( &This->ref );
496 static ULONG WINAPI domdoc_Release(
497 IXMLDOMDocument2 *iface )
499 domdoc *This = impl_from_IXMLDOMDocument2( iface );
502 TRACE("%p\n", This );
504 ref = InterlockedDecrement( &This->ref );
508 detach_bsc(This->bsc);
511 IUnknown_Release( This->site );
512 destroy_xmlnode(This->node);
513 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
514 if (This->stream) IStream_Release(This->stream);
515 HeapFree( GetProcessHeap(), 0, This );
521 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
523 domdoc *This = impl_from_IXMLDOMDocument2( iface );
525 TRACE("(%p)->(%p)\n", This, pctinfo);
532 static HRESULT WINAPI domdoc_GetTypeInfo(
533 IXMLDOMDocument2 *iface,
534 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
536 domdoc *This = impl_from_IXMLDOMDocument2( iface );
539 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
541 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
546 static HRESULT WINAPI domdoc_GetIDsOfNames(
547 IXMLDOMDocument2 *iface,
554 domdoc *This = impl_from_IXMLDOMDocument2( iface );
558 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
561 if(!rgszNames || cNames == 0 || !rgDispId)
564 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
567 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
568 ITypeInfo_Release(typeinfo);
575 static HRESULT WINAPI domdoc_Invoke(
576 IXMLDOMDocument2 *iface,
581 DISPPARAMS* pDispParams,
583 EXCEPINFO* pExcepInfo,
586 domdoc *This = impl_from_IXMLDOMDocument2( iface );
590 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
591 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
593 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
596 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
597 pVarResult, pExcepInfo, puArgErr);
598 ITypeInfo_Release(typeinfo);
605 static HRESULT WINAPI domdoc_get_nodeName(
606 IXMLDOMDocument2 *iface,
609 domdoc *This = impl_from_IXMLDOMDocument2( iface );
610 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(This->node), name );
614 static HRESULT WINAPI domdoc_get_nodeValue(
615 IXMLDOMDocument2 *iface,
618 domdoc *This = impl_from_IXMLDOMDocument2( iface );
619 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(This->node), value );
623 static HRESULT WINAPI domdoc_put_nodeValue(
624 IXMLDOMDocument2 *iface,
627 domdoc *This = impl_from_IXMLDOMDocument2( iface );
628 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(This->node), value );
632 static HRESULT WINAPI domdoc_get_nodeType(
633 IXMLDOMDocument2 *iface,
636 domdoc *This = impl_from_IXMLDOMDocument2( iface );
637 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(This->node), type );
641 static HRESULT WINAPI domdoc_get_parentNode(
642 IXMLDOMDocument2 *iface,
643 IXMLDOMNode** parent )
645 domdoc *This = impl_from_IXMLDOMDocument2( iface );
646 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(This->node), parent );
650 static HRESULT WINAPI domdoc_get_childNodes(
651 IXMLDOMDocument2 *iface,
652 IXMLDOMNodeList** childList )
654 domdoc *This = impl_from_IXMLDOMDocument2( iface );
655 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(This->node), childList );
659 static HRESULT WINAPI domdoc_get_firstChild(
660 IXMLDOMDocument2 *iface,
661 IXMLDOMNode** firstChild )
663 domdoc *This = impl_from_IXMLDOMDocument2( iface );
664 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(This->node), firstChild );
668 static HRESULT WINAPI domdoc_get_lastChild(
669 IXMLDOMDocument2 *iface,
670 IXMLDOMNode** lastChild )
672 domdoc *This = impl_from_IXMLDOMDocument2( iface );
673 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(This->node), lastChild );
677 static HRESULT WINAPI domdoc_get_previousSibling(
678 IXMLDOMDocument2 *iface,
679 IXMLDOMNode** previousSibling )
681 domdoc *This = impl_from_IXMLDOMDocument2( iface );
682 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(This->node), previousSibling );
686 static HRESULT WINAPI domdoc_get_nextSibling(
687 IXMLDOMDocument2 *iface,
688 IXMLDOMNode** nextSibling )
690 domdoc *This = impl_from_IXMLDOMDocument2( iface );
691 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(This->node), nextSibling );
695 static HRESULT WINAPI domdoc_get_attributes(
696 IXMLDOMDocument2 *iface,
697 IXMLDOMNamedNodeMap** attributeMap )
699 domdoc *This = impl_from_IXMLDOMDocument2( iface );
700 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(This->node), attributeMap );
704 static HRESULT WINAPI domdoc_insertBefore(
705 IXMLDOMDocument2 *iface,
706 IXMLDOMNode* newChild,
708 IXMLDOMNode** outNewChild )
710 domdoc *This = impl_from_IXMLDOMDocument2( iface );
711 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(This->node), newChild, refChild, outNewChild );
715 static HRESULT WINAPI domdoc_replaceChild(
716 IXMLDOMDocument2 *iface,
717 IXMLDOMNode* newChild,
718 IXMLDOMNode* oldChild,
719 IXMLDOMNode** outOldChild)
721 domdoc *This = impl_from_IXMLDOMDocument2( iface );
722 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(This->node), newChild, oldChild, outOldChild );
726 static HRESULT WINAPI domdoc_removeChild(
727 IXMLDOMDocument2 *iface,
728 IXMLDOMNode* childNode,
729 IXMLDOMNode** oldChild)
731 domdoc *This = impl_from_IXMLDOMDocument2( iface );
732 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(This->node), childNode, oldChild );
736 static HRESULT WINAPI domdoc_appendChild(
737 IXMLDOMDocument2 *iface,
738 IXMLDOMNode* newChild,
739 IXMLDOMNode** outNewChild)
741 domdoc *This = impl_from_IXMLDOMDocument2( iface );
742 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(This->node), newChild, outNewChild );
746 static HRESULT WINAPI domdoc_hasChildNodes(
747 IXMLDOMDocument2 *iface,
748 VARIANT_BOOL* hasChild)
750 domdoc *This = impl_from_IXMLDOMDocument2( iface );
751 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(This->node), hasChild );
755 static HRESULT WINAPI domdoc_get_ownerDocument(
756 IXMLDOMDocument2 *iface,
757 IXMLDOMDocument** DOMDocument)
759 domdoc *This = impl_from_IXMLDOMDocument2( iface );
760 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(This->node), DOMDocument );
764 static HRESULT WINAPI domdoc_cloneNode(
765 IXMLDOMDocument2 *iface,
767 IXMLDOMNode** cloneRoot)
769 domdoc *This = impl_from_IXMLDOMDocument2( iface );
770 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(This->node), deep, cloneRoot );
774 static HRESULT WINAPI domdoc_get_nodeTypeString(
775 IXMLDOMDocument2 *iface,
778 domdoc *This = impl_from_IXMLDOMDocument2( iface );
779 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(This->node), nodeType );
783 static HRESULT WINAPI domdoc_get_text(
784 IXMLDOMDocument2 *iface,
787 domdoc *This = impl_from_IXMLDOMDocument2( iface );
788 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(This->node), text );
792 static HRESULT WINAPI domdoc_put_text(
793 IXMLDOMDocument2 *iface,
796 domdoc *This = impl_from_IXMLDOMDocument2( iface );
797 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(This->node), text );
801 static HRESULT WINAPI domdoc_get_specified(
802 IXMLDOMDocument2 *iface,
803 VARIANT_BOOL* isSpecified )
805 domdoc *This = impl_from_IXMLDOMDocument2( iface );
806 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(This->node), isSpecified );
810 static HRESULT WINAPI domdoc_get_definition(
811 IXMLDOMDocument2 *iface,
812 IXMLDOMNode** definitionNode )
814 domdoc *This = impl_from_IXMLDOMDocument2( iface );
815 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(This->node), definitionNode );
819 static HRESULT WINAPI domdoc_get_nodeTypedValue(
820 IXMLDOMDocument2 *iface,
821 VARIANT* typedValue )
823 domdoc *This = impl_from_IXMLDOMDocument2( iface );
824 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(This->node), typedValue );
827 static HRESULT WINAPI domdoc_put_nodeTypedValue(
828 IXMLDOMDocument2 *iface,
831 domdoc *This = impl_from_IXMLDOMDocument2( iface );
832 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(This->node), typedValue );
836 static HRESULT WINAPI domdoc_get_dataType(
837 IXMLDOMDocument2 *iface,
838 VARIANT* dataTypeName )
840 domdoc *This = impl_from_IXMLDOMDocument2( iface );
841 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(This->node), dataTypeName );
845 static HRESULT WINAPI domdoc_put_dataType(
846 IXMLDOMDocument2 *iface,
849 domdoc *This = impl_from_IXMLDOMDocument2( iface );
850 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(This->node), dataTypeName );
854 static HRESULT WINAPI domdoc_get_xml(
855 IXMLDOMDocument2 *iface,
858 domdoc *This = impl_from_IXMLDOMDocument2( iface );
859 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(This->node), xmlString );
863 static HRESULT WINAPI domdoc_transformNode(
864 IXMLDOMDocument2 *iface,
865 IXMLDOMNode* styleSheet,
868 domdoc *This = impl_from_IXMLDOMDocument2( iface );
869 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(This->node), styleSheet, xmlString );
873 static HRESULT WINAPI domdoc_selectNodes(
874 IXMLDOMDocument2 *iface,
876 IXMLDOMNodeList** resultList )
878 domdoc *This = impl_from_IXMLDOMDocument2( iface );
879 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(This->node), queryString, resultList );
883 static HRESULT WINAPI domdoc_selectSingleNode(
884 IXMLDOMDocument2 *iface,
886 IXMLDOMNode** resultNode )
888 domdoc *This = impl_from_IXMLDOMDocument2( iface );
889 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(This->node), queryString, resultNode );
893 static HRESULT WINAPI domdoc_get_parsed(
894 IXMLDOMDocument2 *iface,
895 VARIANT_BOOL* isParsed )
897 domdoc *This = impl_from_IXMLDOMDocument2( iface );
898 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(This->node), isParsed );
902 static HRESULT WINAPI domdoc_get_namespaceURI(
903 IXMLDOMDocument2 *iface,
906 domdoc *This = impl_from_IXMLDOMDocument2( iface );
907 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(This->node), namespaceURI );
911 static HRESULT WINAPI domdoc_get_prefix(
912 IXMLDOMDocument2 *iface,
915 domdoc *This = impl_from_IXMLDOMDocument2( iface );
916 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(This->node), prefixString );
920 static HRESULT WINAPI domdoc_get_baseName(
921 IXMLDOMDocument2 *iface,
924 domdoc *This = impl_from_IXMLDOMDocument2( iface );
925 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(This->node), nameString );
929 static HRESULT WINAPI domdoc_transformNodeToObject(
930 IXMLDOMDocument2 *iface,
931 IXMLDOMNode* stylesheet,
932 VARIANT outputObject)
934 domdoc *This = impl_from_IXMLDOMDocument2( iface );
935 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(This->node), stylesheet, outputObject );
939 static HRESULT WINAPI domdoc_get_doctype(
940 IXMLDOMDocument2 *iface,
941 IXMLDOMDocumentType** documentType )
948 static HRESULT WINAPI domdoc_get_implementation(
949 IXMLDOMDocument2 *iface,
950 IXMLDOMImplementation** impl )
955 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
960 static HRESULT WINAPI domdoc_get_documentElement(
961 IXMLDOMDocument2 *iface,
962 IXMLDOMElement** DOMElement )
964 domdoc *This = impl_from_IXMLDOMDocument2( iface );
965 xmlDocPtr xmldoc = NULL;
966 xmlNodePtr root = NULL;
967 IXMLDOMNode *element_node;
970 TRACE("%p %p\n", This, This->node);
977 xmldoc = get_doc( This );
979 root = xmlDocGetRootElement( xmldoc );
983 element_node = create_node( root );
984 if(!element_node) return S_FALSE;
986 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
987 IXMLDOMNode_Release(element_node);
993 static HRESULT WINAPI domdoc_put_documentElement(
994 IXMLDOMDocument2 *iface,
995 IXMLDOMElement* DOMElement )
997 domdoc *This = impl_from_IXMLDOMDocument2( iface );
998 IXMLDOMNode *elementNode;
1003 TRACE("(%p)->(%p)\n", This, DOMElement);
1005 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1009 xmlNode = impl_from_IXMLDOMNode( elementNode );
1011 if(!xmlNode->node->parent)
1012 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1013 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1015 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1016 IXMLDOMNode_Release( elementNode );
1019 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1025 static HRESULT WINAPI domdoc_createElement(
1026 IXMLDOMDocument2 *iface,
1028 IXMLDOMElement** element )
1031 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1036 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1038 xml_name = xmlChar_from_wchar(tagname);
1039 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1040 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1042 TRACE("created xmlptr %p\n", xmlnode);
1043 elem_unk = create_element(xmlnode);
1044 HeapFree(GetProcessHeap(), 0, xml_name);
1046 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1047 IUnknown_Release(elem_unk);
1048 TRACE("returning %p\n", *element);
1053 static HRESULT WINAPI domdoc_createDocumentFragment(
1054 IXMLDOMDocument2 *iface,
1055 IXMLDOMDocumentFragment** docFrag )
1057 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1060 TRACE("%p\n", iface);
1063 return E_INVALIDARG;
1067 xmlnode = xmlNewDocFragment(get_doc( This ) );
1072 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1073 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1079 static HRESULT WINAPI domdoc_createTextNode(
1080 IXMLDOMDocument2 *iface,
1082 IXMLDOMText** text )
1084 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1086 xmlChar *xml_content;
1088 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1091 return E_INVALIDARG;
1095 xml_content = xmlChar_from_wchar(data);
1096 xmlnode = xmlNewText(xml_content);
1097 HeapFree(GetProcessHeap(), 0, xml_content);
1102 xmlnode->doc = get_doc( This );
1103 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1105 *text = (IXMLDOMText*)create_text(xmlnode);
1111 static HRESULT WINAPI domdoc_createComment(
1112 IXMLDOMDocument2 *iface,
1114 IXMLDOMComment** comment )
1116 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1118 xmlChar *xml_content;
1120 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1123 return E_INVALIDARG;
1127 xml_content = xmlChar_from_wchar(data);
1128 xmlnode = xmlNewComment(xml_content);
1129 HeapFree(GetProcessHeap(), 0, xml_content);
1134 xmlnode->doc = get_doc( This );
1135 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1137 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1143 static HRESULT WINAPI domdoc_createCDATASection(
1144 IXMLDOMDocument2 *iface,
1146 IXMLDOMCDATASection** cdata )
1148 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1150 xmlChar *xml_content;
1152 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1155 return E_INVALIDARG;
1159 xml_content = xmlChar_from_wchar(data);
1160 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1161 HeapFree(GetProcessHeap(), 0, xml_content);
1166 xmlnode->doc = get_doc( This );
1167 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1169 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1175 static HRESULT WINAPI domdoc_createProcessingInstruction(
1176 IXMLDOMDocument2 *iface,
1179 IXMLDOMProcessingInstruction** pi )
1181 #ifdef HAVE_XMLNEWDOCPI
1183 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1184 xmlChar *xml_target, *xml_content;
1186 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1189 return E_INVALIDARG;
1191 if(!target || lstrlenW(target) == 0)
1194 xml_target = xmlChar_from_wchar(target);
1195 xml_content = xmlChar_from_wchar(data);
1197 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1198 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1199 TRACE("created xmlptr %p\n", xmlnode);
1200 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1202 HeapFree(GetProcessHeap(), 0, xml_content);
1203 HeapFree(GetProcessHeap(), 0, xml_target);
1207 FIXME("Libxml 2.6.15 or greater required.\n");
1213 static HRESULT WINAPI domdoc_createAttribute(
1214 IXMLDOMDocument2 *iface,
1216 IXMLDOMAttribute** attribute )
1218 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1222 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1225 return E_INVALIDARG;
1229 xml_name = xmlChar_from_wchar(name);
1230 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1231 HeapFree(GetProcessHeap(), 0, xml_name);
1236 xmlnode->doc = get_doc( This );
1237 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1239 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1245 static HRESULT WINAPI domdoc_createEntityReference(
1246 IXMLDOMDocument2 *iface,
1248 IXMLDOMEntityReference** entityRef )
1250 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1254 TRACE("%p\n", iface);
1257 return E_INVALIDARG;
1261 xml_name = xmlChar_from_wchar(name);
1262 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1263 HeapFree(GetProcessHeap(), 0, xml_name);
1268 xmlnode->doc = get_doc( This );
1269 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1271 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1277 static HRESULT WINAPI domdoc_getElementsByTagName(
1278 IXMLDOMDocument2 *iface,
1280 IXMLDOMNodeList** resultList )
1282 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1285 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1287 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1288 szPattern[0] = szPattern[1] = '/';
1289 lstrcpyW(szPattern + 2, tagName);
1291 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1292 HeapFree(GetProcessHeap(), 0, szPattern);
1297 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1303 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1305 return E_INVALIDARG;
1312 static HRESULT WINAPI domdoc_createNode(
1313 IXMLDOMDocument2 *iface,
1317 IXMLDOMNode** node )
1319 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1320 DOMNodeType node_type;
1321 xmlNodePtr xmlnode = NULL;
1325 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1327 if(namespaceURI && namespaceURI[0])
1328 FIXME("nodes with namespaces currently not supported.\n");
1330 hr = get_node_type(Type, &node_type);
1334 TRACE("node_type %d\n", node_type);
1336 xml_name = xmlChar_from_wchar(name);
1341 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1342 *node = create_node(xmlnode);
1343 TRACE("created %p\n", xmlnode);
1345 case NODE_ATTRIBUTE:
1346 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1349 xmlnode->doc = get_doc( This );
1351 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1354 TRACE("created %p\n", xmlnode);
1358 FIXME("unhandled node type %d\n", node_type);
1362 HeapFree(GetProcessHeap(), 0, xml_name);
1364 if(xmlnode && *node)
1366 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1373 static HRESULT WINAPI domdoc_nodeFromID(
1374 IXMLDOMDocument2 *iface,
1376 IXMLDOMNode** node )
1382 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1387 xmldoc = doparse( ptr, len );
1389 xmldoc->_private = create_priv();
1390 return attach_xmldoc(This->node, xmldoc);
1396 static HRESULT doread( domdoc *This, LPWSTR filename )
1401 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1406 detach_bsc(This->bsc);
1412 static HRESULT WINAPI domdoc_load(
1413 IXMLDOMDocument2 *iface,
1415 VARIANT_BOOL* isSuccessful )
1417 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1418 LPWSTR filename = NULL;
1419 HRESULT hr = S_FALSE;
1420 IXMLDOMDocument2 *pNewDoc = NULL;
1421 IStream *pStream = NULL;
1424 TRACE("type %d\n", V_VT(&xmlSource) );
1426 *isSuccessful = VARIANT_FALSE;
1428 assert( This->node );
1430 switch( V_VT(&xmlSource) )
1433 filename = V_BSTR(&xmlSource);
1436 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1441 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1442 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1443 hr = attach_xmldoc(This->node, xmldoc);
1446 *isSuccessful = VARIANT_TRUE;
1451 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1454 IPersistStream *pDocStream;
1455 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1458 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1459 IStream_Release(pStream);
1462 *isSuccessful = VARIANT_TRUE;
1464 TRACE("Using ID_IStream to load Document\n");
1469 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1474 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1479 /* ISequentialStream */
1480 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1484 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1487 TRACE("filename (%s)\n", debugstr_w(filename));
1491 hr = doread( This, filename );
1494 This->error = E_FAIL;
1497 hr = This->error = S_OK;
1498 *isSuccessful = VARIANT_TRUE;
1502 if(!filename || FAILED(hr)) {
1503 xmldoc = xmlNewDoc(NULL);
1504 xmldoc->_private = create_priv();
1505 hr = attach_xmldoc(This->node, xmldoc);
1510 TRACE("ret (%d)\n", hr);
1516 static HRESULT WINAPI domdoc_get_readyState(
1517 IXMLDOMDocument2 *iface,
1525 static HRESULT WINAPI domdoc_get_parseError(
1526 IXMLDOMDocument2 *iface,
1527 IXMLDOMParseError** errorObj )
1529 BSTR error_string = NULL;
1530 static const WCHAR err[] = {'e','r','r','o','r',0};
1531 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1533 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1536 error_string = SysAllocString(err);
1538 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1539 if(!*errorObj) return E_OUTOFMEMORY;
1544 static HRESULT WINAPI domdoc_get_url(
1545 IXMLDOMDocument2 *iface,
1553 static HRESULT WINAPI domdoc_get_async(
1554 IXMLDOMDocument2 *iface,
1555 VARIANT_BOOL* isAsync )
1557 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1559 TRACE("%p <- %d\n", isAsync, This->async);
1560 *isAsync = This->async;
1565 static HRESULT WINAPI domdoc_put_async(
1566 IXMLDOMDocument2 *iface,
1567 VARIANT_BOOL isAsync )
1569 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1571 TRACE("%d\n", isAsync);
1572 This->async = isAsync;
1577 static HRESULT WINAPI domdoc_abort(
1578 IXMLDOMDocument2 *iface )
1585 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1587 UINT len, blen = SysStringLen( bstr );
1590 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1591 str = HeapAlloc( GetProcessHeap(), 0, len );
1594 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1600 static HRESULT WINAPI domdoc_loadXML(
1601 IXMLDOMDocument2 *iface,
1603 VARIANT_BOOL* isSuccessful )
1605 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1606 xmlDocPtr xmldoc = NULL;
1609 HRESULT hr = S_FALSE, hr2;
1611 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1613 assert ( This->node );
1617 *isSuccessful = VARIANT_FALSE;
1619 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1621 xmldoc = doparse( str, len );
1622 HeapFree( GetProcessHeap(), 0, str );
1624 This->error = E_FAIL;
1627 hr = This->error = S_OK;
1628 *isSuccessful = VARIANT_TRUE;
1633 xmldoc = xmlNewDoc(NULL);
1635 xmldoc->_private = create_priv();
1636 hr2 = attach_xmldoc( This->node, xmldoc );
1644 static HRESULT WINAPI domdoc_save(
1645 IXMLDOMDocument2 *iface,
1646 VARIANT destination )
1648 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1655 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1656 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1658 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1660 FIXME("Unhandled vt %d\n", V_VT(&destination));
1664 if(V_VT(&destination) == VT_UNKNOWN)
1666 IUnknown *pUnk = V_UNKNOWN(&destination);
1667 IXMLDOMDocument *pDocument;
1669 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1673 VARIANT_BOOL bSuccessful;
1675 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1678 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1680 SysFreeString(bXML);
1683 IXMLDOMDocument_Release(pDocument);
1686 TRACE("ret %d\n", ret);
1691 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1692 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1693 if( handle == INVALID_HANDLE_VALUE )
1695 WARN("failed to create file\n");
1699 xmlDocDumpMemory(get_doc(This), &mem, &size);
1702 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1703 * MSXML adds XML declaration only for processing instruction nodes.
1704 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1707 if(size > 2 && p[0] == '<' && p[1] == '?') {
1708 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1711 while(p < mem+size && isspace(*p))
1716 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1718 WARN("write error\n");
1723 CloseHandle(handle);
1727 static HRESULT WINAPI domdoc_get_validateOnParse(
1728 IXMLDOMDocument2 *iface,
1729 VARIANT_BOOL* isValidating )
1731 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1733 TRACE("%p <- %d\n", isValidating, This->validating);
1734 *isValidating = This->validating;
1739 static HRESULT WINAPI domdoc_put_validateOnParse(
1740 IXMLDOMDocument2 *iface,
1741 VARIANT_BOOL isValidating )
1743 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1745 TRACE("%d\n", isValidating);
1746 This->validating = isValidating;
1751 static HRESULT WINAPI domdoc_get_resolveExternals(
1752 IXMLDOMDocument2 *iface,
1753 VARIANT_BOOL* isResolving )
1755 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1757 TRACE("%p <- %d\n", isResolving, This->resolving);
1758 *isResolving = This->resolving;
1763 static HRESULT WINAPI domdoc_put_resolveExternals(
1764 IXMLDOMDocument2 *iface,
1765 VARIANT_BOOL isResolving )
1767 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1769 TRACE("%d\n", isResolving);
1770 This->resolving = isResolving;
1775 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1776 IXMLDOMDocument2 *iface,
1777 VARIANT_BOOL* isPreserving )
1779 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1781 TRACE("%p <- %d\n", isPreserving, This->preserving);
1782 *isPreserving = This->preserving;
1787 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1788 IXMLDOMDocument2 *iface,
1789 VARIANT_BOOL isPreserving )
1791 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1793 TRACE("%d\n", isPreserving);
1794 This->preserving = isPreserving;
1799 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1800 IXMLDOMDocument2 *iface,
1801 VARIANT readyStateChangeSink )
1808 static HRESULT WINAPI domdoc_put_onDataAvailable(
1809 IXMLDOMDocument2 *iface,
1810 VARIANT onDataAvailableSink )
1816 static HRESULT WINAPI domdoc_put_onTransformNode(
1817 IXMLDOMDocument2 *iface,
1818 VARIANT onTransformNodeSink )
1824 static HRESULT WINAPI domdoc_get_namespaces(
1825 IXMLDOMDocument2* iface,
1826 IXMLDOMSchemaCollection** schemaCollection )
1832 static HRESULT WINAPI domdoc_get_schemas(
1833 IXMLDOMDocument2* iface,
1836 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1837 HRESULT hr = S_FALSE;
1838 IXMLDOMSchemaCollection *cur_schema = This->schema;
1840 TRACE("(%p)->(%p)\n", This, var1);
1842 VariantInit(var1); /* Test shows we don't call VariantClear here */
1843 V_VT(var1) = VT_NULL;
1847 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1849 V_VT(var1) = VT_DISPATCH;
1854 static HRESULT WINAPI domdoc_putref_schemas(
1855 IXMLDOMDocument2* iface,
1858 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1859 HRESULT hr = E_FAIL;
1860 IXMLDOMSchemaCollection *new_schema = NULL;
1862 FIXME("(%p): semi-stub\n", This);
1866 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1870 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1879 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1884 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1885 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1891 static HRESULT WINAPI domdoc_validate(
1892 IXMLDOMDocument2* iface,
1893 IXMLDOMParseError** err)
1899 static HRESULT WINAPI domdoc_setProperty(
1900 IXMLDOMDocument2* iface,
1904 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1906 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1912 V_VT(&varStr) = VT_EMPTY;
1913 if (V_VT(&var) != VT_BSTR)
1915 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1917 bstr = V_BSTR(&varStr);
1920 bstr = V_BSTR(&var);
1923 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1924 This->bUseXPath = TRUE;
1925 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1926 This->bUseXPath = FALSE;
1930 VariantClear(&varStr);
1934 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1938 static HRESULT WINAPI domdoc_getProperty(
1939 IXMLDOMDocument2* iface,
1943 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1946 return E_INVALIDARG;
1947 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1949 V_VT(var) = VT_BSTR;
1950 if (This->bUseXPath)
1951 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1953 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1957 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1961 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1963 domdoc_QueryInterface,
1966 domdoc_GetTypeInfoCount,
1968 domdoc_GetIDsOfNames,
1970 domdoc_get_nodeName,
1971 domdoc_get_nodeValue,
1972 domdoc_put_nodeValue,
1973 domdoc_get_nodeType,
1974 domdoc_get_parentNode,
1975 domdoc_get_childNodes,
1976 domdoc_get_firstChild,
1977 domdoc_get_lastChild,
1978 domdoc_get_previousSibling,
1979 domdoc_get_nextSibling,
1980 domdoc_get_attributes,
1981 domdoc_insertBefore,
1982 domdoc_replaceChild,
1985 domdoc_hasChildNodes,
1986 domdoc_get_ownerDocument,
1988 domdoc_get_nodeTypeString,
1991 domdoc_get_specified,
1992 domdoc_get_definition,
1993 domdoc_get_nodeTypedValue,
1994 domdoc_put_nodeTypedValue,
1995 domdoc_get_dataType,
1996 domdoc_put_dataType,
1998 domdoc_transformNode,
2000 domdoc_selectSingleNode,
2002 domdoc_get_namespaceURI,
2004 domdoc_get_baseName,
2005 domdoc_transformNodeToObject,
2007 domdoc_get_implementation,
2008 domdoc_get_documentElement,
2009 domdoc_put_documentElement,
2010 domdoc_createElement,
2011 domdoc_createDocumentFragment,
2012 domdoc_createTextNode,
2013 domdoc_createComment,
2014 domdoc_createCDATASection,
2015 domdoc_createProcessingInstruction,
2016 domdoc_createAttribute,
2017 domdoc_createEntityReference,
2018 domdoc_getElementsByTagName,
2022 domdoc_get_readyState,
2023 domdoc_get_parseError,
2030 domdoc_get_validateOnParse,
2031 domdoc_put_validateOnParse,
2032 domdoc_get_resolveExternals,
2033 domdoc_put_resolveExternals,
2034 domdoc_get_preserveWhiteSpace,
2035 domdoc_put_preserveWhiteSpace,
2036 domdoc_put_onReadyStateChange,
2037 domdoc_put_onDataAvailable,
2038 domdoc_put_onTransformNode,
2039 domdoc_get_namespaces,
2041 domdoc_putref_schemas,
2047 /* xmldoc implementation of IObjectWithSite */
2048 static HRESULT WINAPI
2049 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2051 domdoc *This = impl_from_IObjectWithSite(iface);
2052 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2056 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2058 domdoc *This = impl_from_IObjectWithSite(iface);
2059 return IXMLDocument_AddRef((IXMLDocument *)This);
2063 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2065 domdoc *This = impl_from_IObjectWithSite(iface);
2066 return IXMLDocument_Release((IXMLDocument *)This);
2069 static HRESULT WINAPI
2070 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2072 domdoc *This = impl_from_IObjectWithSite(iface);
2074 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2079 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2082 static HRESULT WINAPI
2083 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2085 domdoc *This = impl_from_IObjectWithSite(iface);
2087 TRACE("%p %p\n", iface, punk);
2093 IUnknown_Release( This->site );
2101 IUnknown_AddRef( punk );
2104 IUnknown_Release( This->site );
2111 static const IObjectWithSiteVtbl domdocObjectSite =
2113 xmldoc_ObjectWithSite_QueryInterface,
2114 xmldoc_ObjectWithSite_AddRef,
2115 xmldoc_ObjectWithSite_Release,
2120 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2122 domdoc *This = impl_from_IObjectSafety(iface);
2123 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2126 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2128 domdoc *This = impl_from_IObjectSafety(iface);
2129 return IXMLDocument_AddRef((IXMLDocument *)This);
2132 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2134 domdoc *This = impl_from_IObjectSafety(iface);
2135 return IXMLDocument_Release((IXMLDocument *)This);
2138 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2140 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2141 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2143 domdoc *This = impl_from_IObjectSafety(iface);
2145 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2147 if(!pdwSupportedOptions || !pdwEnabledOptions)
2150 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2151 *pdwEnabledOptions = This->safeopt;
2156 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2157 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2159 domdoc *This = impl_from_IObjectSafety(iface);
2161 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2163 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2166 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2170 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2171 xmldoc_Safety_QueryInterface,
2172 xmldoc_Safety_AddRef,
2173 xmldoc_Safety_Release,
2174 xmldoc_Safety_GetInterfaceSafetyOptions,
2175 xmldoc_Safety_SetInterfaceSafetyOptions
2179 static const tid_t domdoc_iface_tids[] = {
2181 IXMLDOMDocument_tid,
2182 IXMLDOMDocument2_tid,
2185 static dispex_static_data_t domdoc_dispex = {
2187 IXMLDOMDocument2_tid,
2192 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2196 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2198 return E_OUTOFMEMORY;
2200 doc->lpVtbl = &domdoc_vtbl;
2201 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2202 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2203 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2204 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2206 doc->async = VARIANT_TRUE;
2207 doc->validating = 0;
2209 doc->preserving = 0;
2210 doc->bUseXPath = FALSE;
2218 doc->node = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex );
2221 HeapFree(GetProcessHeap(), 0, doc);
2225 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2227 TRACE("returning iface %p\n", *document);
2231 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2236 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2238 xmldoc = xmlNewDoc(NULL);
2240 return E_OUTOFMEMORY;
2242 xmldoc->_private = create_priv();
2244 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2251 IUnknown* create_domdoc( xmlNodePtr document )
2256 TRACE("(%p)\n", document);
2258 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2267 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2269 MESSAGE("This program tried to use a DOMDocument object, but\n"
2270 "libxml2 support was not present at compile time.\n");