2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 #include "msxml_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
50 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
51 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
52 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
54 typedef struct _domdoc
56 const struct IXMLDOMDocument2Vtbl *lpVtbl;
57 const struct IPersistStreamVtbl *lpvtblIPersistStream;
58 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
59 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
62 VARIANT_BOOL validating;
63 VARIANT_BOOL resolving;
64 VARIANT_BOOL preserving;
68 IXMLDOMSchemaCollection *schema;
86 In native windows, the whole lifetime management of XMLDOMNodes is
87 managed automatically using reference counts. Wine emulates that by
88 maintaining a reference count to the document that is increased for
89 each IXMLDOMNode pointer passed out for this document. If all these
90 pointers are gone, the document is unreachable and gets freed, that
91 is, all nodes in the tree of the document get freed.
93 You are able to create nodes that are associated to a document (in
94 fact, in msxml's XMLDOM model, all nodes are associated to a document),
95 but not in the tree of that document, for example using the createFoo
96 functions from IXMLDOMDocument. These nodes do not get cleaned up
97 by libxml, so we have to do it ourselves.
99 To catch these nodes, a list of "orphan nodes" is introduced.
100 It contains pointers to all roots of node trees that are
101 associated with the document without being part of the document
102 tree. All nodes with parent==NULL (except for the document root nodes)
103 should be in the orphan node list of their document. All orphan nodes
104 get freed together with the document itself.
107 typedef struct _xmldoc_priv {
112 typedef struct _orphan_entry {
117 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
119 return doc->_private;
122 static xmldoc_priv * create_priv(void)
125 priv = HeapAlloc( GetProcessHeap(), 0, sizeof (*priv) );
130 list_init( &priv->orphans );
136 static xmlDocPtr doparse( char *ptr, int len )
138 #ifdef HAVE_XMLREADMEMORY
140 * use xmlReadMemory if possible so we can suppress
141 * writing errors to stderr
143 return xmlReadMemory( ptr, len, NULL, NULL,
144 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
146 return xmlParseMemory( ptr, len );
150 LONG xmldoc_add_ref(xmlDocPtr doc)
152 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
157 LONG xmldoc_release(xmlDocPtr doc)
159 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
160 LONG ref = InterlockedDecrement(&priv->refs);
164 orphan_entry *orphan, *orphan2;
165 TRACE("freeing docptr %p\n", doc);
167 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
169 xmlFreeNode( orphan->node );
170 HeapFree( GetProcessHeap(), 0, orphan );
172 HeapFree(GetProcessHeap(), 0, doc->_private);
180 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
182 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
185 entry = HeapAlloc( GetProcessHeap(), 0, sizeof (*entry) );
187 return E_OUTOFMEMORY;
190 list_add_head( &priv->orphans, &entry->entry );
194 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
196 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
197 orphan_entry *entry, *entry2;
199 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
201 if( entry->node == node )
203 list_remove( &entry->entry );
204 HeapFree( GetProcessHeap(), 0, entry );
212 static HRESULT attach_xmldoc( IXMLDOMNode *node, xmlDocPtr xml )
214 xmlnode *This = impl_from_IXMLDOMNode( node );
217 xmldoc_release(This->node->doc);
219 This->node = (xmlNodePtr) xml;
221 xmldoc_add_ref(This->node->doc);
226 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
228 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
231 static inline xmlDocPtr get_doc( domdoc *This )
233 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
236 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
238 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
241 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
243 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
246 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
248 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
252 /************************************************************************
253 * xmldoc implementation of IPersistStream.
255 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
256 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
258 domdoc *this = impl_from_IPersistStream(iface);
259 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
262 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
263 IPersistStream *iface)
265 domdoc *this = impl_from_IPersistStream(iface);
266 return IXMLDocument_AddRef((IXMLDocument *)this);
269 static ULONG WINAPI xmldoc_IPersistStream_Release(
270 IPersistStream *iface)
272 domdoc *this = impl_from_IPersistStream(iface);
273 return IXMLDocument_Release((IXMLDocument *)this);
276 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
277 IPersistStream *iface, CLSID *classid)
279 TRACE("(%p,%p): stub!\n", iface, classid);
284 *classid = CLSID_DOMDocument2;
289 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
290 IPersistStream *iface)
292 domdoc *This = impl_from_IPersistStream(iface);
294 FIXME("(%p->%p): stub!\n", iface, This);
299 static HRESULT WINAPI xmldoc_IPersistStream_Load(
300 IPersistStream *iface, LPSTREAM pStm)
302 domdoc *This = impl_from_IPersistStream(iface);
305 DWORD read, written, len;
308 xmlDocPtr xmldoc = NULL;
310 TRACE("(%p, %p)\n", iface, pStm);
315 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
321 IStream_Read(pStm, buf, sizeof(buf), &read);
322 hr = IStream_Write(This->stream, buf, read, &written);
323 } while(SUCCEEDED(hr) && written != 0 && read != 0);
327 ERR("Failed to copy stream\n");
331 hr = GetHGlobalFromStream(This->stream, &hglobal);
335 len = GlobalSize(hglobal);
336 ptr = GlobalLock(hglobal);
338 xmldoc = parse_xml(ptr, len);
339 GlobalUnlock(hglobal);
343 ERR("Failed to parse xml\n");
347 xmldoc->_private = create_priv();
349 return attach_xmldoc( This->node, xmldoc );
352 static HRESULT WINAPI xmldoc_IPersistStream_Save(
353 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
355 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
359 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
360 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
362 TRACE("(%p, %p): stub!\n", iface, pcbSize);
366 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
368 xmldoc_IPersistStream_QueryInterface,
369 xmldoc_IPersistStream_AddRef,
370 xmldoc_IPersistStream_Release,
371 xmldoc_IPersistStream_GetClassID,
372 xmldoc_IPersistStream_IsDirty,
373 xmldoc_IPersistStream_Load,
374 xmldoc_IPersistStream_Save,
375 xmldoc_IPersistStream_GetSizeMax,
378 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
380 domdoc *This = impl_from_IXMLDOMDocument2( iface );
382 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
386 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
387 IsEqualGUID( riid, &IID_IDispatch ) ||
388 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
389 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
393 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
395 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
397 else if (IsEqualGUID(&IID_IPersistStream, riid))
399 *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
401 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
403 *ppvObject = (IObjectWithSite*)&(This->lpvtblIObjectWithSite);
405 else if(dispex_query_interface(&This->dispex, riid, ppvObject))
407 return *ppvObject ? S_OK : E_NOINTERFACE;
409 else if(IsEqualGUID(&IID_IRunnableObject, riid))
411 TRACE("IID_IRunnableObject not supported returning NULL\n");
412 return E_NOINTERFACE;
416 FIXME("interface %s not implemented\n", debugstr_guid(riid));
417 return E_NOINTERFACE;
420 IXMLDOMDocument_AddRef( iface );
426 static ULONG WINAPI domdoc_AddRef(
427 IXMLDOMDocument2 *iface )
429 domdoc *This = impl_from_IXMLDOMDocument2( iface );
430 TRACE("%p\n", This );
431 return InterlockedIncrement( &This->ref );
435 static ULONG WINAPI domdoc_Release(
436 IXMLDOMDocument2 *iface )
438 domdoc *This = impl_from_IXMLDOMDocument2( iface );
441 TRACE("%p\n", This );
443 ref = InterlockedDecrement( &This->ref );
447 detach_bsc(This->bsc);
450 IUnknown_Release( This->site );
451 IUnknown_Release( This->node_unk );
452 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
453 if (This->stream) IStream_Release(This->stream);
454 HeapFree( GetProcessHeap(), 0, This );
460 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
462 domdoc *This = impl_from_IXMLDOMDocument2( iface );
464 TRACE("(%p)->(%p)\n", This, pctinfo);
471 static HRESULT WINAPI domdoc_GetTypeInfo(
472 IXMLDOMDocument2 *iface,
473 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
475 domdoc *This = impl_from_IXMLDOMDocument2( iface );
478 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
480 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
485 static HRESULT WINAPI domdoc_GetIDsOfNames(
486 IXMLDOMDocument2 *iface,
493 domdoc *This = impl_from_IXMLDOMDocument2( iface );
497 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
500 if(!rgszNames || cNames == 0 || !rgDispId)
503 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
506 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
507 ITypeInfo_Release(typeinfo);
514 static HRESULT WINAPI domdoc_Invoke(
515 IXMLDOMDocument2 *iface,
520 DISPPARAMS* pDispParams,
522 EXCEPINFO* pExcepInfo,
525 domdoc *This = impl_from_IXMLDOMDocument2( iface );
529 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
530 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
532 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
535 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
536 pVarResult, pExcepInfo, puArgErr);
537 ITypeInfo_Release(typeinfo);
544 static HRESULT WINAPI domdoc_get_nodeName(
545 IXMLDOMDocument2 *iface,
548 domdoc *This = impl_from_IXMLDOMDocument2( iface );
549 return IXMLDOMNode_get_nodeName( This->node, name );
553 static HRESULT WINAPI domdoc_get_nodeValue(
554 IXMLDOMDocument2 *iface,
557 domdoc *This = impl_from_IXMLDOMDocument2( iface );
558 return IXMLDOMNode_get_nodeValue( This->node, value );
562 static HRESULT WINAPI domdoc_put_nodeValue(
563 IXMLDOMDocument2 *iface,
566 domdoc *This = impl_from_IXMLDOMDocument2( iface );
567 return IXMLDOMNode_put_nodeValue( This->node, value );
571 static HRESULT WINAPI domdoc_get_nodeType(
572 IXMLDOMDocument2 *iface,
575 domdoc *This = impl_from_IXMLDOMDocument2( iface );
576 return IXMLDOMNode_get_nodeType( This->node, type );
580 static HRESULT WINAPI domdoc_get_parentNode(
581 IXMLDOMDocument2 *iface,
582 IXMLDOMNode** parent )
584 domdoc *This = impl_from_IXMLDOMDocument2( iface );
585 return IXMLDOMNode_get_parentNode( This->node, parent );
589 static HRESULT WINAPI domdoc_get_childNodes(
590 IXMLDOMDocument2 *iface,
591 IXMLDOMNodeList** childList )
593 domdoc *This = impl_from_IXMLDOMDocument2( iface );
594 return IXMLDOMNode_get_childNodes( This->node, childList );
598 static HRESULT WINAPI domdoc_get_firstChild(
599 IXMLDOMDocument2 *iface,
600 IXMLDOMNode** firstChild )
602 domdoc *This = impl_from_IXMLDOMDocument2( iface );
603 return IXMLDOMNode_get_firstChild( This->node, firstChild );
607 static HRESULT WINAPI domdoc_get_lastChild(
608 IXMLDOMDocument2 *iface,
609 IXMLDOMNode** lastChild )
611 domdoc *This = impl_from_IXMLDOMDocument2( iface );
612 return IXMLDOMNode_get_lastChild( This->node, lastChild );
616 static HRESULT WINAPI domdoc_get_previousSibling(
617 IXMLDOMDocument2 *iface,
618 IXMLDOMNode** previousSibling )
620 domdoc *This = impl_from_IXMLDOMDocument2( iface );
621 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
625 static HRESULT WINAPI domdoc_get_nextSibling(
626 IXMLDOMDocument2 *iface,
627 IXMLDOMNode** nextSibling )
629 domdoc *This = impl_from_IXMLDOMDocument2( iface );
630 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
634 static HRESULT WINAPI domdoc_get_attributes(
635 IXMLDOMDocument2 *iface,
636 IXMLDOMNamedNodeMap** attributeMap )
638 domdoc *This = impl_from_IXMLDOMDocument2( iface );
639 return IXMLDOMNode_get_attributes( This->node, attributeMap );
643 static HRESULT WINAPI domdoc_insertBefore(
644 IXMLDOMDocument2 *iface,
645 IXMLDOMNode* newChild,
647 IXMLDOMNode** outNewChild )
649 domdoc *This = impl_from_IXMLDOMDocument2( iface );
650 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
654 static HRESULT WINAPI domdoc_replaceChild(
655 IXMLDOMDocument2 *iface,
656 IXMLDOMNode* newChild,
657 IXMLDOMNode* oldChild,
658 IXMLDOMNode** outOldChild)
660 domdoc *This = impl_from_IXMLDOMDocument2( iface );
661 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
665 static HRESULT WINAPI domdoc_removeChild(
666 IXMLDOMDocument2 *iface,
667 IXMLDOMNode* childNode,
668 IXMLDOMNode** oldChild)
670 domdoc *This = impl_from_IXMLDOMDocument2( iface );
671 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
675 static HRESULT WINAPI domdoc_appendChild(
676 IXMLDOMDocument2 *iface,
677 IXMLDOMNode* newChild,
678 IXMLDOMNode** outNewChild)
680 domdoc *This = impl_from_IXMLDOMDocument2( iface );
681 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
685 static HRESULT WINAPI domdoc_hasChildNodes(
686 IXMLDOMDocument2 *iface,
687 VARIANT_BOOL* hasChild)
689 domdoc *This = impl_from_IXMLDOMDocument2( iface );
690 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
694 static HRESULT WINAPI domdoc_get_ownerDocument(
695 IXMLDOMDocument2 *iface,
696 IXMLDOMDocument** DOMDocument)
698 domdoc *This = impl_from_IXMLDOMDocument2( iface );
699 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
703 static HRESULT WINAPI domdoc_cloneNode(
704 IXMLDOMDocument2 *iface,
706 IXMLDOMNode** cloneRoot)
708 domdoc *This = impl_from_IXMLDOMDocument2( iface );
709 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
713 static HRESULT WINAPI domdoc_get_nodeTypeString(
714 IXMLDOMDocument2 *iface,
717 domdoc *This = impl_from_IXMLDOMDocument2( iface );
718 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
722 static HRESULT WINAPI domdoc_get_text(
723 IXMLDOMDocument2 *iface,
726 domdoc *This = impl_from_IXMLDOMDocument2( iface );
727 return IXMLDOMNode_get_text( This->node, text );
731 static HRESULT WINAPI domdoc_put_text(
732 IXMLDOMDocument2 *iface,
735 domdoc *This = impl_from_IXMLDOMDocument2( iface );
736 return IXMLDOMNode_put_text( This->node, text );
740 static HRESULT WINAPI domdoc_get_specified(
741 IXMLDOMDocument2 *iface,
742 VARIANT_BOOL* isSpecified )
744 domdoc *This = impl_from_IXMLDOMDocument2( iface );
745 return IXMLDOMNode_get_specified( This->node, isSpecified );
749 static HRESULT WINAPI domdoc_get_definition(
750 IXMLDOMDocument2 *iface,
751 IXMLDOMNode** definitionNode )
753 domdoc *This = impl_from_IXMLDOMDocument2( iface );
754 return IXMLDOMNode_get_definition( This->node, definitionNode );
758 static HRESULT WINAPI domdoc_get_nodeTypedValue(
759 IXMLDOMDocument2 *iface,
760 VARIANT* typedValue )
762 domdoc *This = impl_from_IXMLDOMDocument2( iface );
763 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
766 static HRESULT WINAPI domdoc_put_nodeTypedValue(
767 IXMLDOMDocument2 *iface,
770 domdoc *This = impl_from_IXMLDOMDocument2( iface );
771 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
775 static HRESULT WINAPI domdoc_get_dataType(
776 IXMLDOMDocument2 *iface,
777 VARIANT* dataTypeName )
779 domdoc *This = impl_from_IXMLDOMDocument2( iface );
780 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
784 static HRESULT WINAPI domdoc_put_dataType(
785 IXMLDOMDocument2 *iface,
788 domdoc *This = impl_from_IXMLDOMDocument2( iface );
789 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
793 static HRESULT WINAPI domdoc_get_xml(
794 IXMLDOMDocument2 *iface,
797 domdoc *This = impl_from_IXMLDOMDocument2( iface );
798 return IXMLDOMNode_get_xml( This->node, xmlString );
802 static HRESULT WINAPI domdoc_transformNode(
803 IXMLDOMDocument2 *iface,
804 IXMLDOMNode* styleSheet,
807 domdoc *This = impl_from_IXMLDOMDocument2( iface );
808 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
812 static HRESULT WINAPI domdoc_selectNodes(
813 IXMLDOMDocument2 *iface,
815 IXMLDOMNodeList** resultList )
817 domdoc *This = impl_from_IXMLDOMDocument2( iface );
818 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
822 static HRESULT WINAPI domdoc_selectSingleNode(
823 IXMLDOMDocument2 *iface,
825 IXMLDOMNode** resultNode )
827 domdoc *This = impl_from_IXMLDOMDocument2( iface );
828 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
832 static HRESULT WINAPI domdoc_get_parsed(
833 IXMLDOMDocument2 *iface,
834 VARIANT_BOOL* isParsed )
836 domdoc *This = impl_from_IXMLDOMDocument2( iface );
837 return IXMLDOMNode_get_parsed( This->node, isParsed );
841 static HRESULT WINAPI domdoc_get_namespaceURI(
842 IXMLDOMDocument2 *iface,
845 domdoc *This = impl_from_IXMLDOMDocument2( iface );
846 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
850 static HRESULT WINAPI domdoc_get_prefix(
851 IXMLDOMDocument2 *iface,
854 domdoc *This = impl_from_IXMLDOMDocument2( iface );
855 return IXMLDOMNode_get_prefix( This->node, prefixString );
859 static HRESULT WINAPI domdoc_get_baseName(
860 IXMLDOMDocument2 *iface,
863 domdoc *This = impl_from_IXMLDOMDocument2( iface );
864 return IXMLDOMNode_get_baseName( This->node, nameString );
868 static HRESULT WINAPI domdoc_transformNodeToObject(
869 IXMLDOMDocument2 *iface,
870 IXMLDOMNode* stylesheet,
871 VARIANT outputObject)
873 domdoc *This = impl_from_IXMLDOMDocument2( iface );
874 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
878 static HRESULT WINAPI domdoc_get_doctype(
879 IXMLDOMDocument2 *iface,
880 IXMLDOMDocumentType** documentType )
887 static HRESULT WINAPI domdoc_get_implementation(
888 IXMLDOMDocument2 *iface,
889 IXMLDOMImplementation** impl )
894 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
899 static HRESULT WINAPI domdoc_get_documentElement(
900 IXMLDOMDocument2 *iface,
901 IXMLDOMElement** DOMElement )
903 domdoc *This = impl_from_IXMLDOMDocument2( iface );
904 xmlDocPtr xmldoc = NULL;
905 xmlNodePtr root = NULL;
906 IXMLDOMNode *element_node;
909 TRACE("%p %p\n", This, This->node);
916 xmldoc = get_doc( This );
918 root = xmlDocGetRootElement( xmldoc );
922 element_node = create_node( root );
923 if(!element_node) return S_FALSE;
925 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
926 IXMLDOMNode_Release(element_node);
932 static HRESULT WINAPI domdoc_put_documentElement(
933 IXMLDOMDocument2 *iface,
934 IXMLDOMElement* DOMElement )
936 domdoc *This = impl_from_IXMLDOMDocument2( iface );
937 IXMLDOMNode *elementNode;
942 TRACE("(%p)->(%p)\n", This, DOMElement);
944 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
948 xmlNode = impl_from_IXMLDOMNode( elementNode );
950 if(!xmlNode->node->parent)
951 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
952 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
954 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
955 IXMLDOMNode_Release( elementNode );
958 xmldoc_add_orphan(oldRoot->doc, oldRoot);
964 static HRESULT WINAPI domdoc_createElement(
965 IXMLDOMDocument2 *iface,
967 IXMLDOMElement** element )
970 domdoc *This = impl_from_IXMLDOMDocument2( iface );
975 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
977 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
978 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
979 xmldoc_add_orphan(xmlnode->doc, xmlnode);
981 TRACE("created xmlptr %p\n", xmlnode);
982 elem_unk = create_element(xmlnode, NULL);
983 HeapFree(GetProcessHeap(), 0, xml_name);
985 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
986 IUnknown_Release(elem_unk);
987 TRACE("returning %p\n", *element);
992 static HRESULT WINAPI domdoc_createDocumentFragment(
993 IXMLDOMDocument2 *iface,
994 IXMLDOMDocumentFragment** docFrag )
996 domdoc *This = impl_from_IXMLDOMDocument2( iface );
999 TRACE("%p\n", iface);
1002 return E_INVALIDARG;
1006 xmlnode = xmlNewDocFragment(get_doc( This ) );
1011 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1012 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1018 static HRESULT WINAPI domdoc_createTextNode(
1019 IXMLDOMDocument2 *iface,
1021 IXMLDOMText** text )
1023 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1025 xmlChar *xml_content;
1027 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1030 return E_INVALIDARG;
1034 xml_content = xmlChar_from_wchar((WCHAR*)data);
1035 xmlnode = xmlNewText(xml_content);
1036 HeapFree(GetProcessHeap(), 0, xml_content);
1041 xmlnode->doc = get_doc( This );
1042 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1044 *text = (IXMLDOMText*)create_text(xmlnode);
1050 static HRESULT WINAPI domdoc_createComment(
1051 IXMLDOMDocument2 *iface,
1053 IXMLDOMComment** comment )
1055 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1057 xmlChar *xml_content;
1059 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1062 return E_INVALIDARG;
1066 xml_content = xmlChar_from_wchar((WCHAR*)data);
1067 xmlnode = xmlNewComment(xml_content);
1068 HeapFree(GetProcessHeap(), 0, xml_content);
1073 xmlnode->doc = get_doc( This );
1074 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1076 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1082 static HRESULT WINAPI domdoc_createCDATASection(
1083 IXMLDOMDocument2 *iface,
1085 IXMLDOMCDATASection** cdata )
1087 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1089 xmlChar *xml_content;
1091 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1094 return E_INVALIDARG;
1098 xml_content = xmlChar_from_wchar((WCHAR*)data);
1099 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1100 HeapFree(GetProcessHeap(), 0, xml_content);
1105 xmlnode->doc = get_doc( This );
1106 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1108 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1114 static HRESULT WINAPI domdoc_createProcessingInstruction(
1115 IXMLDOMDocument2 *iface,
1118 IXMLDOMProcessingInstruction** pi )
1120 #ifdef HAVE_XMLNEWDOCPI
1122 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1123 xmlChar *xml_target, *xml_content;
1125 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1128 return E_INVALIDARG;
1130 if(!target || lstrlenW(target) == 0)
1133 xml_target = xmlChar_from_wchar((WCHAR*)target);
1134 xml_content = xmlChar_from_wchar((WCHAR*)data);
1136 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1137 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1138 TRACE("created xmlptr %p\n", xmlnode);
1139 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1141 HeapFree(GetProcessHeap(), 0, xml_content);
1142 HeapFree(GetProcessHeap(), 0, xml_target);
1146 FIXME("Libxml 2.6.15 or greater required.\n");
1152 static HRESULT WINAPI domdoc_createAttribute(
1153 IXMLDOMDocument2 *iface,
1155 IXMLDOMAttribute** attribute )
1157 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1161 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1164 return E_INVALIDARG;
1168 xml_name = xmlChar_from_wchar((WCHAR*)name);
1169 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1170 HeapFree(GetProcessHeap(), 0, xml_name);
1175 xmlnode->doc = get_doc( This );
1176 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1178 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1184 static HRESULT WINAPI domdoc_createEntityReference(
1185 IXMLDOMDocument2 *iface,
1187 IXMLDOMEntityReference** entityRef )
1189 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1193 TRACE("%p\n", iface);
1196 return E_INVALIDARG;
1200 xml_name = xmlChar_from_wchar((WCHAR*)name);
1201 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1202 HeapFree(GetProcessHeap(), 0, xml_name);
1207 xmlnode->doc = get_doc( This );
1208 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1210 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1216 static HRESULT WINAPI domdoc_getElementsByTagName(
1217 IXMLDOMDocument2 *iface,
1219 IXMLDOMNodeList** resultList )
1221 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1224 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1226 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1227 szPattern[0] = szPattern[1] = '/';
1228 lstrcpyW(szPattern + 2, tagName);
1230 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1231 HeapFree(GetProcessHeap(), 0, szPattern);
1236 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1242 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1244 return E_INVALIDARG;
1251 static HRESULT WINAPI domdoc_createNode(
1252 IXMLDOMDocument2 *iface,
1256 IXMLDOMNode** node )
1258 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1259 DOMNodeType node_type;
1260 xmlNodePtr xmlnode = NULL;
1264 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1266 hr = get_node_type(Type, &node_type);
1270 TRACE("node_type %d\n", node_type);
1272 xml_name = xmlChar_from_wchar((WCHAR*)name);
1277 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1278 *node = create_node(xmlnode);
1279 TRACE("created %p\n", xmlnode);
1281 case NODE_ATTRIBUTE:
1282 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1285 xmlnode->doc = get_doc( This );
1287 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1290 TRACE("created %p\n", xmlnode);
1294 FIXME("unhandled node type %d\n", node_type);
1298 HeapFree(GetProcessHeap(), 0, xml_name);
1300 if(xmlnode && *node)
1302 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1309 static HRESULT WINAPI domdoc_nodeFromID(
1310 IXMLDOMDocument2 *iface,
1312 IXMLDOMNode** node )
1318 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1323 xmldoc = doparse( ptr, len );
1325 xmldoc->_private = create_priv();
1326 return attach_xmldoc(This->node, xmldoc);
1332 static HRESULT doread( domdoc *This, LPWSTR filename )
1337 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1342 detach_bsc(This->bsc);
1348 static HRESULT WINAPI domdoc_load(
1349 IXMLDOMDocument2 *iface,
1351 VARIANT_BOOL* isSuccessful )
1353 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1354 LPWSTR filename = NULL;
1355 HRESULT hr = S_FALSE;
1356 IXMLDOMDocument2 *pNewDoc = NULL;
1357 IStream *pStream = NULL;
1360 TRACE("type %d\n", V_VT(&xmlSource) );
1362 *isSuccessful = VARIANT_FALSE;
1364 assert( This->node );
1366 switch( V_VT(&xmlSource) )
1369 filename = V_BSTR(&xmlSource);
1372 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1377 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1378 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1379 hr = attach_xmldoc(This->node, xmldoc);
1382 *isSuccessful = VARIANT_TRUE;
1387 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1390 IPersistStream *pDocStream;
1391 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1394 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1395 IStream_Release(pStream);
1398 *isSuccessful = VARIANT_TRUE;
1400 TRACE("Using ID_IStream to load Document\n");
1405 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1410 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1415 /* ISequentialStream */
1416 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1420 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1423 TRACE("filename (%s)\n", debugstr_w(filename));
1427 hr = doread( This, filename );
1430 This->error = E_FAIL;
1433 hr = This->error = S_OK;
1434 *isSuccessful = VARIANT_TRUE;
1438 if(!filename || FAILED(hr)) {
1439 xmldoc = xmlNewDoc(NULL);
1440 xmldoc->_private = create_priv();
1441 hr = attach_xmldoc(This->node, xmldoc);
1446 TRACE("ret (%d)\n", hr);
1452 static HRESULT WINAPI domdoc_get_readyState(
1453 IXMLDOMDocument2 *iface,
1461 static HRESULT WINAPI domdoc_get_parseError(
1462 IXMLDOMDocument2 *iface,
1463 IXMLDOMParseError** errorObj )
1465 BSTR error_string = NULL;
1466 static const WCHAR err[] = {'e','r','r','o','r',0};
1467 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1469 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1472 error_string = SysAllocString(err);
1474 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1475 if(!*errorObj) return E_OUTOFMEMORY;
1480 static HRESULT WINAPI domdoc_get_url(
1481 IXMLDOMDocument2 *iface,
1489 static HRESULT WINAPI domdoc_get_async(
1490 IXMLDOMDocument2 *iface,
1491 VARIANT_BOOL* isAsync )
1493 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1495 TRACE("%p <- %d\n", isAsync, This->async);
1496 *isAsync = This->async;
1501 static HRESULT WINAPI domdoc_put_async(
1502 IXMLDOMDocument2 *iface,
1503 VARIANT_BOOL isAsync )
1505 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1507 TRACE("%d\n", isAsync);
1508 This->async = isAsync;
1513 static HRESULT WINAPI domdoc_abort(
1514 IXMLDOMDocument2 *iface )
1521 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1523 UINT len, blen = SysStringLen( bstr );
1526 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1527 str = HeapAlloc( GetProcessHeap(), 0, len );
1530 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1536 static HRESULT WINAPI domdoc_loadXML(
1537 IXMLDOMDocument2 *iface,
1539 VARIANT_BOOL* isSuccessful )
1541 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1542 xmlDocPtr xmldoc = NULL;
1545 HRESULT hr = S_FALSE, hr2;
1547 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1549 assert ( This->node );
1553 *isSuccessful = VARIANT_FALSE;
1555 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1557 xmldoc = doparse( str, len );
1558 HeapFree( GetProcessHeap(), 0, str );
1560 This->error = E_FAIL;
1563 hr = This->error = S_OK;
1564 *isSuccessful = VARIANT_TRUE;
1569 xmldoc = xmlNewDoc(NULL);
1571 xmldoc->_private = create_priv();
1572 hr2 = attach_xmldoc( This->node, xmldoc );
1580 static HRESULT WINAPI domdoc_save(
1581 IXMLDOMDocument2 *iface,
1582 VARIANT destination )
1584 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1591 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1592 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1594 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1596 FIXME("Unhandled vt %d\n", V_VT(&destination));
1600 if(V_VT(&destination) == VT_UNKNOWN)
1602 IUnknown *pUnk = V_UNKNOWN(&destination);
1603 IXMLDOMDocument *pDocument;
1605 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1609 VARIANT_BOOL bSuccessful;
1611 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1614 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1616 SysFreeString(bXML);
1619 IXMLDOMDocument_Release(pDocument);
1622 TRACE("ret %d\n", ret);
1627 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1628 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1629 if( handle == INVALID_HANDLE_VALUE )
1631 WARN("failed to create file\n");
1635 xmlDocDumpMemory(get_doc(This), &mem, &size);
1638 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1639 * MSXML adds XML declaration only for processing instruction nodes.
1640 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1643 if(size > 2 && p[0] == '<' && p[1] == '?') {
1644 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1647 while(p < mem+size && isspace(*p))
1652 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1654 WARN("write error\n");
1659 CloseHandle(handle);
1663 static HRESULT WINAPI domdoc_get_validateOnParse(
1664 IXMLDOMDocument2 *iface,
1665 VARIANT_BOOL* isValidating )
1667 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1669 TRACE("%p <- %d\n", isValidating, This->validating);
1670 *isValidating = This->validating;
1675 static HRESULT WINAPI domdoc_put_validateOnParse(
1676 IXMLDOMDocument2 *iface,
1677 VARIANT_BOOL isValidating )
1679 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1681 TRACE("%d\n", isValidating);
1682 This->validating = isValidating;
1687 static HRESULT WINAPI domdoc_get_resolveExternals(
1688 IXMLDOMDocument2 *iface,
1689 VARIANT_BOOL* isResolving )
1691 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1693 TRACE("%p <- %d\n", isResolving, This->resolving);
1694 *isResolving = This->resolving;
1699 static HRESULT WINAPI domdoc_put_resolveExternals(
1700 IXMLDOMDocument2 *iface,
1701 VARIANT_BOOL isResolving )
1703 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1705 TRACE("%d\n", isResolving);
1706 This->resolving = isResolving;
1711 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1712 IXMLDOMDocument2 *iface,
1713 VARIANT_BOOL* isPreserving )
1715 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1717 TRACE("%p <- %d\n", isPreserving, This->preserving);
1718 *isPreserving = This->preserving;
1723 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1724 IXMLDOMDocument2 *iface,
1725 VARIANT_BOOL isPreserving )
1727 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1729 TRACE("%d\n", isPreserving);
1730 This->preserving = isPreserving;
1735 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1736 IXMLDOMDocument2 *iface,
1737 VARIANT readyStateChangeSink )
1744 static HRESULT WINAPI domdoc_put_onDataAvailable(
1745 IXMLDOMDocument2 *iface,
1746 VARIANT onDataAvailableSink )
1752 static HRESULT WINAPI domdoc_put_onTransformNode(
1753 IXMLDOMDocument2 *iface,
1754 VARIANT onTransformNodeSink )
1760 static HRESULT WINAPI domdoc_get_namespaces(
1761 IXMLDOMDocument2* iface,
1762 IXMLDOMSchemaCollection** schemaCollection )
1768 static HRESULT WINAPI domdoc_get_schemas(
1769 IXMLDOMDocument2* iface,
1772 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1773 HRESULT hr = S_FALSE;
1774 IXMLDOMSchemaCollection *cur_schema = This->schema;
1776 TRACE("(%p)->(%p)\n", This, var1);
1778 VariantInit(var1); /* Test shows we don't call VariantClear here */
1779 V_VT(var1) = VT_NULL;
1783 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1785 V_VT(var1) = VT_DISPATCH;
1790 static HRESULT WINAPI domdoc_putref_schemas(
1791 IXMLDOMDocument2* iface,
1794 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1795 HRESULT hr = E_FAIL;
1796 IXMLDOMSchemaCollection *new_schema = NULL;
1798 FIXME("(%p): semi-stub\n", This);
1802 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1806 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1815 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1820 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1821 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1827 static HRESULT WINAPI domdoc_validate(
1828 IXMLDOMDocument2* iface,
1829 IXMLDOMParseError** err)
1835 static HRESULT WINAPI domdoc_setProperty(
1836 IXMLDOMDocument2* iface,
1840 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1842 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1848 V_VT(&varStr) = VT_EMPTY;
1849 if (V_VT(&var) != VT_BSTR)
1851 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1853 bstr = V_BSTR(&varStr);
1856 bstr = V_BSTR(&var);
1859 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1860 This->bUseXPath = TRUE;
1861 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1862 This->bUseXPath = FALSE;
1866 VariantClear(&varStr);
1870 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1874 static HRESULT WINAPI domdoc_getProperty(
1875 IXMLDOMDocument2* iface,
1879 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1882 return E_INVALIDARG;
1883 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1885 V_VT(var) = VT_BSTR;
1886 if (This->bUseXPath)
1887 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1889 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1893 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1897 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1899 domdoc_QueryInterface,
1902 domdoc_GetTypeInfoCount,
1904 domdoc_GetIDsOfNames,
1906 domdoc_get_nodeName,
1907 domdoc_get_nodeValue,
1908 domdoc_put_nodeValue,
1909 domdoc_get_nodeType,
1910 domdoc_get_parentNode,
1911 domdoc_get_childNodes,
1912 domdoc_get_firstChild,
1913 domdoc_get_lastChild,
1914 domdoc_get_previousSibling,
1915 domdoc_get_nextSibling,
1916 domdoc_get_attributes,
1917 domdoc_insertBefore,
1918 domdoc_replaceChild,
1921 domdoc_hasChildNodes,
1922 domdoc_get_ownerDocument,
1924 domdoc_get_nodeTypeString,
1927 domdoc_get_specified,
1928 domdoc_get_definition,
1929 domdoc_get_nodeTypedValue,
1930 domdoc_put_nodeTypedValue,
1931 domdoc_get_dataType,
1932 domdoc_put_dataType,
1934 domdoc_transformNode,
1936 domdoc_selectSingleNode,
1938 domdoc_get_namespaceURI,
1940 domdoc_get_baseName,
1941 domdoc_transformNodeToObject,
1943 domdoc_get_implementation,
1944 domdoc_get_documentElement,
1945 domdoc_put_documentElement,
1946 domdoc_createElement,
1947 domdoc_createDocumentFragment,
1948 domdoc_createTextNode,
1949 domdoc_createComment,
1950 domdoc_createCDATASection,
1951 domdoc_createProcessingInstruction,
1952 domdoc_createAttribute,
1953 domdoc_createEntityReference,
1954 domdoc_getElementsByTagName,
1958 domdoc_get_readyState,
1959 domdoc_get_parseError,
1966 domdoc_get_validateOnParse,
1967 domdoc_put_validateOnParse,
1968 domdoc_get_resolveExternals,
1969 domdoc_put_resolveExternals,
1970 domdoc_get_preserveWhiteSpace,
1971 domdoc_put_preserveWhiteSpace,
1972 domdoc_put_onReadyStateChange,
1973 domdoc_put_onDataAvailable,
1974 domdoc_put_onTransformNode,
1975 domdoc_get_namespaces,
1977 domdoc_putref_schemas,
1983 /* xmldoc implementation of IObjectWithSite */
1984 static HRESULT WINAPI
1985 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
1987 domdoc *This = impl_from_IObjectWithSite(iface);
1988 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
1992 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
1994 domdoc *This = impl_from_IObjectWithSite(iface);
1995 return IXMLDocument_AddRef((IXMLDocument *)This);
1999 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2001 domdoc *This = impl_from_IObjectWithSite(iface);
2002 return IXMLDocument_Release((IXMLDocument *)This);
2005 static HRESULT WINAPI
2006 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2008 domdoc *This = impl_from_IObjectWithSite(iface);
2010 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2015 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2018 static HRESULT WINAPI
2019 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2021 domdoc *This = impl_from_IObjectWithSite(iface);
2023 TRACE("%p %p\n", iface, punk);
2029 IUnknown_Release( This->site );
2037 IUnknown_AddRef( punk );
2040 IUnknown_Release( This->site );
2047 static const IObjectWithSiteVtbl domdocObjectSite =
2049 xmldoc_ObjectWithSite_QueryInterface,
2050 xmldoc_ObjectWithSite_AddRef,
2051 xmldoc_ObjectWithSite_Release,
2056 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2058 domdoc *This = impl_from_IObjectSafety(iface);
2059 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2062 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2064 domdoc *This = impl_from_IObjectSafety(iface);
2065 return IXMLDocument_AddRef((IXMLDocument *)This);
2068 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2070 domdoc *This = impl_from_IObjectSafety(iface);
2071 return IXMLDocument_Release((IXMLDocument *)This);
2074 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2076 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2077 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2079 domdoc *This = impl_from_IObjectSafety(iface);
2081 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2083 if(!pdwSupportedOptions || !pdwEnabledOptions)
2086 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2087 *pdwEnabledOptions = This->safeopt;
2092 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2093 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2095 domdoc *This = impl_from_IObjectSafety(iface);
2097 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2099 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2102 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2106 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2107 xmldoc_Safety_QueryInterface,
2108 xmldoc_Safety_AddRef,
2109 xmldoc_Safety_Release,
2110 xmldoc_Safety_GetInterfaceSafetyOptions,
2111 xmldoc_Safety_SetInterfaceSafetyOptions
2115 static const tid_t domdoc_iface_tids[] = {
2117 IXMLDOMDocument_tid,
2118 IXMLDOMDocument2_tid,
2121 static dispex_static_data_t domdoc_dispex = {
2123 IXMLDOMDocument2_tid,
2128 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2133 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2135 return E_OUTOFMEMORY;
2137 doc->lpVtbl = &domdoc_vtbl;
2138 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2139 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2140 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2143 doc->validating = 0;
2145 doc->preserving = 0;
2146 doc->bUseXPath = FALSE;
2154 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2157 HeapFree(GetProcessHeap(), 0, doc);
2161 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2164 IUnknown_Release(doc->node_unk);
2165 HeapFree( GetProcessHeap(), 0, doc );
2169 init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2171 /* The ref on doc->node is actually looped back into this object, so release it */
2172 IXMLDOMNode_Release(doc->node);
2174 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2176 TRACE("returning iface %p\n", *document);
2180 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2185 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2187 xmldoc = xmlNewDoc(NULL);
2189 return E_OUTOFMEMORY;
2191 xmldoc->_private = create_priv();
2193 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2200 IUnknown* create_domdoc( xmlNodePtr document )
2205 TRACE("(%p)\n", document);
2207 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2211 return (IUnknown*)pObj;
2216 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2218 MESSAGE("This program tried to use a DOMDocument object, but\n"
2219 "libxml2 support was not present at compile time.\n");