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 #include <libxml/xmlsave.h>
52 /* not defined in older versions */
53 #define XML_SAVE_FORMAT 1
54 #define XML_SAVE_NO_DECL 2
55 #define XML_SAVE_NO_EMPTY 4
56 #define XML_SAVE_NO_XHTML 8
57 #define XML_SAVE_XHTML 16
58 #define XML_SAVE_AS_XML 32
59 #define XML_SAVE_AS_HTML 64
61 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};
62 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
63 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
65 typedef struct _domdoc
68 const struct IXMLDOMDocument2Vtbl *lpVtbl;
69 const struct IPersistStreamVtbl *lpvtblIPersistStream;
70 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
71 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
72 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
75 VARIANT_BOOL validating;
76 VARIANT_BOOL resolving;
77 VARIANT_BOOL preserving;
79 IXMLDOMSchemaCollection *schema;
94 In native windows, the whole lifetime management of XMLDOMNodes is
95 managed automatically using reference counts. Wine emulates that by
96 maintaining a reference count to the document that is increased for
97 each IXMLDOMNode pointer passed out for this document. If all these
98 pointers are gone, the document is unreachable and gets freed, that
99 is, all nodes in the tree of the document get freed.
101 You are able to create nodes that are associated to a document (in
102 fact, in msxml's XMLDOM model, all nodes are associated to a document),
103 but not in the tree of that document, for example using the createFoo
104 functions from IXMLDOMDocument. These nodes do not get cleaned up
105 by libxml, so we have to do it ourselves.
107 To catch these nodes, a list of "orphan nodes" is introduced.
108 It contains pointers to all roots of node trees that are
109 associated with the document without being part of the document
110 tree. All nodes with parent==NULL (except for the document root nodes)
111 should be in the orphan node list of their document. All orphan nodes
112 get freed together with the document itself.
115 typedef struct _xmldoc_priv {
120 typedef struct _orphan_entry {
125 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
127 return doc->_private;
130 static xmldoc_priv * create_priv(void)
133 priv = heap_alloc( sizeof (*priv) );
138 list_init( &priv->orphans );
144 static xmlDocPtr doparse( char *ptr, int len )
146 #ifdef HAVE_XMLREADMEMORY
148 * use xmlReadMemory if possible so we can suppress
149 * writing errors to stderr
151 return xmlReadMemory( ptr, len, NULL, NULL,
152 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
154 return xmlParseMemory( ptr, len );
158 LONG xmldoc_add_ref(xmlDocPtr doc)
160 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
165 LONG xmldoc_release(xmlDocPtr doc)
167 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
168 LONG ref = InterlockedDecrement(&priv->refs);
172 orphan_entry *orphan, *orphan2;
173 TRACE("freeing docptr %p\n", doc);
175 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
177 xmlFreeNode( orphan->node );
180 heap_free(doc->_private);
188 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
190 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
193 entry = heap_alloc( sizeof (*entry) );
195 return E_OUTOFMEMORY;
198 list_add_head( &priv->orphans, &entry->entry );
202 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
204 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
205 orphan_entry *entry, *entry2;
207 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
209 if( entry->node == node )
211 list_remove( &entry->entry );
220 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
223 xmldoc_release(node->node->doc);
225 node->node = (xmlNodePtr) xml;
227 xmldoc_add_ref(node->node->doc);
232 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
234 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
237 static inline xmlDocPtr get_doc( domdoc *This )
239 return (xmlDocPtr)This->node.node;
242 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
244 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
247 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
249 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
252 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
254 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
257 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
259 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
262 /************************************************************************
263 * xmldoc implementation of IPersistStream.
265 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
266 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
268 domdoc *this = impl_from_IPersistStream(iface);
269 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
272 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
273 IPersistStream *iface)
275 domdoc *this = impl_from_IPersistStream(iface);
276 return IXMLDocument_AddRef((IXMLDocument *)this);
279 static ULONG WINAPI xmldoc_IPersistStream_Release(
280 IPersistStream *iface)
282 domdoc *this = impl_from_IPersistStream(iface);
283 return IXMLDocument_Release((IXMLDocument *)this);
286 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
287 IPersistStream *iface, CLSID *classid)
289 TRACE("(%p,%p): stub!\n", iface, classid);
294 *classid = CLSID_DOMDocument2;
299 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
300 IPersistStream *iface)
302 domdoc *This = impl_from_IPersistStream(iface);
304 FIXME("(%p): stub!\n", This);
309 static HRESULT WINAPI xmldoc_IPersistStream_Load(
310 IPersistStream *iface, LPSTREAM pStm)
312 domdoc *This = impl_from_IPersistStream(iface);
315 DWORD read, written, len;
318 xmlDocPtr xmldoc = NULL;
320 TRACE("(%p)->(%p)\n", This, pStm);
325 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
331 IStream_Read(pStm, buf, sizeof(buf), &read);
332 hr = IStream_Write(This->stream, buf, read, &written);
333 } while(SUCCEEDED(hr) && written != 0 && read != 0);
337 ERR("Failed to copy stream\n");
341 hr = GetHGlobalFromStream(This->stream, &hglobal);
345 len = GlobalSize(hglobal);
346 ptr = GlobalLock(hglobal);
348 xmldoc = parse_xml(ptr, len);
349 GlobalUnlock(hglobal);
353 ERR("Failed to parse xml\n");
357 xmldoc->_private = create_priv();
359 return attach_xmldoc( &This->node, xmldoc );
362 static HRESULT WINAPI xmldoc_IPersistStream_Save(
363 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
365 domdoc *This = impl_from_IPersistStream(iface);
369 TRACE("(%p)->(%p %d)\n", This, pStm, fClearDirty);
371 hr = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), &xmlString );
375 DWORD len = strlenW(xmlString) * sizeof(WCHAR);
377 hr = IStream_Write( pStm, xmlString, len, &count );
379 SysFreeString(xmlString);
382 TRACE("ret 0x%08x\n", hr);
387 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
388 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
390 domdoc *This = impl_from_IPersistStream(iface);
391 TRACE("(%p)->(%p): stub!\n", This, pcbSize);
395 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
397 xmldoc_IPersistStream_QueryInterface,
398 xmldoc_IPersistStream_AddRef,
399 xmldoc_IPersistStream_Release,
400 xmldoc_IPersistStream_GetClassID,
401 xmldoc_IPersistStream_IsDirty,
402 xmldoc_IPersistStream_Load,
403 xmldoc_IPersistStream_Save,
404 xmldoc_IPersistStream_GetSizeMax,
407 /* ISupportErrorInfo interface */
408 static HRESULT WINAPI support_error_QueryInterface(
409 ISupportErrorInfo *iface,
410 REFIID riid, void** ppvObj )
412 domdoc *This = impl_from_ISupportErrorInfo(iface);
413 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
416 static ULONG WINAPI support_error_AddRef(
417 ISupportErrorInfo *iface )
419 domdoc *This = impl_from_ISupportErrorInfo(iface);
420 return IXMLDocument_AddRef((IXMLDocument *)This);
423 static ULONG WINAPI support_error_Release(
424 ISupportErrorInfo *iface )
426 domdoc *This = impl_from_ISupportErrorInfo(iface);
427 return IXMLDocument_Release((IXMLDocument *)This);
430 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
431 ISupportErrorInfo *iface,
434 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
438 static const struct ISupportErrorInfoVtbl support_error_vtbl =
440 support_error_QueryInterface,
441 support_error_AddRef,
442 support_error_Release,
443 support_error_InterfaceSupportsErrorInfo
446 /* IXMLDOMDocument2 interface */
447 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
449 domdoc *This = impl_from_IXMLDOMDocument2( iface );
451 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
455 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
456 IsEqualGUID( riid, &IID_IDispatch ) ||
457 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
458 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
462 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
464 *ppvObject = IXMLDOMNode_from_impl(&This->node);
466 else if (IsEqualGUID(&IID_IPersistStream, riid))
468 *ppvObject = &(This->lpvtblIPersistStream);
470 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
472 *ppvObject = &(This->lpvtblIObjectWithSite);
474 else if (IsEqualGUID(&IID_IObjectSafety, riid))
476 *ppvObject = &(This->lpvtblIObjectSafety);
478 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
480 *ppvObject = &This->lpvtblISupportErrorInfo;
482 else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
484 return *ppvObject ? S_OK : E_NOINTERFACE;
486 else if(IsEqualGUID(&IID_IRunnableObject, riid))
488 TRACE("IID_IRunnableObject not supported returning NULL\n");
489 return E_NOINTERFACE;
493 FIXME("interface %s not implemented\n", debugstr_guid(riid));
494 return E_NOINTERFACE;
497 IUnknown_AddRef((IUnknown*)*ppvObject);
503 static ULONG WINAPI domdoc_AddRef(
504 IXMLDOMDocument2 *iface )
506 domdoc *This = impl_from_IXMLDOMDocument2( iface );
507 TRACE("%p\n", This );
508 return InterlockedIncrement( &This->ref );
512 static ULONG WINAPI domdoc_Release(
513 IXMLDOMDocument2 *iface )
515 domdoc *This = impl_from_IXMLDOMDocument2( iface );
518 TRACE("%p\n", This );
520 ref = InterlockedDecrement( &This->ref );
524 detach_bsc(This->bsc);
527 IUnknown_Release( This->site );
528 destroy_xmlnode(&This->node);
529 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
530 if (This->stream) IStream_Release(This->stream);
531 HeapFree( GetProcessHeap(), 0, This );
537 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
539 domdoc *This = impl_from_IXMLDOMDocument2( iface );
541 TRACE("(%p)->(%p)\n", This, pctinfo);
548 static HRESULT WINAPI domdoc_GetTypeInfo(
549 IXMLDOMDocument2 *iface,
550 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
552 domdoc *This = impl_from_IXMLDOMDocument2( iface );
555 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
557 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
562 static HRESULT WINAPI domdoc_GetIDsOfNames(
563 IXMLDOMDocument2 *iface,
570 domdoc *This = impl_from_IXMLDOMDocument2( iface );
574 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
577 if(!rgszNames || cNames == 0 || !rgDispId)
580 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
583 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
584 ITypeInfo_Release(typeinfo);
591 static HRESULT WINAPI domdoc_Invoke(
592 IXMLDOMDocument2 *iface,
597 DISPPARAMS* pDispParams,
599 EXCEPINFO* pExcepInfo,
602 domdoc *This = impl_from_IXMLDOMDocument2( iface );
606 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
607 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
609 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
612 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
613 pVarResult, pExcepInfo, puArgErr);
614 ITypeInfo_Release(typeinfo);
621 static HRESULT WINAPI domdoc_get_nodeName(
622 IXMLDOMDocument2 *iface,
625 domdoc *This = impl_from_IXMLDOMDocument2( iface );
626 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
630 static HRESULT WINAPI domdoc_get_nodeValue(
631 IXMLDOMDocument2 *iface,
634 domdoc *This = impl_from_IXMLDOMDocument2( iface );
635 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
639 static HRESULT WINAPI domdoc_put_nodeValue(
640 IXMLDOMDocument2 *iface,
643 domdoc *This = impl_from_IXMLDOMDocument2( iface );
644 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
648 static HRESULT WINAPI domdoc_get_nodeType(
649 IXMLDOMDocument2 *iface,
652 domdoc *This = impl_from_IXMLDOMDocument2( iface );
653 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
657 static HRESULT WINAPI domdoc_get_parentNode(
658 IXMLDOMDocument2 *iface,
659 IXMLDOMNode** parent )
661 domdoc *This = impl_from_IXMLDOMDocument2( iface );
662 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
666 static HRESULT WINAPI domdoc_get_childNodes(
667 IXMLDOMDocument2 *iface,
668 IXMLDOMNodeList** childList )
670 domdoc *This = impl_from_IXMLDOMDocument2( iface );
671 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
675 static HRESULT WINAPI domdoc_get_firstChild(
676 IXMLDOMDocument2 *iface,
677 IXMLDOMNode** firstChild )
679 domdoc *This = impl_from_IXMLDOMDocument2( iface );
680 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
684 static HRESULT WINAPI domdoc_get_lastChild(
685 IXMLDOMDocument2 *iface,
686 IXMLDOMNode** lastChild )
688 domdoc *This = impl_from_IXMLDOMDocument2( iface );
689 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
693 static HRESULT WINAPI domdoc_get_previousSibling(
694 IXMLDOMDocument2 *iface,
695 IXMLDOMNode** previousSibling )
697 domdoc *This = impl_from_IXMLDOMDocument2( iface );
698 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
702 static HRESULT WINAPI domdoc_get_nextSibling(
703 IXMLDOMDocument2 *iface,
704 IXMLDOMNode** nextSibling )
706 domdoc *This = impl_from_IXMLDOMDocument2( iface );
707 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
711 static HRESULT WINAPI domdoc_get_attributes(
712 IXMLDOMDocument2 *iface,
713 IXMLDOMNamedNodeMap** attributeMap )
715 domdoc *This = impl_from_IXMLDOMDocument2( iface );
716 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
720 static HRESULT WINAPI domdoc_insertBefore(
721 IXMLDOMDocument2 *iface,
722 IXMLDOMNode* newChild,
724 IXMLDOMNode** outNewChild )
726 domdoc *This = impl_from_IXMLDOMDocument2( iface );
727 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
731 static HRESULT WINAPI domdoc_replaceChild(
732 IXMLDOMDocument2 *iface,
733 IXMLDOMNode* newChild,
734 IXMLDOMNode* oldChild,
735 IXMLDOMNode** outOldChild)
737 domdoc *This = impl_from_IXMLDOMDocument2( iface );
738 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
742 static HRESULT WINAPI domdoc_removeChild(
743 IXMLDOMDocument2 *iface,
744 IXMLDOMNode* childNode,
745 IXMLDOMNode** oldChild)
747 domdoc *This = impl_from_IXMLDOMDocument2( iface );
748 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
752 static HRESULT WINAPI domdoc_appendChild(
753 IXMLDOMDocument2 *iface,
754 IXMLDOMNode* newChild,
755 IXMLDOMNode** outNewChild)
757 domdoc *This = impl_from_IXMLDOMDocument2( iface );
758 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
762 static HRESULT WINAPI domdoc_hasChildNodes(
763 IXMLDOMDocument2 *iface,
764 VARIANT_BOOL* hasChild)
766 domdoc *This = impl_from_IXMLDOMDocument2( iface );
767 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
771 static HRESULT WINAPI domdoc_get_ownerDocument(
772 IXMLDOMDocument2 *iface,
773 IXMLDOMDocument** DOMDocument)
775 domdoc *This = impl_from_IXMLDOMDocument2( iface );
776 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
780 static HRESULT WINAPI domdoc_cloneNode(
781 IXMLDOMDocument2 *iface,
783 IXMLDOMNode** cloneRoot)
785 domdoc *This = impl_from_IXMLDOMDocument2( iface );
786 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
790 static HRESULT WINAPI domdoc_get_nodeTypeString(
791 IXMLDOMDocument2 *iface,
794 domdoc *This = impl_from_IXMLDOMDocument2( iface );
795 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
799 static HRESULT WINAPI domdoc_get_text(
800 IXMLDOMDocument2 *iface,
803 domdoc *This = impl_from_IXMLDOMDocument2( iface );
804 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
808 static HRESULT WINAPI domdoc_put_text(
809 IXMLDOMDocument2 *iface,
812 domdoc *This = impl_from_IXMLDOMDocument2( iface );
813 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
817 static HRESULT WINAPI domdoc_get_specified(
818 IXMLDOMDocument2 *iface,
819 VARIANT_BOOL* isSpecified )
821 domdoc *This = impl_from_IXMLDOMDocument2( iface );
822 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
826 static HRESULT WINAPI domdoc_get_definition(
827 IXMLDOMDocument2 *iface,
828 IXMLDOMNode** definitionNode )
830 domdoc *This = impl_from_IXMLDOMDocument2( iface );
831 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
835 static HRESULT WINAPI domdoc_get_nodeTypedValue(
836 IXMLDOMDocument2 *iface,
837 VARIANT* typedValue )
839 domdoc *This = impl_from_IXMLDOMDocument2( iface );
840 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
843 static HRESULT WINAPI domdoc_put_nodeTypedValue(
844 IXMLDOMDocument2 *iface,
847 domdoc *This = impl_from_IXMLDOMDocument2( iface );
848 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
852 static HRESULT WINAPI domdoc_get_dataType(
853 IXMLDOMDocument2 *iface,
854 VARIANT* dataTypeName )
856 domdoc *This = impl_from_IXMLDOMDocument2( iface );
857 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
861 static HRESULT WINAPI domdoc_put_dataType(
862 IXMLDOMDocument2 *iface,
865 domdoc *This = impl_from_IXMLDOMDocument2( iface );
866 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
870 static HRESULT WINAPI domdoc_get_xml(
871 IXMLDOMDocument2 *iface,
874 domdoc *This = impl_from_IXMLDOMDocument2( iface );
875 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
879 static HRESULT WINAPI domdoc_transformNode(
880 IXMLDOMDocument2 *iface,
881 IXMLDOMNode* styleSheet,
884 domdoc *This = impl_from_IXMLDOMDocument2( iface );
885 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
889 static HRESULT WINAPI domdoc_selectNodes(
890 IXMLDOMDocument2 *iface,
892 IXMLDOMNodeList** resultList )
894 domdoc *This = impl_from_IXMLDOMDocument2( iface );
895 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
899 static HRESULT WINAPI domdoc_selectSingleNode(
900 IXMLDOMDocument2 *iface,
902 IXMLDOMNode** resultNode )
904 domdoc *This = impl_from_IXMLDOMDocument2( iface );
905 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
909 static HRESULT WINAPI domdoc_get_parsed(
910 IXMLDOMDocument2 *iface,
911 VARIANT_BOOL* isParsed )
913 domdoc *This = impl_from_IXMLDOMDocument2( iface );
914 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
918 static HRESULT WINAPI domdoc_get_namespaceURI(
919 IXMLDOMDocument2 *iface,
922 domdoc *This = impl_from_IXMLDOMDocument2( iface );
923 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
927 static HRESULT WINAPI domdoc_get_prefix(
928 IXMLDOMDocument2 *iface,
931 domdoc *This = impl_from_IXMLDOMDocument2( iface );
932 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
936 static HRESULT WINAPI domdoc_get_baseName(
937 IXMLDOMDocument2 *iface,
940 domdoc *This = impl_from_IXMLDOMDocument2( iface );
941 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
945 static HRESULT WINAPI domdoc_transformNodeToObject(
946 IXMLDOMDocument2 *iface,
947 IXMLDOMNode* stylesheet,
948 VARIANT outputObject)
950 domdoc *This = impl_from_IXMLDOMDocument2( iface );
951 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
955 static HRESULT WINAPI domdoc_get_doctype(
956 IXMLDOMDocument2 *iface,
957 IXMLDOMDocumentType** documentType )
959 domdoc *This = impl_from_IXMLDOMDocument2(iface);
960 FIXME("(%p)\n", This);
965 static HRESULT WINAPI domdoc_get_implementation(
966 IXMLDOMDocument2 *iface,
967 IXMLDOMImplementation** impl )
969 domdoc *This = impl_from_IXMLDOMDocument2(iface);
971 TRACE("(%p)->(%p)\n", This, impl);
976 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
981 static HRESULT WINAPI domdoc_get_documentElement(
982 IXMLDOMDocument2 *iface,
983 IXMLDOMElement** DOMElement )
985 domdoc *This = impl_from_IXMLDOMDocument2( iface );
986 xmlDocPtr xmldoc = NULL;
987 xmlNodePtr root = NULL;
988 IXMLDOMNode *element_node;
991 TRACE("(%p)->(%p)\n", This, DOMElement);
998 xmldoc = get_doc( This );
1000 root = xmlDocGetRootElement( xmldoc );
1004 element_node = create_node( root );
1005 if(!element_node) return S_FALSE;
1007 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
1008 IXMLDOMNode_Release(element_node);
1014 static HRESULT WINAPI domdoc_put_documentElement(
1015 IXMLDOMDocument2 *iface,
1016 IXMLDOMElement* DOMElement )
1018 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1019 IXMLDOMNode *elementNode;
1024 TRACE("(%p)->(%p)\n", This, DOMElement);
1026 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1030 xmlNode = impl_from_IXMLDOMNode( elementNode );
1032 if(!xmlNode->node->parent)
1033 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1034 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1036 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1037 IXMLDOMNode_Release( elementNode );
1040 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1046 static HRESULT WINAPI domdoc_createElement(
1047 IXMLDOMDocument2 *iface,
1049 IXMLDOMElement** element )
1051 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1056 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1058 if (!element || !tagname) return E_INVALIDARG;
1060 V_VT(&type) = VT_I1;
1061 V_I1(&type) = NODE_ELEMENT;
1063 hr = IXMLDOMDocument_createNode(iface, type, tagname, NULL, &node);
1066 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1067 IXMLDOMNode_Release(node);
1074 static HRESULT WINAPI domdoc_createDocumentFragment(
1075 IXMLDOMDocument2 *iface,
1076 IXMLDOMDocumentFragment** frag )
1078 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1083 TRACE("(%p)->(%p)\n", This, frag);
1085 if (!frag) return E_INVALIDARG;
1089 V_VT(&type) = VT_I1;
1090 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1092 hr = IXMLDOMDocument_createNode(iface, type, NULL, NULL, &node);
1095 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1096 IXMLDOMNode_Release(node);
1103 static HRESULT WINAPI domdoc_createTextNode(
1104 IXMLDOMDocument2 *iface,
1106 IXMLDOMText** text )
1108 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1113 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1115 if (!text) return E_INVALIDARG;
1119 V_VT(&type) = VT_I1;
1120 V_I1(&type) = NODE_TEXT;
1122 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1125 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1126 IXMLDOMNode_Release(node);
1127 hr = IXMLDOMText_put_data(*text, data);
1134 static HRESULT WINAPI domdoc_createComment(
1135 IXMLDOMDocument2 *iface,
1137 IXMLDOMComment** comment )
1139 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1144 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1146 if (!comment) return E_INVALIDARG;
1150 V_VT(&type) = VT_I1;
1151 V_I1(&type) = NODE_COMMENT;
1153 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1156 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1157 IXMLDOMNode_Release(node);
1158 hr = IXMLDOMComment_put_data(*comment, data);
1165 static HRESULT WINAPI domdoc_createCDATASection(
1166 IXMLDOMDocument2 *iface,
1168 IXMLDOMCDATASection** cdata )
1170 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1175 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1177 if (!cdata) return E_INVALIDARG;
1181 V_VT(&type) = VT_I1;
1182 V_I1(&type) = NODE_CDATA_SECTION;
1184 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1187 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1188 IXMLDOMNode_Release(node);
1189 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1196 static HRESULT WINAPI domdoc_createProcessingInstruction(
1197 IXMLDOMDocument2 *iface,
1200 IXMLDOMProcessingInstruction** pi )
1202 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1207 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1209 if (!pi) return E_INVALIDARG;
1213 V_VT(&type) = VT_I1;
1214 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1216 hr = IXMLDOMDocument2_createNode(iface, type, target, NULL, &node);
1221 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1222 V_VT(&v_data) = VT_BSTR;
1223 V_BSTR(&v_data) = data;
1225 hr = IXMLDOMNode_put_nodeValue( node, v_data );
1227 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1228 IXMLDOMNode_Release(node);
1235 static HRESULT WINAPI domdoc_createAttribute(
1236 IXMLDOMDocument2 *iface,
1238 IXMLDOMAttribute** attribute )
1240 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1245 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1247 if (!attribute || !name) return E_INVALIDARG;
1249 V_VT(&type) = VT_I1;
1250 V_I1(&type) = NODE_ATTRIBUTE;
1252 hr = IXMLDOMDocument_createNode(iface, type, name, NULL, &node);
1255 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1256 IXMLDOMNode_Release(node);
1263 static HRESULT WINAPI domdoc_createEntityReference(
1264 IXMLDOMDocument2 *iface,
1266 IXMLDOMEntityReference** entityref )
1268 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1273 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1275 if (!entityref) return E_INVALIDARG;
1279 V_VT(&type) = VT_I1;
1280 V_I1(&type) = NODE_ENTITY_REFERENCE;
1282 hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
1285 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1286 IXMLDOMNode_Release(node);
1293 static HRESULT WINAPI domdoc_getElementsByTagName(
1294 IXMLDOMDocument2 *iface,
1296 IXMLDOMNodeList** resultList )
1298 static const WCHAR xpathformat[] =
1299 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1300 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1303 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1305 if (tagName[0] == '*' && tagName[1] == 0)
1307 szPattern = heap_alloc(sizeof(WCHAR)*4);
1308 szPattern[0] = szPattern[1] = '/';
1314 szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1315 wsprintfW(szPattern, xpathformat, tagName);
1318 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1319 heap_free(szPattern);
1324 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1330 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1332 return E_INVALIDARG;
1339 static HRESULT WINAPI domdoc_createNode(
1340 IXMLDOMDocument2 *iface,
1344 IXMLDOMNode** node )
1346 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1347 DOMNodeType node_type;
1352 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1354 if(!node) return E_INVALIDARG;
1356 if(namespaceURI && namespaceURI[0])
1357 FIXME("nodes with namespaces currently not supported.\n");
1359 hr = get_node_type(Type, &node_type);
1360 if(FAILED(hr)) return hr;
1362 TRACE("node_type %d\n", node_type);
1364 /* exit earlier for types that need name */
1368 case NODE_ATTRIBUTE:
1369 case NODE_ENTITY_REFERENCE:
1370 case NODE_PROCESSING_INSTRUCTION:
1371 if (!name || SysStringLen(name) == 0) return E_FAIL;
1376 xml_name = xmlChar_from_wchar(name);
1381 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1383 case NODE_ATTRIBUTE:
1384 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1387 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1389 case NODE_CDATA_SECTION:
1390 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1392 case NODE_ENTITY_REFERENCE:
1393 xmlnode = xmlNewReference(get_doc(This), xml_name);
1395 case NODE_PROCESSING_INSTRUCTION:
1396 #ifdef HAVE_XMLNEWDOCPI
1397 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1399 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1404 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1406 case NODE_DOCUMENT_FRAGMENT:
1407 xmlnode = xmlNewDocFragment(get_doc(This));
1409 /* unsupported types */
1411 case NODE_DOCUMENT_TYPE:
1414 heap_free(xml_name);
1415 return E_INVALIDARG;
1417 FIXME("unhandled node type %d\n", node_type);
1422 *node = create_node(xmlnode);
1423 heap_free(xml_name);
1427 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1428 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1435 static HRESULT WINAPI domdoc_nodeFromID(
1436 IXMLDOMDocument2 *iface,
1438 IXMLDOMNode** node )
1440 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1441 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1445 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1450 xmldoc = doparse( ptr, len );
1452 xmldoc->_private = create_priv();
1453 return attach_xmldoc(&This->node, xmldoc);
1459 static HRESULT doread( domdoc *This, LPWSTR filename )
1464 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1469 detach_bsc(This->bsc);
1475 static HRESULT WINAPI domdoc_load(
1476 IXMLDOMDocument2 *iface,
1478 VARIANT_BOOL* isSuccessful )
1480 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1481 LPWSTR filename = NULL;
1482 HRESULT hr = S_FALSE;
1483 IXMLDOMDocument2 *pNewDoc = NULL;
1484 IStream *pStream = NULL;
1487 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1489 *isSuccessful = VARIANT_FALSE;
1491 assert( &This->node );
1493 switch( V_VT(&xmlSource) )
1496 filename = V_BSTR(&xmlSource);
1499 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1504 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1505 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1506 hr = attach_xmldoc(&This->node, xmldoc);
1509 *isSuccessful = VARIANT_TRUE;
1514 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1517 IPersistStream *pDocStream;
1518 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1521 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1522 IStream_Release(pStream);
1525 *isSuccessful = VARIANT_TRUE;
1527 TRACE("Using ID_IStream to load Document\n");
1532 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1537 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1542 /* ISequentialStream */
1543 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1547 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1550 TRACE("filename (%s)\n", debugstr_w(filename));
1554 hr = doread( This, filename );
1557 This->error = E_FAIL;
1560 hr = This->error = S_OK;
1561 *isSuccessful = VARIANT_TRUE;
1565 if(!filename || FAILED(hr)) {
1566 xmldoc = xmlNewDoc(NULL);
1567 xmldoc->_private = create_priv();
1568 hr = attach_xmldoc(&This->node, xmldoc);
1573 TRACE("ret (%d)\n", hr);
1579 static HRESULT WINAPI domdoc_get_readyState(
1580 IXMLDOMDocument2 *iface,
1583 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1584 FIXME("(%p)->(%p)\n", This, value);
1589 static HRESULT WINAPI domdoc_get_parseError(
1590 IXMLDOMDocument2 *iface,
1591 IXMLDOMParseError** errorObj )
1593 BSTR error_string = NULL;
1594 static const WCHAR err[] = {'e','r','r','o','r',0};
1595 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1597 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1600 error_string = SysAllocString(err);
1602 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1603 if(!*errorObj) return E_OUTOFMEMORY;
1608 static HRESULT WINAPI domdoc_get_url(
1609 IXMLDOMDocument2 *iface,
1612 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1613 FIXME("(%p)->(%p)\n", This, urlString);
1618 static HRESULT WINAPI domdoc_get_async(
1619 IXMLDOMDocument2 *iface,
1620 VARIANT_BOOL* isAsync )
1622 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1624 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1625 *isAsync = This->async;
1630 static HRESULT WINAPI domdoc_put_async(
1631 IXMLDOMDocument2 *iface,
1632 VARIANT_BOOL isAsync )
1634 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1636 TRACE("(%p)->(%d)\n", This, isAsync);
1637 This->async = isAsync;
1642 static HRESULT WINAPI domdoc_abort(
1643 IXMLDOMDocument2 *iface )
1645 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1646 FIXME("%p\n", This);
1651 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1656 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
1657 str = heap_alloc( len );
1660 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
1666 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
1667 static HRESULT WINAPI domdoc_loadXML(
1668 IXMLDOMDocument2 *iface,
1670 VARIANT_BOOL* isSuccessful )
1672 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1673 xmlDocPtr xmldoc = NULL;
1676 HRESULT hr = S_FALSE, hr2;
1678 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
1680 assert ( &This->node );
1684 *isSuccessful = VARIANT_FALSE;
1686 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1688 xmldoc = doparse( str, len );
1691 This->error = E_FAIL;
1694 hr = This->error = S_OK;
1695 *isSuccessful = VARIANT_TRUE;
1700 xmldoc = xmlNewDoc(NULL);
1702 xmldoc->_private = create_priv();
1703 hr2 = attach_xmldoc( &This->node, xmldoc );
1710 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1715 if(!WriteFile(ctx, buffer, len, &written, NULL))
1717 WARN("write error\n");
1724 static int XMLCALL domdoc_save_closecallback(void *ctx)
1726 return CloseHandle(ctx) ? 0 : -1;
1729 static HRESULT WINAPI domdoc_save(
1730 IXMLDOMDocument2 *iface,
1731 VARIANT destination )
1733 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1738 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1739 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1741 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1743 FIXME("Unhandled vt %d\n", V_VT(&destination));
1747 if(V_VT(&destination) == VT_UNKNOWN)
1749 IUnknown *pUnk = V_UNKNOWN(&destination);
1750 IXMLDOMDocument *pDocument;
1752 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1756 VARIANT_BOOL bSuccessful;
1758 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1761 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1763 SysFreeString(bXML);
1766 IXMLDOMDocument_Release(pDocument);
1769 TRACE("ret %d\n", ret);
1774 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1775 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1776 if( handle == INVALID_HANDLE_VALUE )
1778 WARN("failed to create file\n");
1782 /* disable top XML declaration */
1783 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1784 handle, NULL, XML_SAVE_NO_DECL);
1787 CloseHandle(handle);
1791 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1792 /* will close file through close callback */
1798 static HRESULT WINAPI domdoc_get_validateOnParse(
1799 IXMLDOMDocument2 *iface,
1800 VARIANT_BOOL* isValidating )
1802 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1804 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
1805 *isValidating = This->validating;
1810 static HRESULT WINAPI domdoc_put_validateOnParse(
1811 IXMLDOMDocument2 *iface,
1812 VARIANT_BOOL isValidating )
1814 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1816 TRACE("(%p)->(%d)\n", This, isValidating);
1817 This->validating = isValidating;
1822 static HRESULT WINAPI domdoc_get_resolveExternals(
1823 IXMLDOMDocument2 *iface,
1824 VARIANT_BOOL* isResolving )
1826 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1828 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
1829 *isResolving = This->resolving;
1834 static HRESULT WINAPI domdoc_put_resolveExternals(
1835 IXMLDOMDocument2 *iface,
1836 VARIANT_BOOL isResolving )
1838 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1840 TRACE("(%p)->(%d)\n", This, isResolving);
1841 This->resolving = isResolving;
1846 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1847 IXMLDOMDocument2 *iface,
1848 VARIANT_BOOL* isPreserving )
1850 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1852 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
1853 *isPreserving = This->preserving;
1858 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1859 IXMLDOMDocument2 *iface,
1860 VARIANT_BOOL isPreserving )
1862 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1864 TRACE("(%p)->(%d)\n", This, isPreserving);
1865 This->preserving = isPreserving;
1870 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1871 IXMLDOMDocument2 *iface,
1872 VARIANT readyStateChangeSink )
1874 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1875 FIXME("%p\n", This);
1880 static HRESULT WINAPI domdoc_put_onDataAvailable(
1881 IXMLDOMDocument2 *iface,
1882 VARIANT onDataAvailableSink )
1884 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1885 FIXME("%p\n", This);
1889 static HRESULT WINAPI domdoc_put_onTransformNode(
1890 IXMLDOMDocument2 *iface,
1891 VARIANT onTransformNodeSink )
1893 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1894 FIXME("%p\n", This);
1898 static HRESULT WINAPI domdoc_get_namespaces(
1899 IXMLDOMDocument2* iface,
1900 IXMLDOMSchemaCollection** schemaCollection )
1902 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1903 FIXME("(%p)->(%p)\n", This, schemaCollection);
1907 static HRESULT WINAPI domdoc_get_schemas(
1908 IXMLDOMDocument2* iface,
1911 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1912 HRESULT hr = S_FALSE;
1913 IXMLDOMSchemaCollection *cur_schema = This->schema;
1915 TRACE("(%p)->(%p)\n", This, var1);
1917 VariantInit(var1); /* Test shows we don't call VariantClear here */
1918 V_VT(var1) = VT_NULL;
1922 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1924 V_VT(var1) = VT_DISPATCH;
1929 static HRESULT WINAPI domdoc_putref_schemas(
1930 IXMLDOMDocument2* iface,
1933 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1934 HRESULT hr = E_FAIL;
1935 IXMLDOMSchemaCollection *new_schema = NULL;
1937 FIXME("(%p): semi-stub\n", This);
1941 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1945 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1954 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1959 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1960 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1966 static HRESULT WINAPI domdoc_validate(
1967 IXMLDOMDocument2* iface,
1968 IXMLDOMParseError** err)
1970 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1971 FIXME("(%p)->(%p)\n", This, err);
1975 static HRESULT WINAPI domdoc_setProperty(
1976 IXMLDOMDocument2* iface,
1980 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1982 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
1984 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1990 V_VT(&varStr) = VT_EMPTY;
1991 if (V_VT(&var) != VT_BSTR)
1993 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1995 bstr = V_BSTR(&varStr);
1998 bstr = V_BSTR(&var);
2001 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
2002 This->bUseXPath = TRUE;
2003 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
2004 This->bUseXPath = FALSE;
2008 VariantClear(&varStr);
2012 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2016 static HRESULT WINAPI domdoc_getProperty(
2017 IXMLDOMDocument2* iface,
2021 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2023 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2026 return E_INVALIDARG;
2027 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
2029 V_VT(var) = VT_BSTR;
2030 if (This->bUseXPath)
2031 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
2033 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
2037 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2041 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
2043 domdoc_QueryInterface,
2046 domdoc_GetTypeInfoCount,
2048 domdoc_GetIDsOfNames,
2050 domdoc_get_nodeName,
2051 domdoc_get_nodeValue,
2052 domdoc_put_nodeValue,
2053 domdoc_get_nodeType,
2054 domdoc_get_parentNode,
2055 domdoc_get_childNodes,
2056 domdoc_get_firstChild,
2057 domdoc_get_lastChild,
2058 domdoc_get_previousSibling,
2059 domdoc_get_nextSibling,
2060 domdoc_get_attributes,
2061 domdoc_insertBefore,
2062 domdoc_replaceChild,
2065 domdoc_hasChildNodes,
2066 domdoc_get_ownerDocument,
2068 domdoc_get_nodeTypeString,
2071 domdoc_get_specified,
2072 domdoc_get_definition,
2073 domdoc_get_nodeTypedValue,
2074 domdoc_put_nodeTypedValue,
2075 domdoc_get_dataType,
2076 domdoc_put_dataType,
2078 domdoc_transformNode,
2080 domdoc_selectSingleNode,
2082 domdoc_get_namespaceURI,
2084 domdoc_get_baseName,
2085 domdoc_transformNodeToObject,
2087 domdoc_get_implementation,
2088 domdoc_get_documentElement,
2089 domdoc_put_documentElement,
2090 domdoc_createElement,
2091 domdoc_createDocumentFragment,
2092 domdoc_createTextNode,
2093 domdoc_createComment,
2094 domdoc_createCDATASection,
2095 domdoc_createProcessingInstruction,
2096 domdoc_createAttribute,
2097 domdoc_createEntityReference,
2098 domdoc_getElementsByTagName,
2102 domdoc_get_readyState,
2103 domdoc_get_parseError,
2110 domdoc_get_validateOnParse,
2111 domdoc_put_validateOnParse,
2112 domdoc_get_resolveExternals,
2113 domdoc_put_resolveExternals,
2114 domdoc_get_preserveWhiteSpace,
2115 domdoc_put_preserveWhiteSpace,
2116 domdoc_put_onReadyStateChange,
2117 domdoc_put_onDataAvailable,
2118 domdoc_put_onTransformNode,
2119 domdoc_get_namespaces,
2121 domdoc_putref_schemas,
2127 /* xmldoc implementation of IObjectWithSite */
2128 static HRESULT WINAPI
2129 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2131 domdoc *This = impl_from_IObjectWithSite(iface);
2132 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2136 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2138 domdoc *This = impl_from_IObjectWithSite(iface);
2139 return IXMLDocument_AddRef((IXMLDocument *)This);
2143 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2145 domdoc *This = impl_from_IObjectWithSite(iface);
2146 return IXMLDocument_Release((IXMLDocument *)This);
2149 static HRESULT WINAPI
2150 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2152 domdoc *This = impl_from_IObjectWithSite(iface);
2154 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2159 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2162 static HRESULT WINAPI
2163 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2165 domdoc *This = impl_from_IObjectWithSite(iface);
2167 TRACE("(%p)->(%p)\n", iface, punk);
2173 IUnknown_Release( This->site );
2181 IUnknown_AddRef( punk );
2184 IUnknown_Release( This->site );
2191 static const IObjectWithSiteVtbl domdocObjectSite =
2193 xmldoc_ObjectWithSite_QueryInterface,
2194 xmldoc_ObjectWithSite_AddRef,
2195 xmldoc_ObjectWithSite_Release,
2200 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2202 domdoc *This = impl_from_IObjectSafety(iface);
2203 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2206 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2208 domdoc *This = impl_from_IObjectSafety(iface);
2209 return IXMLDocument_AddRef((IXMLDocument *)This);
2212 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2214 domdoc *This = impl_from_IObjectSafety(iface);
2215 return IXMLDocument_Release((IXMLDocument *)This);
2218 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2220 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2221 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2223 domdoc *This = impl_from_IObjectSafety(iface);
2225 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2227 if(!pdwSupportedOptions || !pdwEnabledOptions)
2230 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2231 *pdwEnabledOptions = This->safeopt;
2236 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2237 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2239 domdoc *This = impl_from_IObjectSafety(iface);
2240 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2242 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2245 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2249 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2250 xmldoc_Safety_QueryInterface,
2251 xmldoc_Safety_AddRef,
2252 xmldoc_Safety_Release,
2253 xmldoc_Safety_GetInterfaceSafetyOptions,
2254 xmldoc_Safety_SetInterfaceSafetyOptions
2258 static const tid_t domdoc_iface_tids[] = {
2260 IXMLDOMDocument_tid,
2261 IXMLDOMDocument2_tid,
2264 static dispex_static_data_t domdoc_dispex = {
2266 IXMLDOMDocument2_tid,
2271 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2275 doc = heap_alloc( sizeof (*doc) );
2277 return E_OUTOFMEMORY;
2279 doc->lpVtbl = &domdoc_vtbl;
2280 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2281 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2282 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2283 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2285 doc->async = VARIANT_TRUE;
2286 doc->validating = 0;
2288 doc->preserving = 0;
2289 doc->bUseXPath = FALSE;
2297 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2299 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2301 TRACE("returning iface %p\n", *document);
2305 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2310 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2312 xmldoc = xmlNewDoc(NULL);
2314 return E_OUTOFMEMORY;
2316 xmldoc->_private = create_priv();
2318 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2325 IUnknown* create_domdoc( xmlNodePtr document )
2330 TRACE("(%p)\n", document);
2332 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2341 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2343 MESSAGE("This program tried to use a DOMDocument object, but\n"
2344 "libxml2 support was not present at compile time.\n");