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
57 const struct IXMLDOMDocument2Vtbl
*lpVtbl
;
58 const struct IPersistStreamVtbl
*lpvtblIPersistStream
;
59 const struct IObjectWithSiteVtbl
*lpvtblIObjectWithSite
;
60 const struct IObjectSafetyVtbl
*lpvtblIObjectSafety
;
61 const struct ISupportErrorInfoVtbl
*lpvtblISupportErrorInfo
;
64 VARIANT_BOOL validating
;
65 VARIANT_BOOL resolving
;
66 VARIANT_BOOL preserving
;
68 IXMLDOMSchemaCollection
*schema
;
83 In native windows, the whole lifetime management of XMLDOMNodes is
84 managed automatically using reference counts. Wine emulates that by
85 maintaining a reference count to the document that is increased for
86 each IXMLDOMNode pointer passed out for this document. If all these
87 pointers are gone, the document is unreachable and gets freed, that
88 is, all nodes in the tree of the document get freed.
90 You are able to create nodes that are associated to a document (in
91 fact, in msxml's XMLDOM model, all nodes are associated to a document),
92 but not in the tree of that document, for example using the createFoo
93 functions from IXMLDOMDocument. These nodes do not get cleaned up
94 by libxml, so we have to do it ourselves.
96 To catch these nodes, a list of "orphan nodes" is introduced.
97 It contains pointers to all roots of node trees that are
98 associated with the document without being part of the document
99 tree. All nodes with parent==NULL (except for the document root nodes)
100 should be in the orphan node list of their document. All orphan nodes
101 get freed together with the document itself.
104 typedef struct _xmldoc_priv
{
109 typedef struct _orphan_entry
{
114 static inline xmldoc_priv
* priv_from_xmlDocPtr(xmlDocPtr doc
)
116 return doc
->_private
;
119 static xmldoc_priv
* create_priv(void)
122 priv
= HeapAlloc( GetProcessHeap(), 0, sizeof (*priv
) );
127 list_init( &priv
->orphans
);
133 static xmlDocPtr
doparse( char *ptr
, int len
)
135 #ifdef HAVE_XMLREADMEMORY
137 * use xmlReadMemory if possible so we can suppress
138 * writing errors to stderr
140 return xmlReadMemory( ptr
, len
, NULL
, NULL
,
141 XML_PARSE_NOERROR
| XML_PARSE_NOWARNING
| XML_PARSE_NOBLANKS
);
143 return xmlParseMemory( ptr
, len
);
147 LONG
xmldoc_add_ref(xmlDocPtr doc
)
149 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
154 LONG
xmldoc_release(xmlDocPtr doc
)
156 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
157 LONG ref
= InterlockedDecrement(&priv
->refs
);
161 orphan_entry
*orphan
, *orphan2
;
162 TRACE("freeing docptr %p\n", doc
);
164 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
166 xmlFreeNode( orphan
->node
);
167 HeapFree( GetProcessHeap(), 0, orphan
);
169 HeapFree(GetProcessHeap(), 0, doc
->_private
);
177 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
179 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
182 entry
= HeapAlloc( GetProcessHeap(), 0, sizeof (*entry
) );
184 return E_OUTOFMEMORY
;
187 list_add_head( &priv
->orphans
, &entry
->entry
);
191 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
193 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
194 orphan_entry
*entry
, *entry2
;
196 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
198 if( entry
->node
== node
)
200 list_remove( &entry
->entry
);
201 HeapFree( GetProcessHeap(), 0, entry
);
209 static HRESULT
attach_xmldoc( xmlnode
*node
, xmlDocPtr xml
)
212 xmldoc_release(node
->node
->doc
);
214 node
->node
= (xmlNodePtr
) xml
;
216 xmldoc_add_ref(node
->node
->doc
);
221 static inline domdoc
*impl_from_IXMLDOMDocument2( IXMLDOMDocument2
*iface
)
223 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpVtbl
));
226 static inline xmlDocPtr
get_doc( domdoc
*This
)
228 return (xmlDocPtr
)This
->node
.node
;
231 static inline domdoc
*impl_from_IPersistStream(IPersistStream
*iface
)
233 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIPersistStream
));
236 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
238 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectWithSite
));
241 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
243 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectSafety
));
246 static inline domdoc
*impl_from_ISupportErrorInfo(ISupportErrorInfo
*iface
)
248 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblISupportErrorInfo
));
251 /************************************************************************
252 * xmldoc implementation of IPersistStream.
254 static HRESULT WINAPI
xmldoc_IPersistStream_QueryInterface(
255 IPersistStream
*iface
, REFIID riid
, LPVOID
*ppvObj
)
257 domdoc
*this = impl_from_IPersistStream(iface
);
258 return IXMLDocument_QueryInterface((IXMLDocument
*)this, riid
, ppvObj
);
261 static ULONG WINAPI
xmldoc_IPersistStream_AddRef(
262 IPersistStream
*iface
)
264 domdoc
*this = impl_from_IPersistStream(iface
);
265 return IXMLDocument_AddRef((IXMLDocument
*)this);
268 static ULONG WINAPI
xmldoc_IPersistStream_Release(
269 IPersistStream
*iface
)
271 domdoc
*this = impl_from_IPersistStream(iface
);
272 return IXMLDocument_Release((IXMLDocument
*)this);
275 static HRESULT WINAPI
xmldoc_IPersistStream_GetClassID(
276 IPersistStream
*iface
, CLSID
*classid
)
278 TRACE("(%p,%p): stub!\n", iface
, classid
);
283 *classid
= CLSID_DOMDocument2
;
288 static HRESULT WINAPI
xmldoc_IPersistStream_IsDirty(
289 IPersistStream
*iface
)
291 domdoc
*This
= impl_from_IPersistStream(iface
);
293 FIXME("(%p->%p): stub!\n", iface
, This
);
298 static HRESULT WINAPI
xmldoc_IPersistStream_Load(
299 IPersistStream
*iface
, LPSTREAM pStm
)
301 domdoc
*This
= impl_from_IPersistStream(iface
);
304 DWORD read
, written
, len
;
307 xmlDocPtr xmldoc
= NULL
;
309 TRACE("(%p, %p)\n", iface
, pStm
);
314 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
320 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
321 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
322 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
326 ERR("Failed to copy stream\n");
330 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
334 len
= GlobalSize(hglobal
);
335 ptr
= GlobalLock(hglobal
);
337 xmldoc
= parse_xml(ptr
, len
);
338 GlobalUnlock(hglobal
);
342 ERR("Failed to parse xml\n");
346 xmldoc
->_private
= create_priv();
348 return attach_xmldoc( &This
->node
, xmldoc
);
351 static HRESULT WINAPI
xmldoc_IPersistStream_Save(
352 IPersistStream
*iface
, LPSTREAM pStm
, BOOL fClearDirty
)
354 domdoc
*This
= impl_from_IPersistStream(iface
);
358 TRACE("(%p, %p, %d)\n", iface
, pStm
, fClearDirty
);
360 hr
= IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This
->node
), &xmlString
);
364 DWORD len
= strlenW(xmlString
) * sizeof(WCHAR
);
366 hr
= IStream_Write( pStm
, xmlString
, len
, &count
);
368 SysFreeString(xmlString
);
371 TRACE("ret 0x%08x\n", hr
);
376 static HRESULT WINAPI
xmldoc_IPersistStream_GetSizeMax(
377 IPersistStream
*iface
, ULARGE_INTEGER
*pcbSize
)
379 TRACE("(%p, %p): stub!\n", iface
, pcbSize
);
383 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable
=
385 xmldoc_IPersistStream_QueryInterface
,
386 xmldoc_IPersistStream_AddRef
,
387 xmldoc_IPersistStream_Release
,
388 xmldoc_IPersistStream_GetClassID
,
389 xmldoc_IPersistStream_IsDirty
,
390 xmldoc_IPersistStream_Load
,
391 xmldoc_IPersistStream_Save
,
392 xmldoc_IPersistStream_GetSizeMax
,
395 /* ISupportErrorInfo interface */
396 static HRESULT WINAPI
support_error_QueryInterface(
397 ISupportErrorInfo
*iface
,
398 REFIID riid
, void** ppvObj
)
400 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
401 return IXMLDocument_QueryInterface((IXMLDocument
*)This
, riid
, ppvObj
);
404 static ULONG WINAPI
support_error_AddRef(
405 ISupportErrorInfo
*iface
)
407 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
408 return IXMLDocument_AddRef((IXMLDocument
*)This
);
411 static ULONG WINAPI
support_error_Release(
412 ISupportErrorInfo
*iface
)
414 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
415 return IXMLDocument_Release((IXMLDocument
*)This
);
418 static HRESULT WINAPI
support_error_InterfaceSupportsErrorInfo(
419 ISupportErrorInfo
*iface
,
422 FIXME("(%p)->(%s)\n", iface
, debugstr_guid(riid
));
426 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
428 support_error_QueryInterface
,
429 support_error_AddRef
,
430 support_error_Release
,
431 support_error_InterfaceSupportsErrorInfo
434 /* IXMLDOMDocument2 interface */
435 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument2
*iface
, REFIID riid
, void** ppvObject
)
437 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
439 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
443 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
444 IsEqualGUID( riid
, &IID_IDispatch
) ||
445 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
446 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
) )
450 else if ( IsEqualGUID( riid
, &IID_IXMLDOMNode
) )
452 *ppvObject
= IXMLDOMNode_from_impl(&This
->node
);
454 else if (IsEqualGUID(&IID_IPersistStream
, riid
))
456 *ppvObject
= &(This
->lpvtblIPersistStream
);
458 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
460 *ppvObject
= &(This
->lpvtblIObjectWithSite
);
462 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
464 *ppvObject
= &This
->lpvtblISupportErrorInfo
;
466 else if(dispex_query_interface(&This
->node
.dispex
, riid
, ppvObject
))
468 return *ppvObject
? S_OK
: E_NOINTERFACE
;
470 else if(IsEqualGUID(&IID_IRunnableObject
, riid
))
472 TRACE("IID_IRunnableObject not supported returning NULL\n");
473 return E_NOINTERFACE
;
477 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
478 return E_NOINTERFACE
;
481 IUnknown_AddRef((IUnknown
*)*ppvObject
);
487 static ULONG WINAPI
domdoc_AddRef(
488 IXMLDOMDocument2
*iface
)
490 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
491 TRACE("%p\n", This
);
492 return InterlockedIncrement( &This
->ref
);
496 static ULONG WINAPI
domdoc_Release(
497 IXMLDOMDocument2
*iface
)
499 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
502 TRACE("%p\n", This
);
504 ref
= InterlockedDecrement( &This
->ref
);
508 detach_bsc(This
->bsc
);
511 IUnknown_Release( This
->site
);
512 destroy_xmlnode(&This
->node
);
513 if(This
->schema
) IXMLDOMSchemaCollection_Release( This
->schema
);
514 if (This
->stream
) IStream_Release(This
->stream
);
515 HeapFree( GetProcessHeap(), 0, This
);
521 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument2
*iface
, UINT
* pctinfo
)
523 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
525 TRACE("(%p)->(%p)\n", This
, pctinfo
);
532 static HRESULT WINAPI
domdoc_GetTypeInfo(
533 IXMLDOMDocument2
*iface
,
534 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
536 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
539 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
541 hr
= get_typeinfo(IXMLDOMDocument2_tid
, ppTInfo
);
546 static HRESULT WINAPI
domdoc_GetIDsOfNames(
547 IXMLDOMDocument2
*iface
,
554 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
558 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
561 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
564 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
567 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
568 ITypeInfo_Release(typeinfo
);
575 static HRESULT WINAPI
domdoc_Invoke(
576 IXMLDOMDocument2
*iface
,
581 DISPPARAMS
* pDispParams
,
583 EXCEPINFO
* pExcepInfo
,
586 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
590 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
591 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
593 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
596 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
597 pVarResult
, pExcepInfo
, puArgErr
);
598 ITypeInfo_Release(typeinfo
);
605 static HRESULT WINAPI
domdoc_get_nodeName(
606 IXMLDOMDocument2
*iface
,
609 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
610 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This
->node
), name
);
614 static HRESULT WINAPI
domdoc_get_nodeValue(
615 IXMLDOMDocument2
*iface
,
618 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
619 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This
->node
), value
);
623 static HRESULT WINAPI
domdoc_put_nodeValue(
624 IXMLDOMDocument2
*iface
,
627 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
628 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This
->node
), value
);
632 static HRESULT WINAPI
domdoc_get_nodeType(
633 IXMLDOMDocument2
*iface
,
636 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
637 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This
->node
), type
);
641 static HRESULT WINAPI
domdoc_get_parentNode(
642 IXMLDOMDocument2
*iface
,
643 IXMLDOMNode
** parent
)
645 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
646 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This
->node
), parent
);
650 static HRESULT WINAPI
domdoc_get_childNodes(
651 IXMLDOMDocument2
*iface
,
652 IXMLDOMNodeList
** childList
)
654 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
655 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This
->node
), childList
);
659 static HRESULT WINAPI
domdoc_get_firstChild(
660 IXMLDOMDocument2
*iface
,
661 IXMLDOMNode
** firstChild
)
663 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
664 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This
->node
), firstChild
);
668 static HRESULT WINAPI
domdoc_get_lastChild(
669 IXMLDOMDocument2
*iface
,
670 IXMLDOMNode
** lastChild
)
672 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
673 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This
->node
), lastChild
);
677 static HRESULT WINAPI
domdoc_get_previousSibling(
678 IXMLDOMDocument2
*iface
,
679 IXMLDOMNode
** previousSibling
)
681 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
682 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This
->node
), previousSibling
);
686 static HRESULT WINAPI
domdoc_get_nextSibling(
687 IXMLDOMDocument2
*iface
,
688 IXMLDOMNode
** nextSibling
)
690 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
691 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This
->node
), nextSibling
);
695 static HRESULT WINAPI
domdoc_get_attributes(
696 IXMLDOMDocument2
*iface
,
697 IXMLDOMNamedNodeMap
** attributeMap
)
699 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
700 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This
->node
), attributeMap
);
704 static HRESULT WINAPI
domdoc_insertBefore(
705 IXMLDOMDocument2
*iface
,
706 IXMLDOMNode
* newChild
,
708 IXMLDOMNode
** outNewChild
)
710 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
711 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This
->node
), newChild
, refChild
, outNewChild
);
715 static HRESULT WINAPI
domdoc_replaceChild(
716 IXMLDOMDocument2
*iface
,
717 IXMLDOMNode
* newChild
,
718 IXMLDOMNode
* oldChild
,
719 IXMLDOMNode
** outOldChild
)
721 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
722 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This
->node
), newChild
, oldChild
, outOldChild
);
726 static HRESULT WINAPI
domdoc_removeChild(
727 IXMLDOMDocument2
*iface
,
728 IXMLDOMNode
* childNode
,
729 IXMLDOMNode
** oldChild
)
731 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
732 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This
->node
), childNode
, oldChild
);
736 static HRESULT WINAPI
domdoc_appendChild(
737 IXMLDOMDocument2
*iface
,
738 IXMLDOMNode
* newChild
,
739 IXMLDOMNode
** outNewChild
)
741 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
742 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This
->node
), newChild
, outNewChild
);
746 static HRESULT WINAPI
domdoc_hasChildNodes(
747 IXMLDOMDocument2
*iface
,
748 VARIANT_BOOL
* hasChild
)
750 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
751 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This
->node
), hasChild
);
755 static HRESULT WINAPI
domdoc_get_ownerDocument(
756 IXMLDOMDocument2
*iface
,
757 IXMLDOMDocument
** DOMDocument
)
759 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
760 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This
->node
), DOMDocument
);
764 static HRESULT WINAPI
domdoc_cloneNode(
765 IXMLDOMDocument2
*iface
,
767 IXMLDOMNode
** cloneRoot
)
769 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
770 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This
->node
), deep
, cloneRoot
);
774 static HRESULT WINAPI
domdoc_get_nodeTypeString(
775 IXMLDOMDocument2
*iface
,
778 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
779 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This
->node
), nodeType
);
783 static HRESULT WINAPI
domdoc_get_text(
784 IXMLDOMDocument2
*iface
,
787 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
788 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This
->node
), text
);
792 static HRESULT WINAPI
domdoc_put_text(
793 IXMLDOMDocument2
*iface
,
796 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
797 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This
->node
), text
);
801 static HRESULT WINAPI
domdoc_get_specified(
802 IXMLDOMDocument2
*iface
,
803 VARIANT_BOOL
* isSpecified
)
805 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
806 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This
->node
), isSpecified
);
810 static HRESULT WINAPI
domdoc_get_definition(
811 IXMLDOMDocument2
*iface
,
812 IXMLDOMNode
** definitionNode
)
814 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
815 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This
->node
), definitionNode
);
819 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
820 IXMLDOMDocument2
*iface
,
821 VARIANT
* typedValue
)
823 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
824 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
827 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
828 IXMLDOMDocument2
*iface
,
831 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
832 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
836 static HRESULT WINAPI
domdoc_get_dataType(
837 IXMLDOMDocument2
*iface
,
838 VARIANT
* dataTypeName
)
840 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
841 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This
->node
), dataTypeName
);
845 static HRESULT WINAPI
domdoc_put_dataType(
846 IXMLDOMDocument2
*iface
,
849 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
850 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This
->node
), dataTypeName
);
854 static HRESULT WINAPI
domdoc_get_xml(
855 IXMLDOMDocument2
*iface
,
858 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
859 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This
->node
), xmlString
);
863 static HRESULT WINAPI
domdoc_transformNode(
864 IXMLDOMDocument2
*iface
,
865 IXMLDOMNode
* styleSheet
,
868 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
869 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This
->node
), styleSheet
, xmlString
);
873 static HRESULT WINAPI
domdoc_selectNodes(
874 IXMLDOMDocument2
*iface
,
876 IXMLDOMNodeList
** resultList
)
878 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
879 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultList
);
883 static HRESULT WINAPI
domdoc_selectSingleNode(
884 IXMLDOMDocument2
*iface
,
886 IXMLDOMNode
** resultNode
)
888 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
889 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultNode
);
893 static HRESULT WINAPI
domdoc_get_parsed(
894 IXMLDOMDocument2
*iface
,
895 VARIANT_BOOL
* isParsed
)
897 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
898 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This
->node
), isParsed
);
902 static HRESULT WINAPI
domdoc_get_namespaceURI(
903 IXMLDOMDocument2
*iface
,
906 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
907 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This
->node
), namespaceURI
);
911 static HRESULT WINAPI
domdoc_get_prefix(
912 IXMLDOMDocument2
*iface
,
915 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
916 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This
->node
), prefixString
);
920 static HRESULT WINAPI
domdoc_get_baseName(
921 IXMLDOMDocument2
*iface
,
924 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
925 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This
->node
), nameString
);
929 static HRESULT WINAPI
domdoc_transformNodeToObject(
930 IXMLDOMDocument2
*iface
,
931 IXMLDOMNode
* stylesheet
,
932 VARIANT outputObject
)
934 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
935 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This
->node
), stylesheet
, outputObject
);
939 static HRESULT WINAPI
domdoc_get_doctype(
940 IXMLDOMDocument2
*iface
,
941 IXMLDOMDocumentType
** documentType
)
948 static HRESULT WINAPI
domdoc_get_implementation(
949 IXMLDOMDocument2
*iface
,
950 IXMLDOMImplementation
** impl
)
955 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
960 static HRESULT WINAPI
domdoc_get_documentElement(
961 IXMLDOMDocument2
*iface
,
962 IXMLDOMElement
** DOMElement
)
964 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
965 xmlDocPtr xmldoc
= NULL
;
966 xmlNodePtr root
= NULL
;
967 IXMLDOMNode
*element_node
;
977 xmldoc
= get_doc( This
);
979 root
= xmlDocGetRootElement( xmldoc
);
983 element_node
= create_node( root
);
984 if(!element_node
) return S_FALSE
;
986 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (LPVOID
*)DOMElement
);
987 IXMLDOMNode_Release(element_node
);
993 static HRESULT WINAPI
domdoc_put_documentElement(
994 IXMLDOMDocument2
*iface
,
995 IXMLDOMElement
* DOMElement
)
997 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
998 IXMLDOMNode
*elementNode
;
1003 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1005 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1009 xmlNode
= impl_from_IXMLDOMNode( elementNode
);
1011 if(!xmlNode
->node
->parent
)
1012 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1013 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1015 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1016 IXMLDOMNode_Release( elementNode
);
1019 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1025 static HRESULT WINAPI
domdoc_createElement(
1026 IXMLDOMDocument2
*iface
,
1028 IXMLDOMElement
** element
)
1031 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1036 TRACE("%p->(%s,%p)\n", iface
, debugstr_w(tagname
), element
);
1038 xml_name
= xmlChar_from_wchar(tagname
);
1039 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, xml_name
, NULL
);
1040 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1042 TRACE("created xmlptr %p\n", xmlnode
);
1043 elem_unk
= create_element(xmlnode
);
1044 HeapFree(GetProcessHeap(), 0, xml_name
);
1046 hr
= IUnknown_QueryInterface(elem_unk
, &IID_IXMLDOMElement
, (void **)element
);
1047 IUnknown_Release(elem_unk
);
1048 TRACE("returning %p\n", *element
);
1053 static HRESULT WINAPI
domdoc_createDocumentFragment(
1054 IXMLDOMDocument2
*iface
,
1055 IXMLDOMDocumentFragment
** docFrag
)
1057 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1060 TRACE("%p\n", iface
);
1063 return E_INVALIDARG
;
1067 xmlnode
= xmlNewDocFragment(get_doc( This
) );
1072 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1073 *docFrag
= (IXMLDOMDocumentFragment
*)create_doc_fragment(xmlnode
);
1079 static HRESULT WINAPI
domdoc_createTextNode(
1080 IXMLDOMDocument2
*iface
,
1082 IXMLDOMText
** text
)
1084 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1086 xmlChar
*xml_content
;
1088 TRACE("%p->(%s %p)\n", iface
, debugstr_w(data
), text
);
1091 return E_INVALIDARG
;
1095 xml_content
= xmlChar_from_wchar(data
);
1096 xmlnode
= xmlNewText(xml_content
);
1097 HeapFree(GetProcessHeap(), 0, xml_content
);
1102 xmlnode
->doc
= get_doc( This
);
1103 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1105 *text
= (IXMLDOMText
*)create_text(xmlnode
);
1111 static HRESULT WINAPI
domdoc_createComment(
1112 IXMLDOMDocument2
*iface
,
1114 IXMLDOMComment
** comment
)
1116 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1118 xmlChar
*xml_content
;
1120 TRACE("%p->(%s %p)\n", iface
, debugstr_w(data
), comment
);
1123 return E_INVALIDARG
;
1127 xml_content
= xmlChar_from_wchar(data
);
1128 xmlnode
= xmlNewComment(xml_content
);
1129 HeapFree(GetProcessHeap(), 0, xml_content
);
1134 xmlnode
->doc
= get_doc( This
);
1135 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1137 *comment
= (IXMLDOMComment
*)create_comment(xmlnode
);
1143 static HRESULT WINAPI
domdoc_createCDATASection(
1144 IXMLDOMDocument2
*iface
,
1146 IXMLDOMCDATASection
** cdata
)
1148 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1150 xmlChar
*xml_content
;
1152 TRACE("%p->(%s %p)\n", iface
, debugstr_w(data
), cdata
);
1155 return E_INVALIDARG
;
1159 xml_content
= xmlChar_from_wchar(data
);
1160 xmlnode
= xmlNewCDataBlock(get_doc( This
), xml_content
, strlen( (char*)xml_content
) );
1161 HeapFree(GetProcessHeap(), 0, xml_content
);
1166 xmlnode
->doc
= get_doc( This
);
1167 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1169 *cdata
= (IXMLDOMCDATASection
*)create_cdata(xmlnode
);
1175 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1176 IXMLDOMDocument2
*iface
,
1179 IXMLDOMProcessingInstruction
** pi
)
1181 #ifdef HAVE_XMLNEWDOCPI
1183 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1184 xmlChar
*xml_target
, *xml_content
;
1186 TRACE("%p->(%s %s %p)\n", iface
, debugstr_w(target
), debugstr_w(data
), pi
);
1189 return E_INVALIDARG
;
1191 if(!target
|| lstrlenW(target
) == 0)
1194 xml_target
= xmlChar_from_wchar(target
);
1195 xml_content
= xmlChar_from_wchar(data
);
1197 xmlnode
= xmlNewDocPI(get_doc(This
), xml_target
, xml_content
);
1198 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1199 TRACE("created xmlptr %p\n", xmlnode
);
1200 *pi
= (IXMLDOMProcessingInstruction
*)create_pi(xmlnode
);
1202 HeapFree(GetProcessHeap(), 0, xml_content
);
1203 HeapFree(GetProcessHeap(), 0, xml_target
);
1207 FIXME("Libxml 2.6.15 or greater required.\n");
1213 static HRESULT WINAPI
domdoc_createAttribute(
1214 IXMLDOMDocument2
*iface
,
1216 IXMLDOMAttribute
** attribute
)
1218 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1222 TRACE("%p->(%s %p)\n", iface
, debugstr_w(name
), attribute
);
1225 return E_INVALIDARG
;
1229 xml_name
= xmlChar_from_wchar(name
);
1230 xmlnode
= (xmlNode
*)xmlNewProp(NULL
, xml_name
, NULL
);
1231 HeapFree(GetProcessHeap(), 0, xml_name
);
1236 xmlnode
->doc
= get_doc( This
);
1237 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1239 *attribute
= (IXMLDOMAttribute
*)create_attribute(xmlnode
);
1245 static HRESULT WINAPI
domdoc_createEntityReference(
1246 IXMLDOMDocument2
*iface
,
1248 IXMLDOMEntityReference
** entityRef
)
1250 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1254 TRACE("%p\n", iface
);
1257 return E_INVALIDARG
;
1261 xml_name
= xmlChar_from_wchar(name
);
1262 xmlnode
= xmlNewReference(get_doc( This
), xml_name
);
1263 HeapFree(GetProcessHeap(), 0, xml_name
);
1268 xmlnode
->doc
= get_doc( This
);
1269 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1271 *entityRef
= (IXMLDOMEntityReference
*)create_doc_entity_ref(xmlnode
);
1277 static HRESULT WINAPI
domdoc_getElementsByTagName(
1278 IXMLDOMDocument2
*iface
,
1280 IXMLDOMNodeList
** resultList
)
1282 static const WCHAR xpathformat
[] =
1283 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1284 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1287 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(tagName
), resultList
);
1289 if (tagName
[0] == '*' && tagName
[1] == 0)
1291 szPattern
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*4);
1292 szPattern
[0] = szPattern
[1] = '/';
1298 szPattern
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(20+lstrlenW(tagName
)+1));
1299 wsprintfW(szPattern
, xpathformat
, tagName
);
1302 hr
= queryresult_create((xmlNodePtr
)get_doc(This
), szPattern
, resultList
);
1303 HeapFree(GetProcessHeap(), 0, szPattern
);
1308 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1314 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1316 return E_INVALIDARG
;
1323 static HRESULT WINAPI
domdoc_createNode(
1324 IXMLDOMDocument2
*iface
,
1328 IXMLDOMNode
** node
)
1330 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1331 DOMNodeType node_type
;
1332 xmlNodePtr xmlnode
= NULL
;
1336 TRACE("(%p)->(type,%s,%s,%p)\n", This
, debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1338 if(namespaceURI
&& namespaceURI
[0])
1339 FIXME("nodes with namespaces currently not supported.\n");
1341 hr
= get_node_type(Type
, &node_type
);
1345 TRACE("node_type %d\n", node_type
);
1347 xml_name
= xmlChar_from_wchar(name
);
1352 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, xml_name
, NULL
);
1353 *node
= create_node(xmlnode
);
1354 TRACE("created %p\n", xmlnode
);
1356 case NODE_ATTRIBUTE
:
1357 xmlnode
= (xmlNode
*)xmlNewProp(NULL
, xml_name
, NULL
);
1360 xmlnode
->doc
= get_doc( This
);
1362 *node
= (IXMLDOMNode
*)create_attribute(xmlnode
);
1365 TRACE("created %p\n", xmlnode
);
1369 FIXME("unhandled node type %d\n", node_type
);
1373 HeapFree(GetProcessHeap(), 0, xml_name
);
1375 if(xmlnode
&& *node
)
1377 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1384 static HRESULT WINAPI
domdoc_nodeFromID(
1385 IXMLDOMDocument2
*iface
,
1387 IXMLDOMNode
** node
)
1393 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
1398 xmldoc
= doparse( ptr
, len
);
1400 xmldoc
->_private
= create_priv();
1401 return attach_xmldoc(&This
->node
, xmldoc
);
1407 static HRESULT
doread( domdoc
*This
, LPWSTR filename
)
1412 hr
= bind_url(filename
, domdoc_onDataAvailable
, This
, &bsc
);
1417 detach_bsc(This
->bsc
);
1423 static HRESULT WINAPI
domdoc_load(
1424 IXMLDOMDocument2
*iface
,
1426 VARIANT_BOOL
* isSuccessful
)
1428 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1429 LPWSTR filename
= NULL
;
1430 HRESULT hr
= S_FALSE
;
1431 IXMLDOMDocument2
*pNewDoc
= NULL
;
1432 IStream
*pStream
= NULL
;
1435 TRACE("type %d\n", V_VT(&xmlSource
) );
1437 *isSuccessful
= VARIANT_FALSE
;
1439 assert( &This
->node
);
1441 switch( V_VT(&xmlSource
) )
1444 filename
= V_BSTR(&xmlSource
);
1447 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IXMLDOMDocument2
, (void**)&pNewDoc
);
1452 domdoc
*newDoc
= impl_from_IXMLDOMDocument2( pNewDoc
);
1453 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
1454 hr
= attach_xmldoc(&This
->node
, xmldoc
);
1457 *isSuccessful
= VARIANT_TRUE
;
1462 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IStream
, (void**)&pStream
);
1465 IPersistStream
*pDocStream
;
1466 hr
= IUnknown_QueryInterface(iface
, &IID_IPersistStream
, (void**)&pDocStream
);
1469 hr
= xmldoc_IPersistStream_Load(pDocStream
, pStream
);
1470 IStream_Release(pStream
);
1473 *isSuccessful
= VARIANT_TRUE
;
1475 TRACE("Using ID_IStream to load Document\n");
1480 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr
);
1485 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr
);
1490 /* ISequentialStream */
1491 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr
, pNewDoc
, V_UNKNOWN(&xmlSource
)->lpVtbl
);
1495 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource
));
1498 TRACE("filename (%s)\n", debugstr_w(filename
));
1502 hr
= doread( This
, filename
);
1505 This
->error
= E_FAIL
;
1508 hr
= This
->error
= S_OK
;
1509 *isSuccessful
= VARIANT_TRUE
;
1513 if(!filename
|| FAILED(hr
)) {
1514 xmldoc
= xmlNewDoc(NULL
);
1515 xmldoc
->_private
= create_priv();
1516 hr
= attach_xmldoc(&This
->node
, xmldoc
);
1521 TRACE("ret (%d)\n", hr
);
1527 static HRESULT WINAPI
domdoc_get_readyState(
1528 IXMLDOMDocument2
*iface
,
1536 static HRESULT WINAPI
domdoc_get_parseError(
1537 IXMLDOMDocument2
*iface
,
1538 IXMLDOMParseError
** errorObj
)
1540 BSTR error_string
= NULL
;
1541 static const WCHAR err
[] = {'e','r','r','o','r',0};
1542 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1544 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
1547 error_string
= SysAllocString(err
);
1549 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
1550 if(!*errorObj
) return E_OUTOFMEMORY
;
1555 static HRESULT WINAPI
domdoc_get_url(
1556 IXMLDOMDocument2
*iface
,
1564 static HRESULT WINAPI
domdoc_get_async(
1565 IXMLDOMDocument2
*iface
,
1566 VARIANT_BOOL
* isAsync
)
1568 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1570 TRACE("%p <- %d\n", isAsync
, This
->async
);
1571 *isAsync
= This
->async
;
1576 static HRESULT WINAPI
domdoc_put_async(
1577 IXMLDOMDocument2
*iface
,
1578 VARIANT_BOOL isAsync
)
1580 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1582 TRACE("%d\n", isAsync
);
1583 This
->async
= isAsync
;
1588 static HRESULT WINAPI
domdoc_abort(
1589 IXMLDOMDocument2
*iface
)
1596 static BOOL
bstr_to_utf8( BSTR bstr
, char **pstr
, int *plen
)
1598 UINT len
, blen
= SysStringLen( bstr
);
1601 len
= WideCharToMultiByte( CP_UTF8
, 0, bstr
, blen
, NULL
, 0, NULL
, NULL
);
1602 str
= HeapAlloc( GetProcessHeap(), 0, len
);
1605 WideCharToMultiByte( CP_UTF8
, 0, bstr
, blen
, str
, len
, NULL
, NULL
);
1611 static HRESULT WINAPI
domdoc_loadXML(
1612 IXMLDOMDocument2
*iface
,
1614 VARIANT_BOOL
* isSuccessful
)
1616 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1617 xmlDocPtr xmldoc
= NULL
;
1620 HRESULT hr
= S_FALSE
, hr2
;
1622 TRACE("%p %s %p\n", This
, debugstr_w( bstrXML
), isSuccessful
);
1624 assert ( &This
->node
);
1628 *isSuccessful
= VARIANT_FALSE
;
1630 if ( bstrXML
&& bstr_to_utf8( bstrXML
, &str
, &len
) )
1632 xmldoc
= doparse( str
, len
);
1633 HeapFree( GetProcessHeap(), 0, str
);
1635 This
->error
= E_FAIL
;
1638 hr
= This
->error
= S_OK
;
1639 *isSuccessful
= VARIANT_TRUE
;
1644 xmldoc
= xmlNewDoc(NULL
);
1646 xmldoc
->_private
= create_priv();
1647 hr2
= attach_xmldoc( &This
->node
, xmldoc
);
1655 static HRESULT WINAPI
domdoc_save(
1656 IXMLDOMDocument2
*iface
,
1657 VARIANT destination
)
1659 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1666 TRACE("(%p)->(var(vt %d, %s))\n", This
, V_VT(&destination
),
1667 V_VT(&destination
) == VT_BSTR
? debugstr_w(V_BSTR(&destination
)) : NULL
);
1669 if(V_VT(&destination
) != VT_BSTR
&& V_VT(&destination
) != VT_UNKNOWN
)
1671 FIXME("Unhandled vt %d\n", V_VT(&destination
));
1675 if(V_VT(&destination
) == VT_UNKNOWN
)
1677 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
1678 IXMLDOMDocument
*pDocument
;
1680 ret
= IXMLDOMDocument_QueryInterface(pUnk
, &IID_IXMLDOMDocument2
, (void**)&pDocument
);
1684 VARIANT_BOOL bSuccessful
;
1686 ret
= IXMLDOMDocument_get_xml(iface
, &bXML
);
1689 ret
= IXMLDOMDocument_loadXML(pDocument
, bXML
, &bSuccessful
);
1691 SysFreeString(bXML
);
1694 IXMLDOMDocument_Release(pDocument
);
1697 TRACE("ret %d\n", ret
);
1702 handle
= CreateFileW( V_BSTR(&destination
), GENERIC_WRITE
, 0,
1703 NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1704 if( handle
== INVALID_HANDLE_VALUE
)
1706 WARN("failed to create file\n");
1710 xmlDocDumpMemory(get_doc(This
), &mem
, &size
);
1713 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1714 * MSXML adds XML declaration only for processing instruction nodes.
1715 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1718 if(size
> 2 && p
[0] == '<' && p
[1] == '?') {
1719 while(p
< mem
+size
&& (p
[0] != '?' || p
[1] != '>'))
1722 while(p
< mem
+size
&& isspace(*p
))
1727 if(!WriteFile(handle
, p
, (DWORD
)size
, &written
, NULL
) || written
!= (DWORD
)size
)
1729 WARN("write error\n");
1734 CloseHandle(handle
);
1738 static HRESULT WINAPI
domdoc_get_validateOnParse(
1739 IXMLDOMDocument2
*iface
,
1740 VARIANT_BOOL
* isValidating
)
1742 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1744 TRACE("%p <- %d\n", isValidating
, This
->validating
);
1745 *isValidating
= This
->validating
;
1750 static HRESULT WINAPI
domdoc_put_validateOnParse(
1751 IXMLDOMDocument2
*iface
,
1752 VARIANT_BOOL isValidating
)
1754 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1756 TRACE("%d\n", isValidating
);
1757 This
->validating
= isValidating
;
1762 static HRESULT WINAPI
domdoc_get_resolveExternals(
1763 IXMLDOMDocument2
*iface
,
1764 VARIANT_BOOL
* isResolving
)
1766 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1768 TRACE("%p <- %d\n", isResolving
, This
->resolving
);
1769 *isResolving
= This
->resolving
;
1774 static HRESULT WINAPI
domdoc_put_resolveExternals(
1775 IXMLDOMDocument2
*iface
,
1776 VARIANT_BOOL isResolving
)
1778 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1780 TRACE("%d\n", isResolving
);
1781 This
->resolving
= isResolving
;
1786 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
1787 IXMLDOMDocument2
*iface
,
1788 VARIANT_BOOL
* isPreserving
)
1790 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1792 TRACE("%p <- %d\n", isPreserving
, This
->preserving
);
1793 *isPreserving
= This
->preserving
;
1798 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
1799 IXMLDOMDocument2
*iface
,
1800 VARIANT_BOOL isPreserving
)
1802 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1804 TRACE("%d\n", isPreserving
);
1805 This
->preserving
= isPreserving
;
1810 static HRESULT WINAPI
domdoc_put_onReadyStateChange(
1811 IXMLDOMDocument2
*iface
,
1812 VARIANT readyStateChangeSink
)
1819 static HRESULT WINAPI
domdoc_put_onDataAvailable(
1820 IXMLDOMDocument2
*iface
,
1821 VARIANT onDataAvailableSink
)
1827 static HRESULT WINAPI
domdoc_put_onTransformNode(
1828 IXMLDOMDocument2
*iface
,
1829 VARIANT onTransformNodeSink
)
1835 static HRESULT WINAPI
domdoc_get_namespaces(
1836 IXMLDOMDocument2
* iface
,
1837 IXMLDOMSchemaCollection
** schemaCollection
)
1843 static HRESULT WINAPI
domdoc_get_schemas(
1844 IXMLDOMDocument2
* iface
,
1847 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1848 HRESULT hr
= S_FALSE
;
1849 IXMLDOMSchemaCollection
*cur_schema
= This
->schema
;
1851 TRACE("(%p)->(%p)\n", This
, var1
);
1853 VariantInit(var1
); /* Test shows we don't call VariantClear here */
1854 V_VT(var1
) = VT_NULL
;
1858 hr
= IXMLDOMSchemaCollection_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(var1
));
1860 V_VT(var1
) = VT_DISPATCH
;
1865 static HRESULT WINAPI
domdoc_putref_schemas(
1866 IXMLDOMDocument2
* iface
,
1869 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1870 HRESULT hr
= E_FAIL
;
1871 IXMLDOMSchemaCollection
*new_schema
= NULL
;
1873 FIXME("(%p): semi-stub\n", This
);
1877 hr
= IUnknown_QueryInterface(V_UNKNOWN(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
1881 hr
= IDispatch_QueryInterface(V_DISPATCH(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
1890 WARN("Can't get schema from vt %x\n", V_VT(&var1
));
1895 IXMLDOMSchemaCollection
*old_schema
= InterlockedExchangePointer((void**)&This
->schema
, new_schema
);
1896 if(old_schema
) IXMLDOMSchemaCollection_Release(old_schema
);
1902 static HRESULT WINAPI
domdoc_validate(
1903 IXMLDOMDocument2
* iface
,
1904 IXMLDOMParseError
** err
)
1910 static HRESULT WINAPI
domdoc_setProperty(
1911 IXMLDOMDocument2
* iface
,
1915 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1917 if (lstrcmpiW(p
, SZ_PROPERTY_SELECTION_LANGUAGE
) == 0)
1923 V_VT(&varStr
) = VT_EMPTY
;
1924 if (V_VT(&var
) != VT_BSTR
)
1926 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
1928 bstr
= V_BSTR(&varStr
);
1931 bstr
= V_BSTR(&var
);
1934 if (lstrcmpiW(bstr
, SZ_VALUE_XPATH
) == 0)
1935 This
->bUseXPath
= TRUE
;
1936 else if (lstrcmpiW(bstr
, SZ_VALUE_XSLPATTERN
) == 0)
1937 This
->bUseXPath
= FALSE
;
1941 VariantClear(&varStr
);
1945 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
1949 static HRESULT WINAPI
domdoc_getProperty(
1950 IXMLDOMDocument2
* iface
,
1954 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1957 return E_INVALIDARG
;
1958 if (lstrcmpiW(p
, SZ_PROPERTY_SELECTION_LANGUAGE
) == 0)
1960 V_VT(var
) = VT_BSTR
;
1961 if (This
->bUseXPath
)
1962 V_BSTR(var
) = SysAllocString(SZ_VALUE_XPATH
);
1964 V_BSTR(var
) = SysAllocString(SZ_VALUE_XSLPATTERN
);
1968 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
1972 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl
=
1974 domdoc_QueryInterface
,
1977 domdoc_GetTypeInfoCount
,
1979 domdoc_GetIDsOfNames
,
1981 domdoc_get_nodeName
,
1982 domdoc_get_nodeValue
,
1983 domdoc_put_nodeValue
,
1984 domdoc_get_nodeType
,
1985 domdoc_get_parentNode
,
1986 domdoc_get_childNodes
,
1987 domdoc_get_firstChild
,
1988 domdoc_get_lastChild
,
1989 domdoc_get_previousSibling
,
1990 domdoc_get_nextSibling
,
1991 domdoc_get_attributes
,
1992 domdoc_insertBefore
,
1993 domdoc_replaceChild
,
1996 domdoc_hasChildNodes
,
1997 domdoc_get_ownerDocument
,
1999 domdoc_get_nodeTypeString
,
2002 domdoc_get_specified
,
2003 domdoc_get_definition
,
2004 domdoc_get_nodeTypedValue
,
2005 domdoc_put_nodeTypedValue
,
2006 domdoc_get_dataType
,
2007 domdoc_put_dataType
,
2009 domdoc_transformNode
,
2011 domdoc_selectSingleNode
,
2013 domdoc_get_namespaceURI
,
2015 domdoc_get_baseName
,
2016 domdoc_transformNodeToObject
,
2018 domdoc_get_implementation
,
2019 domdoc_get_documentElement
,
2020 domdoc_put_documentElement
,
2021 domdoc_createElement
,
2022 domdoc_createDocumentFragment
,
2023 domdoc_createTextNode
,
2024 domdoc_createComment
,
2025 domdoc_createCDATASection
,
2026 domdoc_createProcessingInstruction
,
2027 domdoc_createAttribute
,
2028 domdoc_createEntityReference
,
2029 domdoc_getElementsByTagName
,
2033 domdoc_get_readyState
,
2034 domdoc_get_parseError
,
2041 domdoc_get_validateOnParse
,
2042 domdoc_put_validateOnParse
,
2043 domdoc_get_resolveExternals
,
2044 domdoc_put_resolveExternals
,
2045 domdoc_get_preserveWhiteSpace
,
2046 domdoc_put_preserveWhiteSpace
,
2047 domdoc_put_onReadyStateChange
,
2048 domdoc_put_onDataAvailable
,
2049 domdoc_put_onTransformNode
,
2050 domdoc_get_namespaces
,
2052 domdoc_putref_schemas
,
2058 /* xmldoc implementation of IObjectWithSite */
2059 static HRESULT WINAPI
2060 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
2062 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2063 return IXMLDocument_QueryInterface( (IXMLDocument
*)This
, riid
, ppvObject
);
2067 xmldoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
2069 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2070 return IXMLDocument_AddRef((IXMLDocument
*)This
);
2074 xmldoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
2076 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2077 return IXMLDocument_Release((IXMLDocument
*)This
);
2080 static HRESULT WINAPI
2081 xmldoc_GetSite( IObjectWithSite
*iface
, REFIID iid
, void ** ppvSite
)
2083 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2085 TRACE("%p %s %p\n", This
, debugstr_guid( iid
), ppvSite
);
2090 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
2093 static HRESULT WINAPI
2094 xmldoc_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
2096 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2098 TRACE("%p %p\n", iface
, punk
);
2104 IUnknown_Release( This
->site
);
2112 IUnknown_AddRef( punk
);
2115 IUnknown_Release( This
->site
);
2122 static const IObjectWithSiteVtbl domdocObjectSite
=
2124 xmldoc_ObjectWithSite_QueryInterface
,
2125 xmldoc_ObjectWithSite_AddRef
,
2126 xmldoc_ObjectWithSite_Release
,
2131 static HRESULT WINAPI
xmldoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
2133 domdoc
*This
= impl_from_IObjectSafety(iface
);
2134 return IXMLDocument_QueryInterface( (IXMLDocument
*)This
, riid
, ppv
);
2137 static ULONG WINAPI
xmldoc_Safety_AddRef(IObjectSafety
*iface
)
2139 domdoc
*This
= impl_from_IObjectSafety(iface
);
2140 return IXMLDocument_AddRef((IXMLDocument
*)This
);
2143 static ULONG WINAPI
xmldoc_Safety_Release(IObjectSafety
*iface
)
2145 domdoc
*This
= impl_from_IObjectSafety(iface
);
2146 return IXMLDocument_Release((IXMLDocument
*)This
);
2149 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2151 static HRESULT WINAPI
xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
2152 DWORD
*pdwSupportedOptions
, DWORD
*pdwEnabledOptions
)
2154 domdoc
*This
= impl_from_IObjectSafety(iface
);
2156 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), pdwSupportedOptions
, pdwEnabledOptions
);
2158 if(!pdwSupportedOptions
|| !pdwEnabledOptions
)
2161 *pdwSupportedOptions
= SUPPORTED_OPTIONS
;
2162 *pdwEnabledOptions
= This
->safeopt
;
2167 static HRESULT WINAPI
xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
2168 DWORD dwOptionSetMask
, DWORD dwEnabledOptions
)
2170 domdoc
*This
= impl_from_IObjectSafety(iface
);
2172 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), dwOptionSetMask
, dwEnabledOptions
);
2174 if(dwOptionSetMask
& ~SUPPORTED_OPTIONS
)
2177 This
->safeopt
= dwEnabledOptions
& dwEnabledOptions
;
2181 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
2182 xmldoc_Safety_QueryInterface
,
2183 xmldoc_Safety_AddRef
,
2184 xmldoc_Safety_Release
,
2185 xmldoc_Safety_GetInterfaceSafetyOptions
,
2186 xmldoc_Safety_SetInterfaceSafetyOptions
2190 static const tid_t domdoc_iface_tids
[] = {
2192 IXMLDOMDocument_tid
,
2193 IXMLDOMDocument2_tid
,
2196 static dispex_static_data_t domdoc_dispex
= {
2198 IXMLDOMDocument2_tid
,
2203 HRESULT
DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument2
**document
)
2207 doc
= HeapAlloc( GetProcessHeap(), 0, sizeof (*doc
) );
2209 return E_OUTOFMEMORY
;
2211 doc
->lpVtbl
= &domdoc_vtbl
;
2212 doc
->lpvtblIPersistStream
= &xmldoc_IPersistStream_VTable
;
2213 doc
->lpvtblIObjectWithSite
= &domdocObjectSite
;
2214 doc
->lpvtblIObjectSafety
= &domdocObjectSafetyVtbl
;
2215 doc
->lpvtblISupportErrorInfo
= &support_error_vtbl
;
2217 doc
->async
= VARIANT_TRUE
;
2218 doc
->validating
= 0;
2220 doc
->preserving
= 0;
2221 doc
->bUseXPath
= FALSE
;
2229 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IUnknown
*)&doc
->lpVtbl
, &domdoc_dispex
);
2231 *document
= (IXMLDOMDocument2
*)&doc
->lpVtbl
;
2233 TRACE("returning iface %p\n", *document
);
2237 HRESULT
DOMDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
2242 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
2244 xmldoc
= xmlNewDoc(NULL
);
2246 return E_OUTOFMEMORY
;
2248 xmldoc
->_private
= create_priv();
2250 hr
= DOMDocument_create_from_xmldoc(xmldoc
, (IXMLDOMDocument2
**)ppObj
);
2257 IUnknown
* create_domdoc( xmlNodePtr document
)
2262 TRACE("(%p)\n", document
);
2264 hr
= DOMDocument_create_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument2
**)&pObj
);
2273 HRESULT
DOMDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
2275 MESSAGE("This program tried to use a DOMDocument object, but\n"
2276 "libxml2 support was not present at compile time.\n");