2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 #include "msxml_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
50 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
51 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
52 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
54 typedef struct _domdoc
56 const struct IXMLDOMDocument2Vtbl *lpVtbl;
57 const struct IPersistStreamVtbl *lpvtblIPersistStream;
58 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
59 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
60 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
63 VARIANT_BOOL validating;
64 VARIANT_BOOL resolving;
65 VARIANT_BOOL preserving;
69 IXMLDOMSchemaCollection *schema;
87 In native windows, the whole lifetime management of XMLDOMNodes is
88 managed automatically using reference counts. Wine emulates that by
89 maintaining a reference count to the document that is increased for
90 each IXMLDOMNode pointer passed out for this document. If all these
91 pointers are gone, the document is unreachable and gets freed, that
92 is, all nodes in the tree of the document get freed.
94 You are able to create nodes that are associated to a document (in
95 fact, in msxml's XMLDOM model, all nodes are associated to a document),
96 but not in the tree of that document, for example using the createFoo
97 functions from IXMLDOMDocument. These nodes do not get cleaned up
98 by libxml, so we have to do it ourselves.
100 To catch these nodes, a list of "orphan nodes" is introduced.
101 It contains pointers to all roots of node trees that are
102 associated with the document without being part of the document
103 tree. All nodes with parent==NULL (except for the document root nodes)
104 should be in the orphan node list of their document. All orphan nodes
105 get freed together with the document itself.
108 typedef struct _xmldoc_priv {
113 typedef struct _orphan_entry {
118 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
120 return doc->_private;
123 static xmldoc_priv * create_priv(void)
126 priv = HeapAlloc( GetProcessHeap(), 0, sizeof (*priv) );
131 list_init( &priv->orphans );
137 static xmlDocPtr doparse( char *ptr, int len )
139 #ifdef HAVE_XMLREADMEMORY
141 * use xmlReadMemory if possible so we can suppress
142 * writing errors to stderr
144 return xmlReadMemory( ptr, len, NULL, NULL,
145 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
147 return xmlParseMemory( ptr, len );
151 LONG xmldoc_add_ref(xmlDocPtr doc)
153 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
158 LONG xmldoc_release(xmlDocPtr doc)
160 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
161 LONG ref = InterlockedDecrement(&priv->refs);
165 orphan_entry *orphan, *orphan2;
166 TRACE("freeing docptr %p\n", doc);
168 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
170 xmlFreeNode( orphan->node );
171 HeapFree( GetProcessHeap(), 0, orphan );
173 HeapFree(GetProcessHeap(), 0, doc->_private);
181 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
183 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
186 entry = HeapAlloc( GetProcessHeap(), 0, sizeof (*entry) );
188 return E_OUTOFMEMORY;
191 list_add_head( &priv->orphans, &entry->entry );
195 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
197 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
198 orphan_entry *entry, *entry2;
200 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
202 if( entry->node == node )
204 list_remove( &entry->entry );
205 HeapFree( GetProcessHeap(), 0, entry );
213 static HRESULT attach_xmldoc( IXMLDOMNode *node, xmlDocPtr xml )
215 xmlnode *This = impl_from_IXMLDOMNode( node );
218 xmldoc_release(This->node->doc);
220 This->node = (xmlNodePtr) xml;
222 xmldoc_add_ref(This->node->doc);
227 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
229 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
232 static inline xmlDocPtr get_doc( domdoc *This )
234 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
237 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
239 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
242 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
244 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
247 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
249 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
252 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
254 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
257 /************************************************************************
258 * xmldoc implementation of IPersistStream.
260 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
261 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
263 domdoc *this = impl_from_IPersistStream(iface);
264 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
267 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
268 IPersistStream *iface)
270 domdoc *this = impl_from_IPersistStream(iface);
271 return IXMLDocument_AddRef((IXMLDocument *)this);
274 static ULONG WINAPI xmldoc_IPersistStream_Release(
275 IPersistStream *iface)
277 domdoc *this = impl_from_IPersistStream(iface);
278 return IXMLDocument_Release((IXMLDocument *)this);
281 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
282 IPersistStream *iface, CLSID *classid)
284 TRACE("(%p,%p): stub!\n", iface, classid);
289 *classid = CLSID_DOMDocument2;
294 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
295 IPersistStream *iface)
297 domdoc *This = impl_from_IPersistStream(iface);
299 FIXME("(%p->%p): stub!\n", iface, This);
304 static HRESULT WINAPI xmldoc_IPersistStream_Load(
305 IPersistStream *iface, LPSTREAM pStm)
307 domdoc *This = impl_from_IPersistStream(iface);
310 DWORD read, written, len;
313 xmlDocPtr xmldoc = NULL;
315 TRACE("(%p, %p)\n", iface, pStm);
320 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
326 IStream_Read(pStm, buf, sizeof(buf), &read);
327 hr = IStream_Write(This->stream, buf, read, &written);
328 } while(SUCCEEDED(hr) && written != 0 && read != 0);
332 ERR("Failed to copy stream\n");
336 hr = GetHGlobalFromStream(This->stream, &hglobal);
340 len = GlobalSize(hglobal);
341 ptr = GlobalLock(hglobal);
343 xmldoc = parse_xml(ptr, len);
344 GlobalUnlock(hglobal);
348 ERR("Failed to parse xml\n");
352 xmldoc->_private = create_priv();
354 return attach_xmldoc( This->node, xmldoc );
357 static HRESULT WINAPI xmldoc_IPersistStream_Save(
358 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
360 domdoc *This = impl_from_IPersistStream(iface);
364 TRACE("(%p, %p, %d)\n", iface, pStm, fClearDirty);
366 hr = IXMLDOMNode_get_xml( This->node, &xmlString );
370 DWORD len = strlenW(xmlString) * sizeof(WCHAR);
372 hr = IStream_Write( pStm, xmlString, len, &count );
374 SysFreeString(xmlString);
377 TRACE("ret 0x%08x\n", hr);
382 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
383 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
385 TRACE("(%p, %p): stub!\n", iface, pcbSize);
389 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
391 xmldoc_IPersistStream_QueryInterface,
392 xmldoc_IPersistStream_AddRef,
393 xmldoc_IPersistStream_Release,
394 xmldoc_IPersistStream_GetClassID,
395 xmldoc_IPersistStream_IsDirty,
396 xmldoc_IPersistStream_Load,
397 xmldoc_IPersistStream_Save,
398 xmldoc_IPersistStream_GetSizeMax,
401 /* ISupportErrorInfo interface */
402 static HRESULT WINAPI support_error_QueryInterface(
403 ISupportErrorInfo *iface,
404 REFIID riid, void** ppvObj )
406 domdoc *This = impl_from_ISupportErrorInfo(iface);
407 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
410 static ULONG WINAPI support_error_AddRef(
411 ISupportErrorInfo *iface )
413 domdoc *This = impl_from_ISupportErrorInfo(iface);
414 return IXMLDocument_AddRef((IXMLDocument *)This);
417 static ULONG WINAPI support_error_Release(
418 ISupportErrorInfo *iface )
420 domdoc *This = impl_from_ISupportErrorInfo(iface);
421 return IXMLDocument_Release((IXMLDocument *)This);
424 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
425 ISupportErrorInfo *iface,
428 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
432 static const struct ISupportErrorInfoVtbl support_error_vtbl =
434 support_error_QueryInterface,
435 support_error_AddRef,
436 support_error_Release,
437 support_error_InterfaceSupportsErrorInfo
440 /* IXMLDOMDocument2 interface */
441 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
443 domdoc *This = impl_from_IXMLDOMDocument2( iface );
445 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
449 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
450 IsEqualGUID( riid, &IID_IDispatch ) ||
451 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
452 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
456 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
458 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
460 else if (IsEqualGUID(&IID_IPersistStream, riid))
462 *ppvObject = &(This->lpvtblIPersistStream);
464 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
466 *ppvObject = &(This->lpvtblIObjectWithSite);
468 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
470 *ppvObject = &This->lpvtblISupportErrorInfo;
472 else if(dispex_query_interface(&This->dispex, riid, ppvObject))
474 return *ppvObject ? S_OK : E_NOINTERFACE;
476 else if(IsEqualGUID(&IID_IRunnableObject, riid))
478 TRACE("IID_IRunnableObject not supported returning NULL\n");
479 return E_NOINTERFACE;
483 FIXME("interface %s not implemented\n", debugstr_guid(riid));
484 return E_NOINTERFACE;
487 IXMLDOMDocument_AddRef( iface );
493 static ULONG WINAPI domdoc_AddRef(
494 IXMLDOMDocument2 *iface )
496 domdoc *This = impl_from_IXMLDOMDocument2( iface );
497 TRACE("%p\n", This );
498 return InterlockedIncrement( &This->ref );
502 static ULONG WINAPI domdoc_Release(
503 IXMLDOMDocument2 *iface )
505 domdoc *This = impl_from_IXMLDOMDocument2( iface );
508 TRACE("%p\n", This );
510 ref = InterlockedDecrement( &This->ref );
514 detach_bsc(This->bsc);
517 IUnknown_Release( This->site );
518 IUnknown_Release( This->node_unk );
519 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
520 if (This->stream) IStream_Release(This->stream);
521 HeapFree( GetProcessHeap(), 0, This );
527 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
529 domdoc *This = impl_from_IXMLDOMDocument2( iface );
531 TRACE("(%p)->(%p)\n", This, pctinfo);
538 static HRESULT WINAPI domdoc_GetTypeInfo(
539 IXMLDOMDocument2 *iface,
540 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
542 domdoc *This = impl_from_IXMLDOMDocument2( iface );
545 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
547 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
552 static HRESULT WINAPI domdoc_GetIDsOfNames(
553 IXMLDOMDocument2 *iface,
560 domdoc *This = impl_from_IXMLDOMDocument2( iface );
564 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
567 if(!rgszNames || cNames == 0 || !rgDispId)
570 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
573 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
574 ITypeInfo_Release(typeinfo);
581 static HRESULT WINAPI domdoc_Invoke(
582 IXMLDOMDocument2 *iface,
587 DISPPARAMS* pDispParams,
589 EXCEPINFO* pExcepInfo,
592 domdoc *This = impl_from_IXMLDOMDocument2( iface );
596 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
597 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
599 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
602 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
603 pVarResult, pExcepInfo, puArgErr);
604 ITypeInfo_Release(typeinfo);
611 static HRESULT WINAPI domdoc_get_nodeName(
612 IXMLDOMDocument2 *iface,
615 domdoc *This = impl_from_IXMLDOMDocument2( iface );
616 return IXMLDOMNode_get_nodeName( This->node, name );
620 static HRESULT WINAPI domdoc_get_nodeValue(
621 IXMLDOMDocument2 *iface,
624 domdoc *This = impl_from_IXMLDOMDocument2( iface );
625 return IXMLDOMNode_get_nodeValue( This->node, value );
629 static HRESULT WINAPI domdoc_put_nodeValue(
630 IXMLDOMDocument2 *iface,
633 domdoc *This = impl_from_IXMLDOMDocument2( iface );
634 return IXMLDOMNode_put_nodeValue( This->node, value );
638 static HRESULT WINAPI domdoc_get_nodeType(
639 IXMLDOMDocument2 *iface,
642 domdoc *This = impl_from_IXMLDOMDocument2( iface );
643 return IXMLDOMNode_get_nodeType( This->node, type );
647 static HRESULT WINAPI domdoc_get_parentNode(
648 IXMLDOMDocument2 *iface,
649 IXMLDOMNode** parent )
651 domdoc *This = impl_from_IXMLDOMDocument2( iface );
652 return IXMLDOMNode_get_parentNode( This->node, parent );
656 static HRESULT WINAPI domdoc_get_childNodes(
657 IXMLDOMDocument2 *iface,
658 IXMLDOMNodeList** childList )
660 domdoc *This = impl_from_IXMLDOMDocument2( iface );
661 return IXMLDOMNode_get_childNodes( This->node, childList );
665 static HRESULT WINAPI domdoc_get_firstChild(
666 IXMLDOMDocument2 *iface,
667 IXMLDOMNode** firstChild )
669 domdoc *This = impl_from_IXMLDOMDocument2( iface );
670 return IXMLDOMNode_get_firstChild( This->node, firstChild );
674 static HRESULT WINAPI domdoc_get_lastChild(
675 IXMLDOMDocument2 *iface,
676 IXMLDOMNode** lastChild )
678 domdoc *This = impl_from_IXMLDOMDocument2( iface );
679 return IXMLDOMNode_get_lastChild( This->node, lastChild );
683 static HRESULT WINAPI domdoc_get_previousSibling(
684 IXMLDOMDocument2 *iface,
685 IXMLDOMNode** previousSibling )
687 domdoc *This = impl_from_IXMLDOMDocument2( iface );
688 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
692 static HRESULT WINAPI domdoc_get_nextSibling(
693 IXMLDOMDocument2 *iface,
694 IXMLDOMNode** nextSibling )
696 domdoc *This = impl_from_IXMLDOMDocument2( iface );
697 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
701 static HRESULT WINAPI domdoc_get_attributes(
702 IXMLDOMDocument2 *iface,
703 IXMLDOMNamedNodeMap** attributeMap )
705 domdoc *This = impl_from_IXMLDOMDocument2( iface );
706 return IXMLDOMNode_get_attributes( This->node, attributeMap );
710 static HRESULT WINAPI domdoc_insertBefore(
711 IXMLDOMDocument2 *iface,
712 IXMLDOMNode* newChild,
714 IXMLDOMNode** outNewChild )
716 domdoc *This = impl_from_IXMLDOMDocument2( iface );
717 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
721 static HRESULT WINAPI domdoc_replaceChild(
722 IXMLDOMDocument2 *iface,
723 IXMLDOMNode* newChild,
724 IXMLDOMNode* oldChild,
725 IXMLDOMNode** outOldChild)
727 domdoc *This = impl_from_IXMLDOMDocument2( iface );
728 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
732 static HRESULT WINAPI domdoc_removeChild(
733 IXMLDOMDocument2 *iface,
734 IXMLDOMNode* childNode,
735 IXMLDOMNode** oldChild)
737 domdoc *This = impl_from_IXMLDOMDocument2( iface );
738 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
742 static HRESULT WINAPI domdoc_appendChild(
743 IXMLDOMDocument2 *iface,
744 IXMLDOMNode* newChild,
745 IXMLDOMNode** outNewChild)
747 domdoc *This = impl_from_IXMLDOMDocument2( iface );
748 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
752 static HRESULT WINAPI domdoc_hasChildNodes(
753 IXMLDOMDocument2 *iface,
754 VARIANT_BOOL* hasChild)
756 domdoc *This = impl_from_IXMLDOMDocument2( iface );
757 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
761 static HRESULT WINAPI domdoc_get_ownerDocument(
762 IXMLDOMDocument2 *iface,
763 IXMLDOMDocument** DOMDocument)
765 domdoc *This = impl_from_IXMLDOMDocument2( iface );
766 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
770 static HRESULT WINAPI domdoc_cloneNode(
771 IXMLDOMDocument2 *iface,
773 IXMLDOMNode** cloneRoot)
775 domdoc *This = impl_from_IXMLDOMDocument2( iface );
776 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
780 static HRESULT WINAPI domdoc_get_nodeTypeString(
781 IXMLDOMDocument2 *iface,
784 domdoc *This = impl_from_IXMLDOMDocument2( iface );
785 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
789 static HRESULT WINAPI domdoc_get_text(
790 IXMLDOMDocument2 *iface,
793 domdoc *This = impl_from_IXMLDOMDocument2( iface );
794 return IXMLDOMNode_get_text( This->node, text );
798 static HRESULT WINAPI domdoc_put_text(
799 IXMLDOMDocument2 *iface,
802 domdoc *This = impl_from_IXMLDOMDocument2( iface );
803 return IXMLDOMNode_put_text( This->node, text );
807 static HRESULT WINAPI domdoc_get_specified(
808 IXMLDOMDocument2 *iface,
809 VARIANT_BOOL* isSpecified )
811 domdoc *This = impl_from_IXMLDOMDocument2( iface );
812 return IXMLDOMNode_get_specified( This->node, isSpecified );
816 static HRESULT WINAPI domdoc_get_definition(
817 IXMLDOMDocument2 *iface,
818 IXMLDOMNode** definitionNode )
820 domdoc *This = impl_from_IXMLDOMDocument2( iface );
821 return IXMLDOMNode_get_definition( This->node, definitionNode );
825 static HRESULT WINAPI domdoc_get_nodeTypedValue(
826 IXMLDOMDocument2 *iface,
827 VARIANT* typedValue )
829 domdoc *This = impl_from_IXMLDOMDocument2( iface );
830 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
833 static HRESULT WINAPI domdoc_put_nodeTypedValue(
834 IXMLDOMDocument2 *iface,
837 domdoc *This = impl_from_IXMLDOMDocument2( iface );
838 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
842 static HRESULT WINAPI domdoc_get_dataType(
843 IXMLDOMDocument2 *iface,
844 VARIANT* dataTypeName )
846 domdoc *This = impl_from_IXMLDOMDocument2( iface );
847 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
851 static HRESULT WINAPI domdoc_put_dataType(
852 IXMLDOMDocument2 *iface,
855 domdoc *This = impl_from_IXMLDOMDocument2( iface );
856 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
860 static HRESULT WINAPI domdoc_get_xml(
861 IXMLDOMDocument2 *iface,
864 domdoc *This = impl_from_IXMLDOMDocument2( iface );
865 return IXMLDOMNode_get_xml( This->node, xmlString );
869 static HRESULT WINAPI domdoc_transformNode(
870 IXMLDOMDocument2 *iface,
871 IXMLDOMNode* styleSheet,
874 domdoc *This = impl_from_IXMLDOMDocument2( iface );
875 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
879 static HRESULT WINAPI domdoc_selectNodes(
880 IXMLDOMDocument2 *iface,
882 IXMLDOMNodeList** resultList )
884 domdoc *This = impl_from_IXMLDOMDocument2( iface );
885 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
889 static HRESULT WINAPI domdoc_selectSingleNode(
890 IXMLDOMDocument2 *iface,
892 IXMLDOMNode** resultNode )
894 domdoc *This = impl_from_IXMLDOMDocument2( iface );
895 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
899 static HRESULT WINAPI domdoc_get_parsed(
900 IXMLDOMDocument2 *iface,
901 VARIANT_BOOL* isParsed )
903 domdoc *This = impl_from_IXMLDOMDocument2( iface );
904 return IXMLDOMNode_get_parsed( This->node, isParsed );
908 static HRESULT WINAPI domdoc_get_namespaceURI(
909 IXMLDOMDocument2 *iface,
912 domdoc *This = impl_from_IXMLDOMDocument2( iface );
913 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
917 static HRESULT WINAPI domdoc_get_prefix(
918 IXMLDOMDocument2 *iface,
921 domdoc *This = impl_from_IXMLDOMDocument2( iface );
922 return IXMLDOMNode_get_prefix( This->node, prefixString );
926 static HRESULT WINAPI domdoc_get_baseName(
927 IXMLDOMDocument2 *iface,
930 domdoc *This = impl_from_IXMLDOMDocument2( iface );
931 return IXMLDOMNode_get_baseName( This->node, nameString );
935 static HRESULT WINAPI domdoc_transformNodeToObject(
936 IXMLDOMDocument2 *iface,
937 IXMLDOMNode* stylesheet,
938 VARIANT outputObject)
940 domdoc *This = impl_from_IXMLDOMDocument2( iface );
941 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
945 static HRESULT WINAPI domdoc_get_doctype(
946 IXMLDOMDocument2 *iface,
947 IXMLDOMDocumentType** documentType )
954 static HRESULT WINAPI domdoc_get_implementation(
955 IXMLDOMDocument2 *iface,
956 IXMLDOMImplementation** impl )
961 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
966 static HRESULT WINAPI domdoc_get_documentElement(
967 IXMLDOMDocument2 *iface,
968 IXMLDOMElement** DOMElement )
970 domdoc *This = impl_from_IXMLDOMDocument2( iface );
971 xmlDocPtr xmldoc = NULL;
972 xmlNodePtr root = NULL;
973 IXMLDOMNode *element_node;
976 TRACE("%p %p\n", This, This->node);
983 xmldoc = get_doc( This );
985 root = xmlDocGetRootElement( xmldoc );
989 element_node = create_node( root );
990 if(!element_node) return S_FALSE;
992 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
993 IXMLDOMNode_Release(element_node);
999 static HRESULT WINAPI domdoc_put_documentElement(
1000 IXMLDOMDocument2 *iface,
1001 IXMLDOMElement* DOMElement )
1003 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1004 IXMLDOMNode *elementNode;
1009 TRACE("(%p)->(%p)\n", This, DOMElement);
1011 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1015 xmlNode = impl_from_IXMLDOMNode( elementNode );
1017 if(!xmlNode->node->parent)
1018 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1019 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1021 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1022 IXMLDOMNode_Release( elementNode );
1025 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1031 static HRESULT WINAPI domdoc_createElement(
1032 IXMLDOMDocument2 *iface,
1034 IXMLDOMElement** element )
1037 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1042 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1044 xml_name = xmlChar_from_wchar(tagname);
1045 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1046 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1048 TRACE("created xmlptr %p\n", xmlnode);
1049 elem_unk = create_element(xmlnode, NULL);
1050 HeapFree(GetProcessHeap(), 0, xml_name);
1052 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1053 IUnknown_Release(elem_unk);
1054 TRACE("returning %p\n", *element);
1059 static HRESULT WINAPI domdoc_createDocumentFragment(
1060 IXMLDOMDocument2 *iface,
1061 IXMLDOMDocumentFragment** docFrag )
1063 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1066 TRACE("%p\n", iface);
1069 return E_INVALIDARG;
1073 xmlnode = xmlNewDocFragment(get_doc( This ) );
1078 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1079 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1085 static HRESULT WINAPI domdoc_createTextNode(
1086 IXMLDOMDocument2 *iface,
1088 IXMLDOMText** text )
1090 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1092 xmlChar *xml_content;
1094 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1097 return E_INVALIDARG;
1101 xml_content = xmlChar_from_wchar(data);
1102 xmlnode = xmlNewText(xml_content);
1103 HeapFree(GetProcessHeap(), 0, xml_content);
1108 xmlnode->doc = get_doc( This );
1109 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1111 *text = (IXMLDOMText*)create_text(xmlnode);
1117 static HRESULT WINAPI domdoc_createComment(
1118 IXMLDOMDocument2 *iface,
1120 IXMLDOMComment** comment )
1122 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1124 xmlChar *xml_content;
1126 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1129 return E_INVALIDARG;
1133 xml_content = xmlChar_from_wchar(data);
1134 xmlnode = xmlNewComment(xml_content);
1135 HeapFree(GetProcessHeap(), 0, xml_content);
1140 xmlnode->doc = get_doc( This );
1141 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1143 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1149 static HRESULT WINAPI domdoc_createCDATASection(
1150 IXMLDOMDocument2 *iface,
1152 IXMLDOMCDATASection** cdata )
1154 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1156 xmlChar *xml_content;
1158 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1161 return E_INVALIDARG;
1165 xml_content = xmlChar_from_wchar(data);
1166 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1167 HeapFree(GetProcessHeap(), 0, xml_content);
1172 xmlnode->doc = get_doc( This );
1173 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1175 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1181 static HRESULT WINAPI domdoc_createProcessingInstruction(
1182 IXMLDOMDocument2 *iface,
1185 IXMLDOMProcessingInstruction** pi )
1187 #ifdef HAVE_XMLNEWDOCPI
1189 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1190 xmlChar *xml_target, *xml_content;
1192 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1195 return E_INVALIDARG;
1197 if(!target || lstrlenW(target) == 0)
1200 xml_target = xmlChar_from_wchar(target);
1201 xml_content = xmlChar_from_wchar(data);
1203 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1204 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1205 TRACE("created xmlptr %p\n", xmlnode);
1206 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1208 HeapFree(GetProcessHeap(), 0, xml_content);
1209 HeapFree(GetProcessHeap(), 0, xml_target);
1213 FIXME("Libxml 2.6.15 or greater required.\n");
1219 static HRESULT WINAPI domdoc_createAttribute(
1220 IXMLDOMDocument2 *iface,
1222 IXMLDOMAttribute** attribute )
1224 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1228 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1231 return E_INVALIDARG;
1235 xml_name = xmlChar_from_wchar(name);
1236 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1237 HeapFree(GetProcessHeap(), 0, xml_name);
1242 xmlnode->doc = get_doc( This );
1243 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1245 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1251 static HRESULT WINAPI domdoc_createEntityReference(
1252 IXMLDOMDocument2 *iface,
1254 IXMLDOMEntityReference** entityRef )
1256 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1260 TRACE("%p\n", iface);
1263 return E_INVALIDARG;
1267 xml_name = xmlChar_from_wchar(name);
1268 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1269 HeapFree(GetProcessHeap(), 0, xml_name);
1274 xmlnode->doc = get_doc( This );
1275 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1277 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1283 static HRESULT WINAPI domdoc_getElementsByTagName(
1284 IXMLDOMDocument2 *iface,
1286 IXMLDOMNodeList** resultList )
1288 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1291 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1293 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1294 szPattern[0] = szPattern[1] = '/';
1295 lstrcpyW(szPattern + 2, tagName);
1297 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1298 HeapFree(GetProcessHeap(), 0, szPattern);
1303 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1309 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1311 return E_INVALIDARG;
1318 static HRESULT WINAPI domdoc_createNode(
1319 IXMLDOMDocument2 *iface,
1323 IXMLDOMNode** node )
1325 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1326 DOMNodeType node_type;
1327 xmlNodePtr xmlnode = NULL;
1331 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1333 if(namespaceURI && namespaceURI[0])
1334 FIXME("nodes with namespaces currently not supported.\n");
1336 hr = get_node_type(Type, &node_type);
1340 TRACE("node_type %d\n", node_type);
1342 xml_name = xmlChar_from_wchar(name);
1347 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1348 *node = create_node(xmlnode);
1349 TRACE("created %p\n", xmlnode);
1351 case NODE_ATTRIBUTE:
1352 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1355 xmlnode->doc = get_doc( This );
1357 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1360 TRACE("created %p\n", xmlnode);
1364 FIXME("unhandled node type %d\n", node_type);
1368 HeapFree(GetProcessHeap(), 0, xml_name);
1370 if(xmlnode && *node)
1372 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1379 static HRESULT WINAPI domdoc_nodeFromID(
1380 IXMLDOMDocument2 *iface,
1382 IXMLDOMNode** node )
1388 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1393 xmldoc = doparse( ptr, len );
1395 xmldoc->_private = create_priv();
1396 return attach_xmldoc(This->node, xmldoc);
1402 static HRESULT doread( domdoc *This, LPWSTR filename )
1407 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1412 detach_bsc(This->bsc);
1418 static HRESULT WINAPI domdoc_load(
1419 IXMLDOMDocument2 *iface,
1421 VARIANT_BOOL* isSuccessful )
1423 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1424 LPWSTR filename = NULL;
1425 HRESULT hr = S_FALSE;
1426 IXMLDOMDocument2 *pNewDoc = NULL;
1427 IStream *pStream = NULL;
1430 TRACE("type %d\n", V_VT(&xmlSource) );
1432 *isSuccessful = VARIANT_FALSE;
1434 assert( This->node );
1436 switch( V_VT(&xmlSource) )
1439 filename = V_BSTR(&xmlSource);
1442 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1447 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1448 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1449 hr = attach_xmldoc(This->node, xmldoc);
1452 *isSuccessful = VARIANT_TRUE;
1457 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1460 IPersistStream *pDocStream;
1461 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1464 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1465 IStream_Release(pStream);
1468 *isSuccessful = VARIANT_TRUE;
1470 TRACE("Using ID_IStream to load Document\n");
1475 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1480 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1485 /* ISequentialStream */
1486 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1490 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1493 TRACE("filename (%s)\n", debugstr_w(filename));
1497 hr = doread( This, filename );
1500 This->error = E_FAIL;
1503 hr = This->error = S_OK;
1504 *isSuccessful = VARIANT_TRUE;
1508 if(!filename || FAILED(hr)) {
1509 xmldoc = xmlNewDoc(NULL);
1510 xmldoc->_private = create_priv();
1511 hr = attach_xmldoc(This->node, xmldoc);
1516 TRACE("ret (%d)\n", hr);
1522 static HRESULT WINAPI domdoc_get_readyState(
1523 IXMLDOMDocument2 *iface,
1531 static HRESULT WINAPI domdoc_get_parseError(
1532 IXMLDOMDocument2 *iface,
1533 IXMLDOMParseError** errorObj )
1535 BSTR error_string = NULL;
1536 static const WCHAR err[] = {'e','r','r','o','r',0};
1537 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1539 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1542 error_string = SysAllocString(err);
1544 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1545 if(!*errorObj) return E_OUTOFMEMORY;
1550 static HRESULT WINAPI domdoc_get_url(
1551 IXMLDOMDocument2 *iface,
1559 static HRESULT WINAPI domdoc_get_async(
1560 IXMLDOMDocument2 *iface,
1561 VARIANT_BOOL* isAsync )
1563 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1565 TRACE("%p <- %d\n", isAsync, This->async);
1566 *isAsync = This->async;
1571 static HRESULT WINAPI domdoc_put_async(
1572 IXMLDOMDocument2 *iface,
1573 VARIANT_BOOL isAsync )
1575 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1577 TRACE("%d\n", isAsync);
1578 This->async = isAsync;
1583 static HRESULT WINAPI domdoc_abort(
1584 IXMLDOMDocument2 *iface )
1591 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1593 UINT len, blen = SysStringLen( bstr );
1596 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1597 str = HeapAlloc( GetProcessHeap(), 0, len );
1600 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1606 static HRESULT WINAPI domdoc_loadXML(
1607 IXMLDOMDocument2 *iface,
1609 VARIANT_BOOL* isSuccessful )
1611 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1612 xmlDocPtr xmldoc = NULL;
1615 HRESULT hr = S_FALSE, hr2;
1617 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1619 assert ( This->node );
1623 *isSuccessful = VARIANT_FALSE;
1625 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1627 xmldoc = doparse( str, len );
1628 HeapFree( GetProcessHeap(), 0, str );
1630 This->error = E_FAIL;
1633 hr = This->error = S_OK;
1634 *isSuccessful = VARIANT_TRUE;
1639 xmldoc = xmlNewDoc(NULL);
1641 xmldoc->_private = create_priv();
1642 hr2 = attach_xmldoc( This->node, xmldoc );
1650 static HRESULT WINAPI domdoc_save(
1651 IXMLDOMDocument2 *iface,
1652 VARIANT destination )
1654 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1661 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1662 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1664 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1666 FIXME("Unhandled vt %d\n", V_VT(&destination));
1670 if(V_VT(&destination) == VT_UNKNOWN)
1672 IUnknown *pUnk = V_UNKNOWN(&destination);
1673 IXMLDOMDocument *pDocument;
1675 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1679 VARIANT_BOOL bSuccessful;
1681 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1684 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1686 SysFreeString(bXML);
1689 IXMLDOMDocument_Release(pDocument);
1692 TRACE("ret %d\n", ret);
1697 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1698 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1699 if( handle == INVALID_HANDLE_VALUE )
1701 WARN("failed to create file\n");
1705 xmlDocDumpMemory(get_doc(This), &mem, &size);
1708 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1709 * MSXML adds XML declaration only for processing instruction nodes.
1710 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1713 if(size > 2 && p[0] == '<' && p[1] == '?') {
1714 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1717 while(p < mem+size && isspace(*p))
1722 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1724 WARN("write error\n");
1729 CloseHandle(handle);
1733 static HRESULT WINAPI domdoc_get_validateOnParse(
1734 IXMLDOMDocument2 *iface,
1735 VARIANT_BOOL* isValidating )
1737 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1739 TRACE("%p <- %d\n", isValidating, This->validating);
1740 *isValidating = This->validating;
1745 static HRESULT WINAPI domdoc_put_validateOnParse(
1746 IXMLDOMDocument2 *iface,
1747 VARIANT_BOOL isValidating )
1749 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1751 TRACE("%d\n", isValidating);
1752 This->validating = isValidating;
1757 static HRESULT WINAPI domdoc_get_resolveExternals(
1758 IXMLDOMDocument2 *iface,
1759 VARIANT_BOOL* isResolving )
1761 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1763 TRACE("%p <- %d\n", isResolving, This->resolving);
1764 *isResolving = This->resolving;
1769 static HRESULT WINAPI domdoc_put_resolveExternals(
1770 IXMLDOMDocument2 *iface,
1771 VARIANT_BOOL isResolving )
1773 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1775 TRACE("%d\n", isResolving);
1776 This->resolving = isResolving;
1781 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1782 IXMLDOMDocument2 *iface,
1783 VARIANT_BOOL* isPreserving )
1785 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1787 TRACE("%p <- %d\n", isPreserving, This->preserving);
1788 *isPreserving = This->preserving;
1793 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1794 IXMLDOMDocument2 *iface,
1795 VARIANT_BOOL isPreserving )
1797 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1799 TRACE("%d\n", isPreserving);
1800 This->preserving = isPreserving;
1805 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1806 IXMLDOMDocument2 *iface,
1807 VARIANT readyStateChangeSink )
1814 static HRESULT WINAPI domdoc_put_onDataAvailable(
1815 IXMLDOMDocument2 *iface,
1816 VARIANT onDataAvailableSink )
1822 static HRESULT WINAPI domdoc_put_onTransformNode(
1823 IXMLDOMDocument2 *iface,
1824 VARIANT onTransformNodeSink )
1830 static HRESULT WINAPI domdoc_get_namespaces(
1831 IXMLDOMDocument2* iface,
1832 IXMLDOMSchemaCollection** schemaCollection )
1838 static HRESULT WINAPI domdoc_get_schemas(
1839 IXMLDOMDocument2* iface,
1842 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1843 HRESULT hr = S_FALSE;
1844 IXMLDOMSchemaCollection *cur_schema = This->schema;
1846 TRACE("(%p)->(%p)\n", This, var1);
1848 VariantInit(var1); /* Test shows we don't call VariantClear here */
1849 V_VT(var1) = VT_NULL;
1853 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1855 V_VT(var1) = VT_DISPATCH;
1860 static HRESULT WINAPI domdoc_putref_schemas(
1861 IXMLDOMDocument2* iface,
1864 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1865 HRESULT hr = E_FAIL;
1866 IXMLDOMSchemaCollection *new_schema = NULL;
1868 FIXME("(%p): semi-stub\n", This);
1872 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1876 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1885 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1890 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1891 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1897 static HRESULT WINAPI domdoc_validate(
1898 IXMLDOMDocument2* iface,
1899 IXMLDOMParseError** err)
1905 static HRESULT WINAPI domdoc_setProperty(
1906 IXMLDOMDocument2* iface,
1910 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1912 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1918 V_VT(&varStr) = VT_EMPTY;
1919 if (V_VT(&var) != VT_BSTR)
1921 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1923 bstr = V_BSTR(&varStr);
1926 bstr = V_BSTR(&var);
1929 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1930 This->bUseXPath = TRUE;
1931 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1932 This->bUseXPath = FALSE;
1936 VariantClear(&varStr);
1940 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1944 static HRESULT WINAPI domdoc_getProperty(
1945 IXMLDOMDocument2* iface,
1949 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1952 return E_INVALIDARG;
1953 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1955 V_VT(var) = VT_BSTR;
1956 if (This->bUseXPath)
1957 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1959 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1963 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1967 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1969 domdoc_QueryInterface,
1972 domdoc_GetTypeInfoCount,
1974 domdoc_GetIDsOfNames,
1976 domdoc_get_nodeName,
1977 domdoc_get_nodeValue,
1978 domdoc_put_nodeValue,
1979 domdoc_get_nodeType,
1980 domdoc_get_parentNode,
1981 domdoc_get_childNodes,
1982 domdoc_get_firstChild,
1983 domdoc_get_lastChild,
1984 domdoc_get_previousSibling,
1985 domdoc_get_nextSibling,
1986 domdoc_get_attributes,
1987 domdoc_insertBefore,
1988 domdoc_replaceChild,
1991 domdoc_hasChildNodes,
1992 domdoc_get_ownerDocument,
1994 domdoc_get_nodeTypeString,
1997 domdoc_get_specified,
1998 domdoc_get_definition,
1999 domdoc_get_nodeTypedValue,
2000 domdoc_put_nodeTypedValue,
2001 domdoc_get_dataType,
2002 domdoc_put_dataType,
2004 domdoc_transformNode,
2006 domdoc_selectSingleNode,
2008 domdoc_get_namespaceURI,
2010 domdoc_get_baseName,
2011 domdoc_transformNodeToObject,
2013 domdoc_get_implementation,
2014 domdoc_get_documentElement,
2015 domdoc_put_documentElement,
2016 domdoc_createElement,
2017 domdoc_createDocumentFragment,
2018 domdoc_createTextNode,
2019 domdoc_createComment,
2020 domdoc_createCDATASection,
2021 domdoc_createProcessingInstruction,
2022 domdoc_createAttribute,
2023 domdoc_createEntityReference,
2024 domdoc_getElementsByTagName,
2028 domdoc_get_readyState,
2029 domdoc_get_parseError,
2036 domdoc_get_validateOnParse,
2037 domdoc_put_validateOnParse,
2038 domdoc_get_resolveExternals,
2039 domdoc_put_resolveExternals,
2040 domdoc_get_preserveWhiteSpace,
2041 domdoc_put_preserveWhiteSpace,
2042 domdoc_put_onReadyStateChange,
2043 domdoc_put_onDataAvailable,
2044 domdoc_put_onTransformNode,
2045 domdoc_get_namespaces,
2047 domdoc_putref_schemas,
2053 /* xmldoc implementation of IObjectWithSite */
2054 static HRESULT WINAPI
2055 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2057 domdoc *This = impl_from_IObjectWithSite(iface);
2058 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2062 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2064 domdoc *This = impl_from_IObjectWithSite(iface);
2065 return IXMLDocument_AddRef((IXMLDocument *)This);
2069 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2071 domdoc *This = impl_from_IObjectWithSite(iface);
2072 return IXMLDocument_Release((IXMLDocument *)This);
2075 static HRESULT WINAPI
2076 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2078 domdoc *This = impl_from_IObjectWithSite(iface);
2080 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2085 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2088 static HRESULT WINAPI
2089 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2091 domdoc *This = impl_from_IObjectWithSite(iface);
2093 TRACE("%p %p\n", iface, punk);
2099 IUnknown_Release( This->site );
2107 IUnknown_AddRef( punk );
2110 IUnknown_Release( This->site );
2117 static const IObjectWithSiteVtbl domdocObjectSite =
2119 xmldoc_ObjectWithSite_QueryInterface,
2120 xmldoc_ObjectWithSite_AddRef,
2121 xmldoc_ObjectWithSite_Release,
2126 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2128 domdoc *This = impl_from_IObjectSafety(iface);
2129 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2132 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2134 domdoc *This = impl_from_IObjectSafety(iface);
2135 return IXMLDocument_AddRef((IXMLDocument *)This);
2138 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2140 domdoc *This = impl_from_IObjectSafety(iface);
2141 return IXMLDocument_Release((IXMLDocument *)This);
2144 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2146 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2147 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2149 domdoc *This = impl_from_IObjectSafety(iface);
2151 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2153 if(!pdwSupportedOptions || !pdwEnabledOptions)
2156 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2157 *pdwEnabledOptions = This->safeopt;
2162 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2163 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2165 domdoc *This = impl_from_IObjectSafety(iface);
2167 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2169 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2172 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2176 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2177 xmldoc_Safety_QueryInterface,
2178 xmldoc_Safety_AddRef,
2179 xmldoc_Safety_Release,
2180 xmldoc_Safety_GetInterfaceSafetyOptions,
2181 xmldoc_Safety_SetInterfaceSafetyOptions
2185 static const tid_t domdoc_iface_tids[] = {
2187 IXMLDOMDocument_tid,
2188 IXMLDOMDocument2_tid,
2191 static dispex_static_data_t domdoc_dispex = {
2193 IXMLDOMDocument2_tid,
2198 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2203 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2205 return E_OUTOFMEMORY;
2207 doc->lpVtbl = &domdoc_vtbl;
2208 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2209 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2210 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2211 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2213 doc->async = VARIANT_TRUE;
2214 doc->validating = 0;
2216 doc->preserving = 0;
2217 doc->bUseXPath = FALSE;
2225 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2228 HeapFree(GetProcessHeap(), 0, doc);
2232 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2235 IUnknown_Release(doc->node_unk);
2236 HeapFree( GetProcessHeap(), 0, doc );
2240 init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2242 /* The ref on doc->node is actually looped back into this object, so release it */
2243 IXMLDOMNode_Release(doc->node);
2245 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2247 TRACE("returning iface %p\n", *document);
2251 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2256 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2258 xmldoc = xmlNewDoc(NULL);
2260 return E_OUTOFMEMORY;
2262 xmldoc->_private = create_priv();
2264 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2271 IUnknown* create_domdoc( xmlNodePtr document )
2276 TRACE("(%p)\n", document);
2278 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2287 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2289 MESSAGE("This program tried to use a DOMDocument object, but\n"
2290 "libxml2 support was not present at compile time.\n");