2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 #include "msxml_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
50 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
51 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
52 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
54 typedef struct _domdoc
56 const struct IXMLDOMDocument2Vtbl *lpVtbl;
57 const struct IPersistStreamVtbl *lpvtblIPersistStream;
58 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
59 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
62 VARIANT_BOOL validating;
63 VARIANT_BOOL resolving;
64 VARIANT_BOOL preserving;
68 IXMLDOMSchemaCollection *schema;
86 In native windows, the whole lifetime management of XMLDOMNodes is
87 managed automatically using reference counts. Wine emulates that by
88 maintaining a reference count to the document that is increased for
89 each IXMLDOMNode pointer passed out for this document. If all these
90 pointers are gone, the document is unreachable and gets freed, that
91 is, all nodes in the tree of the document get freed.
93 You are able to create nodes that are associated to a document (in
94 fact, in msxml's XMLDOM model, all nodes are associated to a document),
95 but not in the tree of that document, for example using the createFoo
96 functions from IXMLDOMDocument. These nodes do not get cleaned up
97 by libxml, so we have to do it ourselves.
99 To catch these nodes, a list of "orphan nodes" is introduced.
100 It contains pointers to all roots of node trees that are
101 associated with the document without being part of the document
102 tree. All nodes with parent==NULL (except for the document root nodes)
103 should be in the orphan node list of their document. All orphan nodes
104 get freed together with the document itself.
107 typedef struct _xmldoc_priv {
112 typedef struct _orphan_entry {
117 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
119 return doc->_private;
122 static xmldoc_priv * create_priv(void)
125 priv = HeapAlloc( GetProcessHeap(), 0, sizeof (*priv) );
130 list_init( &priv->orphans );
136 static xmlDocPtr doparse( char *ptr, int len )
138 #ifdef HAVE_XMLREADMEMORY
140 * use xmlReadMemory if possible so we can suppress
141 * writing errors to stderr
143 return xmlReadMemory( ptr, len, NULL, NULL,
144 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
146 return xmlParseMemory( ptr, len );
150 LONG xmldoc_add_ref(xmlDocPtr doc)
152 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
157 LONG xmldoc_release(xmlDocPtr doc)
159 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
160 LONG ref = InterlockedDecrement(&priv->refs);
164 orphan_entry *orphan, *orphan2;
165 TRACE("freeing docptr %p\n", doc);
167 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
169 xmlFreeNode( orphan->node );
170 HeapFree( GetProcessHeap(), 0, orphan );
172 HeapFree(GetProcessHeap(), 0, doc->_private);
180 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
182 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
185 entry = HeapAlloc( GetProcessHeap(), 0, sizeof (*entry) );
187 return E_OUTOFMEMORY;
190 list_add_head( &priv->orphans, &entry->entry );
194 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
196 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
197 orphan_entry *entry, *entry2;
199 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
201 if( entry->node == node )
203 list_remove( &entry->entry );
204 HeapFree( GetProcessHeap(), 0, entry );
212 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
214 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
217 static inline xmlDocPtr get_doc( domdoc *This )
219 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
222 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
224 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
227 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
229 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
232 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
234 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
238 /************************************************************************
239 * xmldoc implementation of IPersistStream.
241 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
242 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
244 domdoc *this = impl_from_IPersistStream(iface);
245 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
248 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
249 IPersistStream *iface)
251 domdoc *this = impl_from_IPersistStream(iface);
252 return IXMLDocument_AddRef((IXMLDocument *)this);
255 static ULONG WINAPI xmldoc_IPersistStream_Release(
256 IPersistStream *iface)
258 domdoc *this = impl_from_IPersistStream(iface);
259 return IXMLDocument_Release((IXMLDocument *)this);
262 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
263 IPersistStream *iface, CLSID *classid)
265 TRACE("(%p,%p): stub!\n", iface, classid);
270 *classid = CLSID_DOMDocument2;
275 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
276 IPersistStream *iface)
278 domdoc *This = impl_from_IPersistStream(iface);
280 FIXME("(%p->%p): stub!\n", iface, This);
285 static HRESULT WINAPI xmldoc_IPersistStream_Load(
286 IPersistStream *iface, LPSTREAM pStm)
288 domdoc *This = impl_from_IPersistStream(iface);
291 DWORD read, written, len;
294 xmlDocPtr xmldoc = NULL;
296 TRACE("(%p, %p)\n", iface, pStm);
301 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
307 IStream_Read(pStm, buf, sizeof(buf), &read);
308 hr = IStream_Write(This->stream, buf, read, &written);
309 } while(SUCCEEDED(hr) && written != 0 && read != 0);
313 ERR("Failed to copy stream\n");
317 hr = GetHGlobalFromStream(This->stream, &hglobal);
321 len = GlobalSize(hglobal);
322 ptr = GlobalLock(hglobal);
324 xmldoc = parse_xml(ptr, len);
325 GlobalUnlock(hglobal);
329 ERR("Failed to parse xml\n");
333 attach_xmlnode( This->node, (xmlNodePtr)xmldoc );
338 static HRESULT WINAPI xmldoc_IPersistStream_Save(
339 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
341 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
345 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
346 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
348 TRACE("(%p, %p): stub!\n", iface, pcbSize);
352 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
354 xmldoc_IPersistStream_QueryInterface,
355 xmldoc_IPersistStream_AddRef,
356 xmldoc_IPersistStream_Release,
357 xmldoc_IPersistStream_GetClassID,
358 xmldoc_IPersistStream_IsDirty,
359 xmldoc_IPersistStream_Load,
360 xmldoc_IPersistStream_Save,
361 xmldoc_IPersistStream_GetSizeMax,
364 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
366 domdoc *This = impl_from_IXMLDOMDocument2( iface );
368 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
372 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
373 IsEqualGUID( riid, &IID_IDispatch ) ||
374 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
375 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
379 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
381 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
383 else if (IsEqualGUID(&IID_IPersistStream, riid))
385 *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
387 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
389 *ppvObject = (IObjectWithSite*)&(This->lpvtblIObjectWithSite);
391 else if(dispex_query_interface(&This->dispex, riid, ppvObject))
393 return *ppvObject ? S_OK : E_NOINTERFACE;
395 else if(IsEqualGUID(&IID_IRunnableObject, riid))
397 TRACE("IID_IRunnableObject not supported returning NULL\n");
398 return E_NOINTERFACE;
402 FIXME("interface %s not implemented\n", debugstr_guid(riid));
403 return E_NOINTERFACE;
406 IXMLDOMDocument_AddRef( iface );
412 static ULONG WINAPI domdoc_AddRef(
413 IXMLDOMDocument2 *iface )
415 domdoc *This = impl_from_IXMLDOMDocument2( iface );
416 TRACE("%p\n", This );
417 return InterlockedIncrement( &This->ref );
421 static ULONG WINAPI domdoc_Release(
422 IXMLDOMDocument2 *iface )
424 domdoc *This = impl_from_IXMLDOMDocument2( iface );
427 TRACE("%p\n", This );
429 ref = InterlockedDecrement( &This->ref );
433 detach_bsc(This->bsc);
436 IUnknown_Release( This->site );
437 IUnknown_Release( This->node_unk );
438 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
439 if (This->stream) IStream_Release(This->stream);
440 HeapFree( GetProcessHeap(), 0, This );
446 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
448 domdoc *This = impl_from_IXMLDOMDocument2( iface );
450 TRACE("(%p)->(%p)\n", This, pctinfo);
457 static HRESULT WINAPI domdoc_GetTypeInfo(
458 IXMLDOMDocument2 *iface,
459 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
461 domdoc *This = impl_from_IXMLDOMDocument2( iface );
464 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
466 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
471 static HRESULT WINAPI domdoc_GetIDsOfNames(
472 IXMLDOMDocument2 *iface,
479 domdoc *This = impl_from_IXMLDOMDocument2( iface );
483 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
486 if(!rgszNames || cNames == 0 || !rgDispId)
489 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
492 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
493 ITypeInfo_Release(typeinfo);
500 static HRESULT WINAPI domdoc_Invoke(
501 IXMLDOMDocument2 *iface,
506 DISPPARAMS* pDispParams,
508 EXCEPINFO* pExcepInfo,
511 domdoc *This = impl_from_IXMLDOMDocument2( iface );
515 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
516 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
518 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
521 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
522 pVarResult, pExcepInfo, puArgErr);
523 ITypeInfo_Release(typeinfo);
530 static HRESULT WINAPI domdoc_get_nodeName(
531 IXMLDOMDocument2 *iface,
534 domdoc *This = impl_from_IXMLDOMDocument2( iface );
535 return IXMLDOMNode_get_nodeName( This->node, name );
539 static HRESULT WINAPI domdoc_get_nodeValue(
540 IXMLDOMDocument2 *iface,
543 domdoc *This = impl_from_IXMLDOMDocument2( iface );
544 return IXMLDOMNode_get_nodeValue( This->node, value );
548 static HRESULT WINAPI domdoc_put_nodeValue(
549 IXMLDOMDocument2 *iface,
552 domdoc *This = impl_from_IXMLDOMDocument2( iface );
553 return IXMLDOMNode_put_nodeValue( This->node, value );
557 static HRESULT WINAPI domdoc_get_nodeType(
558 IXMLDOMDocument2 *iface,
561 domdoc *This = impl_from_IXMLDOMDocument2( iface );
562 return IXMLDOMNode_get_nodeType( This->node, type );
566 static HRESULT WINAPI domdoc_get_parentNode(
567 IXMLDOMDocument2 *iface,
568 IXMLDOMNode** parent )
570 domdoc *This = impl_from_IXMLDOMDocument2( iface );
571 return IXMLDOMNode_get_parentNode( This->node, parent );
575 static HRESULT WINAPI domdoc_get_childNodes(
576 IXMLDOMDocument2 *iface,
577 IXMLDOMNodeList** childList )
579 domdoc *This = impl_from_IXMLDOMDocument2( iface );
580 return IXMLDOMNode_get_childNodes( This->node, childList );
584 static HRESULT WINAPI domdoc_get_firstChild(
585 IXMLDOMDocument2 *iface,
586 IXMLDOMNode** firstChild )
588 domdoc *This = impl_from_IXMLDOMDocument2( iface );
589 return IXMLDOMNode_get_firstChild( This->node, firstChild );
593 static HRESULT WINAPI domdoc_get_lastChild(
594 IXMLDOMDocument2 *iface,
595 IXMLDOMNode** lastChild )
597 domdoc *This = impl_from_IXMLDOMDocument2( iface );
598 return IXMLDOMNode_get_lastChild( This->node, lastChild );
602 static HRESULT WINAPI domdoc_get_previousSibling(
603 IXMLDOMDocument2 *iface,
604 IXMLDOMNode** previousSibling )
606 domdoc *This = impl_from_IXMLDOMDocument2( iface );
607 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
611 static HRESULT WINAPI domdoc_get_nextSibling(
612 IXMLDOMDocument2 *iface,
613 IXMLDOMNode** nextSibling )
615 domdoc *This = impl_from_IXMLDOMDocument2( iface );
616 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
620 static HRESULT WINAPI domdoc_get_attributes(
621 IXMLDOMDocument2 *iface,
622 IXMLDOMNamedNodeMap** attributeMap )
624 domdoc *This = impl_from_IXMLDOMDocument2( iface );
625 return IXMLDOMNode_get_attributes( This->node, attributeMap );
629 static HRESULT WINAPI domdoc_insertBefore(
630 IXMLDOMDocument2 *iface,
631 IXMLDOMNode* newChild,
633 IXMLDOMNode** outNewChild )
635 domdoc *This = impl_from_IXMLDOMDocument2( iface );
636 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
640 static HRESULT WINAPI domdoc_replaceChild(
641 IXMLDOMDocument2 *iface,
642 IXMLDOMNode* newChild,
643 IXMLDOMNode* oldChild,
644 IXMLDOMNode** outOldChild)
646 domdoc *This = impl_from_IXMLDOMDocument2( iface );
647 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
651 static HRESULT WINAPI domdoc_removeChild(
652 IXMLDOMDocument2 *iface,
653 IXMLDOMNode* childNode,
654 IXMLDOMNode** oldChild)
656 domdoc *This = impl_from_IXMLDOMDocument2( iface );
657 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
661 static HRESULT WINAPI domdoc_appendChild(
662 IXMLDOMDocument2 *iface,
663 IXMLDOMNode* newChild,
664 IXMLDOMNode** outNewChild)
666 domdoc *This = impl_from_IXMLDOMDocument2( iface );
667 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
671 static HRESULT WINAPI domdoc_hasChildNodes(
672 IXMLDOMDocument2 *iface,
673 VARIANT_BOOL* hasChild)
675 domdoc *This = impl_from_IXMLDOMDocument2( iface );
676 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
680 static HRESULT WINAPI domdoc_get_ownerDocument(
681 IXMLDOMDocument2 *iface,
682 IXMLDOMDocument** DOMDocument)
684 domdoc *This = impl_from_IXMLDOMDocument2( iface );
685 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
689 static HRESULT WINAPI domdoc_cloneNode(
690 IXMLDOMDocument2 *iface,
692 IXMLDOMNode** cloneRoot)
694 domdoc *This = impl_from_IXMLDOMDocument2( iface );
695 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
699 static HRESULT WINAPI domdoc_get_nodeTypeString(
700 IXMLDOMDocument2 *iface,
703 domdoc *This = impl_from_IXMLDOMDocument2( iface );
704 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
708 static HRESULT WINAPI domdoc_get_text(
709 IXMLDOMDocument2 *iface,
712 domdoc *This = impl_from_IXMLDOMDocument2( iface );
713 return IXMLDOMNode_get_text( This->node, text );
717 static HRESULT WINAPI domdoc_put_text(
718 IXMLDOMDocument2 *iface,
721 domdoc *This = impl_from_IXMLDOMDocument2( iface );
722 return IXMLDOMNode_put_text( This->node, text );
726 static HRESULT WINAPI domdoc_get_specified(
727 IXMLDOMDocument2 *iface,
728 VARIANT_BOOL* isSpecified )
730 domdoc *This = impl_from_IXMLDOMDocument2( iface );
731 return IXMLDOMNode_get_specified( This->node, isSpecified );
735 static HRESULT WINAPI domdoc_get_definition(
736 IXMLDOMDocument2 *iface,
737 IXMLDOMNode** definitionNode )
739 domdoc *This = impl_from_IXMLDOMDocument2( iface );
740 return IXMLDOMNode_get_definition( This->node, definitionNode );
744 static HRESULT WINAPI domdoc_get_nodeTypedValue(
745 IXMLDOMDocument2 *iface,
746 VARIANT* typedValue )
748 domdoc *This = impl_from_IXMLDOMDocument2( iface );
749 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
752 static HRESULT WINAPI domdoc_put_nodeTypedValue(
753 IXMLDOMDocument2 *iface,
756 domdoc *This = impl_from_IXMLDOMDocument2( iface );
757 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
761 static HRESULT WINAPI domdoc_get_dataType(
762 IXMLDOMDocument2 *iface,
763 VARIANT* dataTypeName )
765 domdoc *This = impl_from_IXMLDOMDocument2( iface );
766 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
770 static HRESULT WINAPI domdoc_put_dataType(
771 IXMLDOMDocument2 *iface,
774 domdoc *This = impl_from_IXMLDOMDocument2( iface );
775 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
779 static HRESULT WINAPI domdoc_get_xml(
780 IXMLDOMDocument2 *iface,
783 domdoc *This = impl_from_IXMLDOMDocument2( iface );
784 return IXMLDOMNode_get_xml( This->node, xmlString );
788 static HRESULT WINAPI domdoc_transformNode(
789 IXMLDOMDocument2 *iface,
790 IXMLDOMNode* styleSheet,
793 domdoc *This = impl_from_IXMLDOMDocument2( iface );
794 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
798 static HRESULT WINAPI domdoc_selectNodes(
799 IXMLDOMDocument2 *iface,
801 IXMLDOMNodeList** resultList )
803 domdoc *This = impl_from_IXMLDOMDocument2( iface );
804 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
808 static HRESULT WINAPI domdoc_selectSingleNode(
809 IXMLDOMDocument2 *iface,
811 IXMLDOMNode** resultNode )
813 domdoc *This = impl_from_IXMLDOMDocument2( iface );
814 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
818 static HRESULT WINAPI domdoc_get_parsed(
819 IXMLDOMDocument2 *iface,
820 VARIANT_BOOL* isParsed )
822 domdoc *This = impl_from_IXMLDOMDocument2( iface );
823 return IXMLDOMNode_get_parsed( This->node, isParsed );
827 static HRESULT WINAPI domdoc_get_namespaceURI(
828 IXMLDOMDocument2 *iface,
831 domdoc *This = impl_from_IXMLDOMDocument2( iface );
832 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
836 static HRESULT WINAPI domdoc_get_prefix(
837 IXMLDOMDocument2 *iface,
840 domdoc *This = impl_from_IXMLDOMDocument2( iface );
841 return IXMLDOMNode_get_prefix( This->node, prefixString );
845 static HRESULT WINAPI domdoc_get_baseName(
846 IXMLDOMDocument2 *iface,
849 domdoc *This = impl_from_IXMLDOMDocument2( iface );
850 return IXMLDOMNode_get_baseName( This->node, nameString );
854 static HRESULT WINAPI domdoc_transformNodeToObject(
855 IXMLDOMDocument2 *iface,
856 IXMLDOMNode* stylesheet,
857 VARIANT outputObject)
859 domdoc *This = impl_from_IXMLDOMDocument2( iface );
860 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
864 static HRESULT WINAPI domdoc_get_doctype(
865 IXMLDOMDocument2 *iface,
866 IXMLDOMDocumentType** documentType )
873 static HRESULT WINAPI domdoc_get_implementation(
874 IXMLDOMDocument2 *iface,
875 IXMLDOMImplementation** impl )
880 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
885 static HRESULT WINAPI domdoc_get_documentElement(
886 IXMLDOMDocument2 *iface,
887 IXMLDOMElement** DOMElement )
889 domdoc *This = impl_from_IXMLDOMDocument2( iface );
890 xmlDocPtr xmldoc = NULL;
891 xmlNodePtr root = NULL;
892 IXMLDOMNode *element_node;
895 TRACE("%p %p\n", This, This->node);
902 xmldoc = get_doc( This );
904 root = xmlDocGetRootElement( xmldoc );
908 element_node = create_node( root );
909 if(!element_node) return S_FALSE;
911 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
912 IXMLDOMNode_Release(element_node);
918 static HRESULT WINAPI domdoc_put_documentElement(
919 IXMLDOMDocument2 *iface,
920 IXMLDOMElement* DOMElement )
922 domdoc *This = impl_from_IXMLDOMDocument2( iface );
923 IXMLDOMNode *elementNode;
927 TRACE("(%p)->(%p)\n", This, DOMElement);
929 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
933 xmlNode = impl_from_IXMLDOMNode( elementNode );
934 xmlDocSetRootElement( get_doc(This), xmlNode->node);
935 IXMLDOMNode_Release( elementNode );
941 static HRESULT WINAPI domdoc_createElement(
942 IXMLDOMDocument2 *iface,
944 IXMLDOMElement** element )
947 domdoc *This = impl_from_IXMLDOMDocument2( iface );
952 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
954 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
955 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
957 TRACE("created xmlptr %p\n", xmlnode);
958 elem_unk = create_element(xmlnode, NULL);
959 HeapFree(GetProcessHeap(), 0, xml_name);
961 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
962 IUnknown_Release(elem_unk);
963 TRACE("returning %p\n", *element);
968 static HRESULT WINAPI domdoc_createDocumentFragment(
969 IXMLDOMDocument2 *iface,
970 IXMLDOMDocumentFragment** docFrag )
972 domdoc *This = impl_from_IXMLDOMDocument2( iface );
975 TRACE("%p\n", iface);
982 xmlnode = xmlNewDocFragment(get_doc( This ) );
987 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
993 static HRESULT WINAPI domdoc_createTextNode(
994 IXMLDOMDocument2 *iface,
998 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1000 xmlChar *xml_content;
1002 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1005 return E_INVALIDARG;
1009 xml_content = xmlChar_from_wchar((WCHAR*)data);
1010 xmlnode = xmlNewText(xml_content);
1011 HeapFree(GetProcessHeap(), 0, xml_content);
1016 xmlnode->doc = get_doc( This );
1018 *text = (IXMLDOMText*)create_text(xmlnode);
1024 static HRESULT WINAPI domdoc_createComment(
1025 IXMLDOMDocument2 *iface,
1027 IXMLDOMComment** comment )
1029 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1031 xmlChar *xml_content;
1033 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1036 return E_INVALIDARG;
1040 xml_content = xmlChar_from_wchar((WCHAR*)data);
1041 xmlnode = xmlNewComment(xml_content);
1042 HeapFree(GetProcessHeap(), 0, xml_content);
1047 xmlnode->doc = get_doc( This );
1049 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1055 static HRESULT WINAPI domdoc_createCDATASection(
1056 IXMLDOMDocument2 *iface,
1058 IXMLDOMCDATASection** cdata )
1060 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1062 xmlChar *xml_content;
1064 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1067 return E_INVALIDARG;
1071 xml_content = xmlChar_from_wchar((WCHAR*)data);
1072 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1073 HeapFree(GetProcessHeap(), 0, xml_content);
1078 xmlnode->doc = get_doc( This );
1080 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1086 static HRESULT WINAPI domdoc_createProcessingInstruction(
1087 IXMLDOMDocument2 *iface,
1090 IXMLDOMProcessingInstruction** pi )
1092 #ifdef HAVE_XMLNEWDOCPI
1094 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1095 xmlChar *xml_target, *xml_content;
1097 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1100 return E_INVALIDARG;
1102 if(!target || lstrlenW(target) == 0)
1105 xml_target = xmlChar_from_wchar((WCHAR*)target);
1106 xml_content = xmlChar_from_wchar((WCHAR*)data);
1108 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1109 TRACE("created xmlptr %p\n", xmlnode);
1110 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1112 HeapFree(GetProcessHeap(), 0, xml_content);
1113 HeapFree(GetProcessHeap(), 0, xml_target);
1117 FIXME("Libxml 2.6.15 or greater required.\n");
1123 static HRESULT WINAPI domdoc_createAttribute(
1124 IXMLDOMDocument2 *iface,
1126 IXMLDOMAttribute** attribute )
1128 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1132 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1135 return E_INVALIDARG;
1139 xml_name = xmlChar_from_wchar((WCHAR*)name);
1140 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1141 HeapFree(GetProcessHeap(), 0, xml_name);
1146 xmlnode->doc = get_doc( This );
1148 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1154 static HRESULT WINAPI domdoc_createEntityReference(
1155 IXMLDOMDocument2 *iface,
1157 IXMLDOMEntityReference** entityRef )
1159 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1163 TRACE("%p\n", iface);
1166 return E_INVALIDARG;
1170 xml_name = xmlChar_from_wchar((WCHAR*)name);
1171 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1172 HeapFree(GetProcessHeap(), 0, xml_name);
1177 xmlnode->doc = get_doc( This );
1179 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1185 static HRESULT WINAPI domdoc_getElementsByTagName(
1186 IXMLDOMDocument2 *iface,
1188 IXMLDOMNodeList** resultList )
1190 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1193 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1195 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1196 szPattern[0] = szPattern[1] = '/';
1197 lstrcpyW(szPattern + 2, tagName);
1199 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1200 HeapFree(GetProcessHeap(), 0, szPattern);
1205 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1211 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1213 return E_INVALIDARG;
1220 static HRESULT WINAPI domdoc_createNode(
1221 IXMLDOMDocument2 *iface,
1225 IXMLDOMNode** node )
1227 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1228 DOMNodeType node_type;
1229 xmlNodePtr xmlnode = NULL;
1233 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1235 hr = get_node_type(Type, &node_type);
1239 TRACE("node_type %d\n", node_type);
1241 xml_name = xmlChar_from_wchar((WCHAR*)name);
1246 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1247 *node = create_node(xmlnode);
1248 TRACE("created %p\n", xmlnode);
1250 case NODE_ATTRIBUTE:
1251 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1254 xmlnode->doc = get_doc( This );
1256 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1259 TRACE("created %p\n", xmlnode);
1263 FIXME("unhandled node type %d\n", node_type);
1267 HeapFree(GetProcessHeap(), 0, xml_name);
1269 if(xmlnode && *node)
1275 static HRESULT WINAPI domdoc_nodeFromID(
1276 IXMLDOMDocument2 *iface,
1278 IXMLDOMNode** node )
1284 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1289 xmldoc = doparse( ptr, len );
1291 xmldoc->_private = create_priv();
1292 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1298 static HRESULT doread( domdoc *This, LPWSTR filename )
1303 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1308 detach_bsc(This->bsc);
1314 static HRESULT WINAPI domdoc_load(
1315 IXMLDOMDocument2 *iface,
1317 VARIANT_BOOL* isSuccessful )
1319 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1320 LPWSTR filename = NULL;
1321 HRESULT hr = S_FALSE;
1322 IXMLDOMDocument2 *pNewDoc = NULL;
1323 IStream *pStream = NULL;
1326 TRACE("type %d\n", V_VT(&xmlSource) );
1328 *isSuccessful = VARIANT_FALSE;
1330 assert( This->node );
1332 attach_xmlnode(This->node, NULL);
1334 switch( V_VT(&xmlSource) )
1337 filename = V_BSTR(&xmlSource);
1340 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1345 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1346 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1347 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1349 *isSuccessful = VARIANT_TRUE;
1354 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1357 IPersistStream *pDocStream;
1358 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1361 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1362 IStream_Release(pStream);
1365 *isSuccessful = VARIANT_TRUE;
1367 TRACE("Using ID_IStream to load Document\n");
1372 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1377 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1382 /* ISequentialStream */
1383 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1387 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1390 TRACE("filename (%s)\n", debugstr_w(filename));
1394 hr = doread( This, filename );
1397 This->error = E_FAIL;
1400 hr = This->error = S_OK;
1401 *isSuccessful = VARIANT_TRUE;
1405 if(!filename || FAILED(hr)) {
1406 xmldoc = xmlNewDoc(NULL);
1407 xmldoc->_private = create_priv();
1408 attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
1412 TRACE("ret (%d)\n", hr);
1418 static HRESULT WINAPI domdoc_get_readyState(
1419 IXMLDOMDocument2 *iface,
1427 static HRESULT WINAPI domdoc_get_parseError(
1428 IXMLDOMDocument2 *iface,
1429 IXMLDOMParseError** errorObj )
1431 BSTR error_string = NULL;
1432 static const WCHAR err[] = {'e','r','r','o','r',0};
1433 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1435 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1438 error_string = SysAllocString(err);
1440 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1441 if(!*errorObj) return E_OUTOFMEMORY;
1446 static HRESULT WINAPI domdoc_get_url(
1447 IXMLDOMDocument2 *iface,
1455 static HRESULT WINAPI domdoc_get_async(
1456 IXMLDOMDocument2 *iface,
1457 VARIANT_BOOL* isAsync )
1459 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1461 TRACE("%p <- %d\n", isAsync, This->async);
1462 *isAsync = This->async;
1467 static HRESULT WINAPI domdoc_put_async(
1468 IXMLDOMDocument2 *iface,
1469 VARIANT_BOOL isAsync )
1471 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1473 TRACE("%d\n", isAsync);
1474 This->async = isAsync;
1479 static HRESULT WINAPI domdoc_abort(
1480 IXMLDOMDocument2 *iface )
1487 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1489 UINT len, blen = SysStringLen( bstr );
1492 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1493 str = HeapAlloc( GetProcessHeap(), 0, len );
1496 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1502 static HRESULT WINAPI domdoc_loadXML(
1503 IXMLDOMDocument2 *iface,
1505 VARIANT_BOOL* isSuccessful )
1507 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1508 xmlDocPtr xmldoc = NULL;
1511 HRESULT hr = S_FALSE;
1513 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1515 assert ( This->node );
1517 attach_xmlnode( This->node, NULL );
1521 *isSuccessful = VARIANT_FALSE;
1523 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1525 xmldoc = doparse( str, len );
1526 HeapFree( GetProcessHeap(), 0, str );
1528 This->error = E_FAIL;
1531 hr = This->error = S_OK;
1532 *isSuccessful = VARIANT_TRUE;
1537 xmldoc = xmlNewDoc(NULL);
1539 xmldoc->_private = create_priv();
1540 attach_xmlnode( This->node, (xmlNodePtr) xmldoc );
1546 static HRESULT WINAPI domdoc_save(
1547 IXMLDOMDocument2 *iface,
1548 VARIANT destination )
1550 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1557 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1558 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1560 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1562 FIXME("Unhandled vt %d\n", V_VT(&destination));
1566 if(V_VT(&destination) == VT_UNKNOWN)
1568 IUnknown *pUnk = V_UNKNOWN(&destination);
1569 IXMLDOMDocument *pDocument;
1571 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1575 VARIANT_BOOL bSuccessful;
1577 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1580 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1582 SysFreeString(bXML);
1585 IXMLDOMDocument_Release(pDocument);
1588 TRACE("ret %d\n", ret);
1593 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1594 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1595 if( handle == INVALID_HANDLE_VALUE )
1597 WARN("failed to create file\n");
1601 xmlDocDumpMemory(get_doc(This), &mem, &size);
1604 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1605 * MSXML adds XML declaration only for processing instruction nodes.
1606 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1609 if(size > 2 && p[0] == '<' && p[1] == '?') {
1610 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1613 while(p < mem+size && isspace(*p))
1618 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1620 WARN("write error\n");
1625 CloseHandle(handle);
1629 static HRESULT WINAPI domdoc_get_validateOnParse(
1630 IXMLDOMDocument2 *iface,
1631 VARIANT_BOOL* isValidating )
1633 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1635 TRACE("%p <- %d\n", isValidating, This->validating);
1636 *isValidating = This->validating;
1641 static HRESULT WINAPI domdoc_put_validateOnParse(
1642 IXMLDOMDocument2 *iface,
1643 VARIANT_BOOL isValidating )
1645 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1647 TRACE("%d\n", isValidating);
1648 This->validating = isValidating;
1653 static HRESULT WINAPI domdoc_get_resolveExternals(
1654 IXMLDOMDocument2 *iface,
1655 VARIANT_BOOL* isResolving )
1657 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1659 TRACE("%p <- %d\n", isResolving, This->resolving);
1660 *isResolving = This->resolving;
1665 static HRESULT WINAPI domdoc_put_resolveExternals(
1666 IXMLDOMDocument2 *iface,
1667 VARIANT_BOOL isResolving )
1669 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1671 TRACE("%d\n", isResolving);
1672 This->resolving = isResolving;
1677 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1678 IXMLDOMDocument2 *iface,
1679 VARIANT_BOOL* isPreserving )
1681 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1683 TRACE("%p <- %d\n", isPreserving, This->preserving);
1684 *isPreserving = This->preserving;
1689 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1690 IXMLDOMDocument2 *iface,
1691 VARIANT_BOOL isPreserving )
1693 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1695 TRACE("%d\n", isPreserving);
1696 This->preserving = isPreserving;
1701 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1702 IXMLDOMDocument2 *iface,
1703 VARIANT readyStateChangeSink )
1710 static HRESULT WINAPI domdoc_put_onDataAvailable(
1711 IXMLDOMDocument2 *iface,
1712 VARIANT onDataAvailableSink )
1718 static HRESULT WINAPI domdoc_put_onTransformNode(
1719 IXMLDOMDocument2 *iface,
1720 VARIANT onTransformNodeSink )
1726 static HRESULT WINAPI domdoc_get_namespaces(
1727 IXMLDOMDocument2* iface,
1728 IXMLDOMSchemaCollection** schemaCollection )
1734 static HRESULT WINAPI domdoc_get_schemas(
1735 IXMLDOMDocument2* iface,
1738 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1739 HRESULT hr = S_FALSE;
1740 IXMLDOMSchemaCollection *cur_schema = This->schema;
1742 TRACE("(%p)->(%p)\n", This, var1);
1744 VariantInit(var1); /* Test shows we don't call VariantClear here */
1745 V_VT(var1) = VT_NULL;
1749 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1751 V_VT(var1) = VT_DISPATCH;
1756 static HRESULT WINAPI domdoc_putref_schemas(
1757 IXMLDOMDocument2* iface,
1760 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1761 HRESULT hr = E_FAIL;
1762 IXMLDOMSchemaCollection *new_schema = NULL;
1764 FIXME("(%p): semi-stub\n", This);
1768 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1772 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1781 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1786 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1787 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1793 static HRESULT WINAPI domdoc_validate(
1794 IXMLDOMDocument2* iface,
1795 IXMLDOMParseError** err)
1801 static HRESULT WINAPI domdoc_setProperty(
1802 IXMLDOMDocument2* iface,
1806 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1808 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1814 V_VT(&varStr) = VT_EMPTY;
1815 if (V_VT(&var) != VT_BSTR)
1817 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1819 bstr = V_BSTR(&varStr);
1822 bstr = V_BSTR(&var);
1825 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1826 This->bUseXPath = TRUE;
1827 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1828 This->bUseXPath = FALSE;
1832 VariantClear(&varStr);
1836 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1840 static HRESULT WINAPI domdoc_getProperty(
1841 IXMLDOMDocument2* iface,
1845 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1848 return E_INVALIDARG;
1849 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1851 V_VT(var) = VT_BSTR;
1852 if (This->bUseXPath)
1853 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1855 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1859 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1863 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1865 domdoc_QueryInterface,
1868 domdoc_GetTypeInfoCount,
1870 domdoc_GetIDsOfNames,
1872 domdoc_get_nodeName,
1873 domdoc_get_nodeValue,
1874 domdoc_put_nodeValue,
1875 domdoc_get_nodeType,
1876 domdoc_get_parentNode,
1877 domdoc_get_childNodes,
1878 domdoc_get_firstChild,
1879 domdoc_get_lastChild,
1880 domdoc_get_previousSibling,
1881 domdoc_get_nextSibling,
1882 domdoc_get_attributes,
1883 domdoc_insertBefore,
1884 domdoc_replaceChild,
1887 domdoc_hasChildNodes,
1888 domdoc_get_ownerDocument,
1890 domdoc_get_nodeTypeString,
1893 domdoc_get_specified,
1894 domdoc_get_definition,
1895 domdoc_get_nodeTypedValue,
1896 domdoc_put_nodeTypedValue,
1897 domdoc_get_dataType,
1898 domdoc_put_dataType,
1900 domdoc_transformNode,
1902 domdoc_selectSingleNode,
1904 domdoc_get_namespaceURI,
1906 domdoc_get_baseName,
1907 domdoc_transformNodeToObject,
1909 domdoc_get_implementation,
1910 domdoc_get_documentElement,
1911 domdoc_put_documentElement,
1912 domdoc_createElement,
1913 domdoc_createDocumentFragment,
1914 domdoc_createTextNode,
1915 domdoc_createComment,
1916 domdoc_createCDATASection,
1917 domdoc_createProcessingInstruction,
1918 domdoc_createAttribute,
1919 domdoc_createEntityReference,
1920 domdoc_getElementsByTagName,
1924 domdoc_get_readyState,
1925 domdoc_get_parseError,
1932 domdoc_get_validateOnParse,
1933 domdoc_put_validateOnParse,
1934 domdoc_get_resolveExternals,
1935 domdoc_put_resolveExternals,
1936 domdoc_get_preserveWhiteSpace,
1937 domdoc_put_preserveWhiteSpace,
1938 domdoc_put_onReadyStateChange,
1939 domdoc_put_onDataAvailable,
1940 domdoc_put_onTransformNode,
1941 domdoc_get_namespaces,
1943 domdoc_putref_schemas,
1949 /* xmldoc implementation of IObjectWithSite */
1950 static HRESULT WINAPI
1951 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
1953 domdoc *This = impl_from_IObjectWithSite(iface);
1954 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
1958 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
1960 domdoc *This = impl_from_IObjectWithSite(iface);
1961 return IXMLDocument_AddRef((IXMLDocument *)This);
1965 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
1967 domdoc *This = impl_from_IObjectWithSite(iface);
1968 return IXMLDocument_Release((IXMLDocument *)This);
1971 static HRESULT WINAPI
1972 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
1974 domdoc *This = impl_from_IObjectWithSite(iface);
1976 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
1981 return IUnknown_QueryInterface( This->site, iid, ppvSite );
1984 static HRESULT WINAPI
1985 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
1987 domdoc *This = impl_from_IObjectWithSite(iface);
1989 TRACE("%p %p\n", iface, punk);
1995 IUnknown_Release( This->site );
2003 IUnknown_AddRef( punk );
2006 IUnknown_Release( This->site );
2013 static const IObjectWithSiteVtbl domdocObjectSite =
2015 xmldoc_ObjectWithSite_QueryInterface,
2016 xmldoc_ObjectWithSite_AddRef,
2017 xmldoc_ObjectWithSite_Release,
2022 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2024 domdoc *This = impl_from_IObjectSafety(iface);
2025 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2028 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2030 domdoc *This = impl_from_IObjectSafety(iface);
2031 return IXMLDocument_AddRef((IXMLDocument *)This);
2034 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2036 domdoc *This = impl_from_IObjectSafety(iface);
2037 return IXMLDocument_Release((IXMLDocument *)This);
2040 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2042 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2043 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2045 domdoc *This = impl_from_IObjectSafety(iface);
2047 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2049 if(!pdwSupportedOptions || !pdwEnabledOptions)
2052 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2053 *pdwEnabledOptions = This->safeopt;
2058 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2059 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2061 domdoc *This = impl_from_IObjectSafety(iface);
2063 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2065 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2068 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2072 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2073 xmldoc_Safety_QueryInterface,
2074 xmldoc_Safety_AddRef,
2075 xmldoc_Safety_Release,
2076 xmldoc_Safety_GetInterfaceSafetyOptions,
2077 xmldoc_Safety_SetInterfaceSafetyOptions
2081 static const tid_t domdoc_iface_tids[] = {
2083 IXMLDOMDocument_tid,
2084 IXMLDOMDocument2_tid,
2087 static dispex_static_data_t domdoc_dispex = {
2089 IXMLDOMDocument2_tid,
2094 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2099 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2101 return E_OUTOFMEMORY;
2103 doc->lpVtbl = &domdoc_vtbl;
2104 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2105 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2106 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2109 doc->validating = 0;
2111 doc->preserving = 0;
2112 doc->bUseXPath = FALSE;
2120 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2123 HeapFree(GetProcessHeap(), 0, doc);
2127 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2130 IUnknown_Release(doc->node_unk);
2131 HeapFree( GetProcessHeap(), 0, doc );
2135 init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2137 /* The ref on doc->node is actually looped back into this object, so release it */
2138 IXMLDOMNode_Release(doc->node);
2140 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2142 TRACE("returning iface %p\n", *document);
2146 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2151 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2153 xmldoc = xmlNewDoc(NULL);
2155 return E_OUTOFMEMORY;
2157 xmldoc->_private = create_priv();
2159 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2166 IUnknown* create_domdoc( xmlNodePtr document )
2171 TRACE("(%p)\n", document);
2173 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2177 return (IUnknown*)pObj;
2182 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2184 MESSAGE("This program tried to use a DOMDocument object, but\n"
2185 "libxml2 support was not present at compile time.\n");