2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 #include "msxml_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
50 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE
[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
51 static const WCHAR SZ_VALUE_XPATH
[] = {'X','P','a','t','h',0};
52 static const WCHAR SZ_VALUE_XSLPATTERN
[] = {'X','S','L','P','a','t','t','e','r','n',0};
54 typedef struct _domdoc
56 const struct IXMLDOMDocument2Vtbl
*lpVtbl
;
57 const struct IPersistStreamVtbl
*lpvtblIPersistStream
;
58 const struct IObjectWithSiteVtbl
*lpvtblIObjectWithSite
;
59 const struct IObjectSafetyVtbl
*lpvtblIObjectSafety
;
60 const struct ISupportErrorInfoVtbl
*lpvtblISupportErrorInfo
;
63 VARIANT_BOOL validating
;
64 VARIANT_BOOL resolving
;
65 VARIANT_BOOL preserving
;
69 IXMLDOMSchemaCollection
*schema
;
87 In native windows, the whole lifetime management of XMLDOMNodes is
88 managed automatically using reference counts. Wine emulates that by
89 maintaining a reference count to the document that is increased for
90 each IXMLDOMNode pointer passed out for this document. If all these
91 pointers are gone, the document is unreachable and gets freed, that
92 is, all nodes in the tree of the document get freed.
94 You are able to create nodes that are associated to a document (in
95 fact, in msxml's XMLDOM model, all nodes are associated to a document),
96 but not in the tree of that document, for example using the createFoo
97 functions from IXMLDOMDocument. These nodes do not get cleaned up
98 by libxml, so we have to do it ourselves.
100 To catch these nodes, a list of "orphan nodes" is introduced.
101 It contains pointers to all roots of node trees that are
102 associated with the document without being part of the document
103 tree. All nodes with parent==NULL (except for the document root nodes)
104 should be in the orphan node list of their document. All orphan nodes
105 get freed together with the document itself.
108 typedef struct _xmldoc_priv
{
113 typedef struct _orphan_entry
{
118 static inline xmldoc_priv
* priv_from_xmlDocPtr(xmlDocPtr doc
)
120 return doc
->_private
;
123 static xmldoc_priv
* create_priv(void)
126 priv
= HeapAlloc( GetProcessHeap(), 0, sizeof (*priv
) );
131 list_init( &priv
->orphans
);
137 static xmlDocPtr
doparse( char *ptr
, int len
)
139 #ifdef HAVE_XMLREADMEMORY
141 * use xmlReadMemory if possible so we can suppress
142 * writing errors to stderr
144 return xmlReadMemory( ptr
, len
, NULL
, NULL
,
145 XML_PARSE_NOERROR
| XML_PARSE_NOWARNING
| XML_PARSE_NOBLANKS
);
147 return xmlParseMemory( ptr
, len
);
151 LONG
xmldoc_add_ref(xmlDocPtr doc
)
153 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
158 LONG
xmldoc_release(xmlDocPtr doc
)
160 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
161 LONG ref
= InterlockedDecrement(&priv
->refs
);
165 orphan_entry
*orphan
, *orphan2
;
166 TRACE("freeing docptr %p\n", doc
);
168 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
170 xmlFreeNode( orphan
->node
);
171 HeapFree( GetProcessHeap(), 0, orphan
);
173 HeapFree(GetProcessHeap(), 0, doc
->_private
);
181 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
183 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
186 entry
= HeapAlloc( GetProcessHeap(), 0, sizeof (*entry
) );
188 return E_OUTOFMEMORY
;
191 list_add_head( &priv
->orphans
, &entry
->entry
);
195 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
197 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
198 orphan_entry
*entry
, *entry2
;
200 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
202 if( entry
->node
== node
)
204 list_remove( &entry
->entry
);
205 HeapFree( GetProcessHeap(), 0, entry
);
213 static HRESULT
attach_xmldoc( IXMLDOMNode
*node
, xmlDocPtr xml
)
215 xmlnode
*This
= impl_from_IXMLDOMNode( node
);
218 xmldoc_release(This
->node
->doc
);
220 This
->node
= (xmlNodePtr
) xml
;
222 xmldoc_add_ref(This
->node
->doc
);
227 static inline domdoc
*impl_from_IXMLDOMDocument2( IXMLDOMDocument2
*iface
)
229 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpVtbl
));
232 static inline xmlDocPtr
get_doc( domdoc
*This
)
234 return (xmlDocPtr
) xmlNodePtr_from_domnode( This
->node
, XML_DOCUMENT_NODE
);
237 static inline domdoc
*impl_from_IPersistStream(IPersistStream
*iface
)
239 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIPersistStream
));
242 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
244 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectWithSite
));
247 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
249 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectSafety
));
252 static inline domdoc
*impl_from_ISupportErrorInfo(ISupportErrorInfo
*iface
)
254 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblISupportErrorInfo
));
257 /************************************************************************
258 * xmldoc implementation of IPersistStream.
260 static HRESULT WINAPI
xmldoc_IPersistStream_QueryInterface(
261 IPersistStream
*iface
, REFIID riid
, LPVOID
*ppvObj
)
263 domdoc
*this = impl_from_IPersistStream(iface
);
264 return IXMLDocument_QueryInterface((IXMLDocument
*)this, riid
, ppvObj
);
267 static ULONG WINAPI
xmldoc_IPersistStream_AddRef(
268 IPersistStream
*iface
)
270 domdoc
*this = impl_from_IPersistStream(iface
);
271 return IXMLDocument_AddRef((IXMLDocument
*)this);
274 static ULONG WINAPI
xmldoc_IPersistStream_Release(
275 IPersistStream
*iface
)
277 domdoc
*this = impl_from_IPersistStream(iface
);
278 return IXMLDocument_Release((IXMLDocument
*)this);
281 static HRESULT WINAPI
xmldoc_IPersistStream_GetClassID(
282 IPersistStream
*iface
, CLSID
*classid
)
284 TRACE("(%p,%p): stub!\n", iface
, classid
);
289 *classid
= CLSID_DOMDocument2
;
294 static HRESULT WINAPI
xmldoc_IPersistStream_IsDirty(
295 IPersistStream
*iface
)
297 domdoc
*This
= impl_from_IPersistStream(iface
);
299 FIXME("(%p->%p): stub!\n", iface
, This
);
304 static HRESULT WINAPI
xmldoc_IPersistStream_Load(
305 IPersistStream
*iface
, LPSTREAM pStm
)
307 domdoc
*This
= impl_from_IPersistStream(iface
);
310 DWORD read
, written
, len
;
313 xmlDocPtr xmldoc
= NULL
;
315 TRACE("(%p, %p)\n", iface
, pStm
);
320 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
326 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
327 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
328 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
332 ERR("Failed to copy stream\n");
336 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
340 len
= GlobalSize(hglobal
);
341 ptr
= GlobalLock(hglobal
);
343 xmldoc
= parse_xml(ptr
, len
);
344 GlobalUnlock(hglobal
);
348 ERR("Failed to parse xml\n");
352 xmldoc
->_private
= create_priv();
354 return attach_xmldoc( This
->node
, xmldoc
);
357 static HRESULT WINAPI
xmldoc_IPersistStream_Save(
358 IPersistStream
*iface
, LPSTREAM pStm
, BOOL fClearDirty
)
360 FIXME("(%p, %p, %d): stub!\n", iface
, pStm
, fClearDirty
);
364 static HRESULT WINAPI
xmldoc_IPersistStream_GetSizeMax(
365 IPersistStream
*iface
, ULARGE_INTEGER
*pcbSize
)
367 TRACE("(%p, %p): stub!\n", iface
, pcbSize
);
371 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable
=
373 xmldoc_IPersistStream_QueryInterface
,
374 xmldoc_IPersistStream_AddRef
,
375 xmldoc_IPersistStream_Release
,
376 xmldoc_IPersistStream_GetClassID
,
377 xmldoc_IPersistStream_IsDirty
,
378 xmldoc_IPersistStream_Load
,
379 xmldoc_IPersistStream_Save
,
380 xmldoc_IPersistStream_GetSizeMax
,
383 /* ISupportErrorInfo interface */
384 static HRESULT WINAPI
support_error_QueryInterface(
385 ISupportErrorInfo
*iface
,
386 REFIID riid
, void** ppvObj
)
388 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
389 return IXMLDocument_QueryInterface((IXMLDocument
*)This
, riid
, ppvObj
);
392 static ULONG WINAPI
support_error_AddRef(
393 ISupportErrorInfo
*iface
)
395 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
396 return IXMLDocument_AddRef((IXMLDocument
*)This
);
399 static ULONG WINAPI
support_error_Release(
400 ISupportErrorInfo
*iface
)
402 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
403 return IXMLDocument_Release((IXMLDocument
*)This
);
406 static HRESULT WINAPI
support_error_InterfaceSupportsErrorInfo(
407 ISupportErrorInfo
*iface
,
410 FIXME("(%p)->(%s)\n", iface
, debugstr_guid(riid
));
414 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
416 support_error_QueryInterface
,
417 support_error_AddRef
,
418 support_error_Release
,
419 support_error_InterfaceSupportsErrorInfo
422 /* IXMLDOMDocument2 interface */
423 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument2
*iface
, REFIID riid
, void** ppvObject
)
425 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
427 TRACE("%p %s %p\n", This
, debugstr_guid( riid
), ppvObject
);
431 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
432 IsEqualGUID( riid
, &IID_IDispatch
) ||
433 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
434 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
) )
438 else if ( IsEqualGUID( riid
, &IID_IXMLDOMNode
) )
440 return IUnknown_QueryInterface(This
->node_unk
, riid
, ppvObject
);
442 else if (IsEqualGUID(&IID_IPersistStream
, riid
))
444 *ppvObject
= (IPersistStream
*)&(This
->lpvtblIPersistStream
);
446 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
448 *ppvObject
= (IObjectWithSite
*)&(This
->lpvtblIObjectWithSite
);
450 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
452 *ppvObject
= &This
->lpvtblISupportErrorInfo
;
454 else if(dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
456 return *ppvObject
? S_OK
: E_NOINTERFACE
;
458 else if(IsEqualGUID(&IID_IRunnableObject
, riid
))
460 TRACE("IID_IRunnableObject not supported returning NULL\n");
461 return E_NOINTERFACE
;
465 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
466 return E_NOINTERFACE
;
469 IXMLDOMDocument_AddRef( iface
);
475 static ULONG WINAPI
domdoc_AddRef(
476 IXMLDOMDocument2
*iface
)
478 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
479 TRACE("%p\n", This
);
480 return InterlockedIncrement( &This
->ref
);
484 static ULONG WINAPI
domdoc_Release(
485 IXMLDOMDocument2
*iface
)
487 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
490 TRACE("%p\n", This
);
492 ref
= InterlockedDecrement( &This
->ref
);
496 detach_bsc(This
->bsc
);
499 IUnknown_Release( This
->site
);
500 IUnknown_Release( This
->node_unk
);
501 if(This
->schema
) IXMLDOMSchemaCollection_Release( This
->schema
);
502 if (This
->stream
) IStream_Release(This
->stream
);
503 HeapFree( GetProcessHeap(), 0, This
);
509 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument2
*iface
, UINT
* pctinfo
)
511 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
513 TRACE("(%p)->(%p)\n", This
, pctinfo
);
520 static HRESULT WINAPI
domdoc_GetTypeInfo(
521 IXMLDOMDocument2
*iface
,
522 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
524 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
527 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
529 hr
= get_typeinfo(IXMLDOMDocument2_tid
, ppTInfo
);
534 static HRESULT WINAPI
domdoc_GetIDsOfNames(
535 IXMLDOMDocument2
*iface
,
542 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
546 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
549 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
552 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
555 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
556 ITypeInfo_Release(typeinfo
);
563 static HRESULT WINAPI
domdoc_Invoke(
564 IXMLDOMDocument2
*iface
,
569 DISPPARAMS
* pDispParams
,
571 EXCEPINFO
* pExcepInfo
,
574 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
578 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
579 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
581 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
584 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
585 pVarResult
, pExcepInfo
, puArgErr
);
586 ITypeInfo_Release(typeinfo
);
593 static HRESULT WINAPI
domdoc_get_nodeName(
594 IXMLDOMDocument2
*iface
,
597 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
598 return IXMLDOMNode_get_nodeName( This
->node
, name
);
602 static HRESULT WINAPI
domdoc_get_nodeValue(
603 IXMLDOMDocument2
*iface
,
606 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
607 return IXMLDOMNode_get_nodeValue( This
->node
, value
);
611 static HRESULT WINAPI
domdoc_put_nodeValue(
612 IXMLDOMDocument2
*iface
,
615 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
616 return IXMLDOMNode_put_nodeValue( This
->node
, value
);
620 static HRESULT WINAPI
domdoc_get_nodeType(
621 IXMLDOMDocument2
*iface
,
624 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
625 return IXMLDOMNode_get_nodeType( This
->node
, type
);
629 static HRESULT WINAPI
domdoc_get_parentNode(
630 IXMLDOMDocument2
*iface
,
631 IXMLDOMNode
** parent
)
633 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
634 return IXMLDOMNode_get_parentNode( This
->node
, parent
);
638 static HRESULT WINAPI
domdoc_get_childNodes(
639 IXMLDOMDocument2
*iface
,
640 IXMLDOMNodeList
** childList
)
642 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
643 return IXMLDOMNode_get_childNodes( This
->node
, childList
);
647 static HRESULT WINAPI
domdoc_get_firstChild(
648 IXMLDOMDocument2
*iface
,
649 IXMLDOMNode
** firstChild
)
651 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
652 return IXMLDOMNode_get_firstChild( This
->node
, firstChild
);
656 static HRESULT WINAPI
domdoc_get_lastChild(
657 IXMLDOMDocument2
*iface
,
658 IXMLDOMNode
** lastChild
)
660 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
661 return IXMLDOMNode_get_lastChild( This
->node
, lastChild
);
665 static HRESULT WINAPI
domdoc_get_previousSibling(
666 IXMLDOMDocument2
*iface
,
667 IXMLDOMNode
** previousSibling
)
669 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
670 return IXMLDOMNode_get_previousSibling( This
->node
, previousSibling
);
674 static HRESULT WINAPI
domdoc_get_nextSibling(
675 IXMLDOMDocument2
*iface
,
676 IXMLDOMNode
** nextSibling
)
678 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
679 return IXMLDOMNode_get_nextSibling( This
->node
, nextSibling
);
683 static HRESULT WINAPI
domdoc_get_attributes(
684 IXMLDOMDocument2
*iface
,
685 IXMLDOMNamedNodeMap
** attributeMap
)
687 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
688 return IXMLDOMNode_get_attributes( This
->node
, attributeMap
);
692 static HRESULT WINAPI
domdoc_insertBefore(
693 IXMLDOMDocument2
*iface
,
694 IXMLDOMNode
* newChild
,
696 IXMLDOMNode
** outNewChild
)
698 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
699 return IXMLDOMNode_insertBefore( This
->node
, newChild
, refChild
, outNewChild
);
703 static HRESULT WINAPI
domdoc_replaceChild(
704 IXMLDOMDocument2
*iface
,
705 IXMLDOMNode
* newChild
,
706 IXMLDOMNode
* oldChild
,
707 IXMLDOMNode
** outOldChild
)
709 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
710 return IXMLDOMNode_replaceChild( This
->node
, newChild
, oldChild
, outOldChild
);
714 static HRESULT WINAPI
domdoc_removeChild(
715 IXMLDOMDocument2
*iface
,
716 IXMLDOMNode
* childNode
,
717 IXMLDOMNode
** oldChild
)
719 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
720 return IXMLDOMNode_removeChild( This
->node
, childNode
, oldChild
);
724 static HRESULT WINAPI
domdoc_appendChild(
725 IXMLDOMDocument2
*iface
,
726 IXMLDOMNode
* newChild
,
727 IXMLDOMNode
** outNewChild
)
729 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
730 return IXMLDOMNode_appendChild( This
->node
, newChild
, outNewChild
);
734 static HRESULT WINAPI
domdoc_hasChildNodes(
735 IXMLDOMDocument2
*iface
,
736 VARIANT_BOOL
* hasChild
)
738 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
739 return IXMLDOMNode_hasChildNodes( This
->node
, hasChild
);
743 static HRESULT WINAPI
domdoc_get_ownerDocument(
744 IXMLDOMDocument2
*iface
,
745 IXMLDOMDocument
** DOMDocument
)
747 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
748 return IXMLDOMNode_get_ownerDocument( This
->node
, DOMDocument
);
752 static HRESULT WINAPI
domdoc_cloneNode(
753 IXMLDOMDocument2
*iface
,
755 IXMLDOMNode
** cloneRoot
)
757 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
758 return IXMLDOMNode_cloneNode( This
->node
, deep
, cloneRoot
);
762 static HRESULT WINAPI
domdoc_get_nodeTypeString(
763 IXMLDOMDocument2
*iface
,
766 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
767 return IXMLDOMNode_get_nodeTypeString( This
->node
, nodeType
);
771 static HRESULT WINAPI
domdoc_get_text(
772 IXMLDOMDocument2
*iface
,
775 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
776 return IXMLDOMNode_get_text( This
->node
, text
);
780 static HRESULT WINAPI
domdoc_put_text(
781 IXMLDOMDocument2
*iface
,
784 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
785 return IXMLDOMNode_put_text( This
->node
, text
);
789 static HRESULT WINAPI
domdoc_get_specified(
790 IXMLDOMDocument2
*iface
,
791 VARIANT_BOOL
* isSpecified
)
793 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
794 return IXMLDOMNode_get_specified( This
->node
, isSpecified
);
798 static HRESULT WINAPI
domdoc_get_definition(
799 IXMLDOMDocument2
*iface
,
800 IXMLDOMNode
** definitionNode
)
802 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
803 return IXMLDOMNode_get_definition( This
->node
, definitionNode
);
807 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
808 IXMLDOMDocument2
*iface
,
809 VARIANT
* typedValue
)
811 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
812 return IXMLDOMNode_get_nodeTypedValue( This
->node
, typedValue
);
815 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
816 IXMLDOMDocument2
*iface
,
819 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
820 return IXMLDOMNode_put_nodeTypedValue( This
->node
, typedValue
);
824 static HRESULT WINAPI
domdoc_get_dataType(
825 IXMLDOMDocument2
*iface
,
826 VARIANT
* dataTypeName
)
828 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
829 return IXMLDOMNode_get_dataType( This
->node
, dataTypeName
);
833 static HRESULT WINAPI
domdoc_put_dataType(
834 IXMLDOMDocument2
*iface
,
837 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
838 return IXMLDOMNode_put_dataType( This
->node
, dataTypeName
);
842 static HRESULT WINAPI
domdoc_get_xml(
843 IXMLDOMDocument2
*iface
,
846 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
847 return IXMLDOMNode_get_xml( This
->node
, xmlString
);
851 static HRESULT WINAPI
domdoc_transformNode(
852 IXMLDOMDocument2
*iface
,
853 IXMLDOMNode
* styleSheet
,
856 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
857 return IXMLDOMNode_transformNode( This
->node
, styleSheet
, xmlString
);
861 static HRESULT WINAPI
domdoc_selectNodes(
862 IXMLDOMDocument2
*iface
,
864 IXMLDOMNodeList
** resultList
)
866 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
867 return IXMLDOMNode_selectNodes( This
->node
, queryString
, resultList
);
871 static HRESULT WINAPI
domdoc_selectSingleNode(
872 IXMLDOMDocument2
*iface
,
874 IXMLDOMNode
** resultNode
)
876 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
877 return IXMLDOMNode_selectSingleNode( This
->node
, queryString
, resultNode
);
881 static HRESULT WINAPI
domdoc_get_parsed(
882 IXMLDOMDocument2
*iface
,
883 VARIANT_BOOL
* isParsed
)
885 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
886 return IXMLDOMNode_get_parsed( This
->node
, isParsed
);
890 static HRESULT WINAPI
domdoc_get_namespaceURI(
891 IXMLDOMDocument2
*iface
,
894 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
895 return IXMLDOMNode_get_namespaceURI( This
->node
, namespaceURI
);
899 static HRESULT WINAPI
domdoc_get_prefix(
900 IXMLDOMDocument2
*iface
,
903 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
904 return IXMLDOMNode_get_prefix( This
->node
, prefixString
);
908 static HRESULT WINAPI
domdoc_get_baseName(
909 IXMLDOMDocument2
*iface
,
912 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
913 return IXMLDOMNode_get_baseName( This
->node
, nameString
);
917 static HRESULT WINAPI
domdoc_transformNodeToObject(
918 IXMLDOMDocument2
*iface
,
919 IXMLDOMNode
* stylesheet
,
920 VARIANT outputObject
)
922 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
923 return IXMLDOMNode_transformNodeToObject( This
->node
, stylesheet
, outputObject
);
927 static HRESULT WINAPI
domdoc_get_doctype(
928 IXMLDOMDocument2
*iface
,
929 IXMLDOMDocumentType
** documentType
)
936 static HRESULT WINAPI
domdoc_get_implementation(
937 IXMLDOMDocument2
*iface
,
938 IXMLDOMImplementation
** impl
)
943 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
948 static HRESULT WINAPI
domdoc_get_documentElement(
949 IXMLDOMDocument2
*iface
,
950 IXMLDOMElement
** DOMElement
)
952 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
953 xmlDocPtr xmldoc
= NULL
;
954 xmlNodePtr root
= NULL
;
955 IXMLDOMNode
*element_node
;
958 TRACE("%p %p\n", This
, This
->node
);
965 xmldoc
= get_doc( This
);
967 root
= xmlDocGetRootElement( xmldoc
);
971 element_node
= create_node( root
);
972 if(!element_node
) return S_FALSE
;
974 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (LPVOID
*)DOMElement
);
975 IXMLDOMNode_Release(element_node
);
981 static HRESULT WINAPI
domdoc_put_documentElement(
982 IXMLDOMDocument2
*iface
,
983 IXMLDOMElement
* DOMElement
)
985 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
986 IXMLDOMNode
*elementNode
;
991 TRACE("(%p)->(%p)\n", This
, DOMElement
);
993 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
997 xmlNode
= impl_from_IXMLDOMNode( elementNode
);
999 if(!xmlNode
->node
->parent
)
1000 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1001 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1003 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1004 IXMLDOMNode_Release( elementNode
);
1007 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1013 static HRESULT WINAPI
domdoc_createElement(
1014 IXMLDOMDocument2
*iface
,
1016 IXMLDOMElement
** element
)
1019 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1024 TRACE("%p->(%s,%p)\n", iface
, debugstr_w(tagname
), element
);
1026 xml_name
= xmlChar_from_wchar((WCHAR
*)tagname
);
1027 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, xml_name
, NULL
);
1028 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1030 TRACE("created xmlptr %p\n", xmlnode
);
1031 elem_unk
= create_element(xmlnode
, NULL
);
1032 HeapFree(GetProcessHeap(), 0, xml_name
);
1034 hr
= IUnknown_QueryInterface(elem_unk
, &IID_IXMLDOMElement
, (void **)element
);
1035 IUnknown_Release(elem_unk
);
1036 TRACE("returning %p\n", *element
);
1041 static HRESULT WINAPI
domdoc_createDocumentFragment(
1042 IXMLDOMDocument2
*iface
,
1043 IXMLDOMDocumentFragment
** docFrag
)
1045 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1048 TRACE("%p\n", iface
);
1051 return E_INVALIDARG
;
1055 xmlnode
= xmlNewDocFragment(get_doc( This
) );
1060 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1061 *docFrag
= (IXMLDOMDocumentFragment
*)create_doc_fragment(xmlnode
);
1067 static HRESULT WINAPI
domdoc_createTextNode(
1068 IXMLDOMDocument2
*iface
,
1070 IXMLDOMText
** text
)
1072 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1074 xmlChar
*xml_content
;
1076 TRACE("%p->(%s %p)\n", iface
, debugstr_w(data
), text
);
1079 return E_INVALIDARG
;
1083 xml_content
= xmlChar_from_wchar((WCHAR
*)data
);
1084 xmlnode
= xmlNewText(xml_content
);
1085 HeapFree(GetProcessHeap(), 0, xml_content
);
1090 xmlnode
->doc
= get_doc( This
);
1091 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1093 *text
= (IXMLDOMText
*)create_text(xmlnode
);
1099 static HRESULT WINAPI
domdoc_createComment(
1100 IXMLDOMDocument2
*iface
,
1102 IXMLDOMComment
** comment
)
1104 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1106 xmlChar
*xml_content
;
1108 TRACE("%p->(%s %p)\n", iface
, debugstr_w(data
), comment
);
1111 return E_INVALIDARG
;
1115 xml_content
= xmlChar_from_wchar((WCHAR
*)data
);
1116 xmlnode
= xmlNewComment(xml_content
);
1117 HeapFree(GetProcessHeap(), 0, xml_content
);
1122 xmlnode
->doc
= get_doc( This
);
1123 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1125 *comment
= (IXMLDOMComment
*)create_comment(xmlnode
);
1131 static HRESULT WINAPI
domdoc_createCDATASection(
1132 IXMLDOMDocument2
*iface
,
1134 IXMLDOMCDATASection
** cdata
)
1136 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1138 xmlChar
*xml_content
;
1140 TRACE("%p->(%s %p)\n", iface
, debugstr_w(data
), cdata
);
1143 return E_INVALIDARG
;
1147 xml_content
= xmlChar_from_wchar((WCHAR
*)data
);
1148 xmlnode
= xmlNewCDataBlock(get_doc( This
), xml_content
, strlen( (char*)xml_content
) );
1149 HeapFree(GetProcessHeap(), 0, xml_content
);
1154 xmlnode
->doc
= get_doc( This
);
1155 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1157 *cdata
= (IXMLDOMCDATASection
*)create_cdata(xmlnode
);
1163 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1164 IXMLDOMDocument2
*iface
,
1167 IXMLDOMProcessingInstruction
** pi
)
1169 #ifdef HAVE_XMLNEWDOCPI
1171 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1172 xmlChar
*xml_target
, *xml_content
;
1174 TRACE("%p->(%s %s %p)\n", iface
, debugstr_w(target
), debugstr_w(data
), pi
);
1177 return E_INVALIDARG
;
1179 if(!target
|| lstrlenW(target
) == 0)
1182 xml_target
= xmlChar_from_wchar((WCHAR
*)target
);
1183 xml_content
= xmlChar_from_wchar((WCHAR
*)data
);
1185 xmlnode
= xmlNewDocPI(get_doc(This
), xml_target
, xml_content
);
1186 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1187 TRACE("created xmlptr %p\n", xmlnode
);
1188 *pi
= (IXMLDOMProcessingInstruction
*)create_pi(xmlnode
);
1190 HeapFree(GetProcessHeap(), 0, xml_content
);
1191 HeapFree(GetProcessHeap(), 0, xml_target
);
1195 FIXME("Libxml 2.6.15 or greater required.\n");
1201 static HRESULT WINAPI
domdoc_createAttribute(
1202 IXMLDOMDocument2
*iface
,
1204 IXMLDOMAttribute
** attribute
)
1206 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1210 TRACE("%p->(%s %p)\n", iface
, debugstr_w(name
), attribute
);
1213 return E_INVALIDARG
;
1217 xml_name
= xmlChar_from_wchar((WCHAR
*)name
);
1218 xmlnode
= (xmlNode
*)xmlNewProp(NULL
, xml_name
, NULL
);
1219 HeapFree(GetProcessHeap(), 0, xml_name
);
1224 xmlnode
->doc
= get_doc( This
);
1225 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1227 *attribute
= (IXMLDOMAttribute
*)create_attribute(xmlnode
);
1233 static HRESULT WINAPI
domdoc_createEntityReference(
1234 IXMLDOMDocument2
*iface
,
1236 IXMLDOMEntityReference
** entityRef
)
1238 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1242 TRACE("%p\n", iface
);
1245 return E_INVALIDARG
;
1249 xml_name
= xmlChar_from_wchar((WCHAR
*)name
);
1250 xmlnode
= xmlNewReference(get_doc( This
), xml_name
);
1251 HeapFree(GetProcessHeap(), 0, xml_name
);
1256 xmlnode
->doc
= get_doc( This
);
1257 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1259 *entityRef
= (IXMLDOMEntityReference
*)create_doc_entity_ref(xmlnode
);
1265 static HRESULT WINAPI
domdoc_getElementsByTagName(
1266 IXMLDOMDocument2
*iface
,
1268 IXMLDOMNodeList
** resultList
)
1270 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1273 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(tagName
), resultList
);
1275 szPattern
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(2+lstrlenW(tagName
)+1));
1276 szPattern
[0] = szPattern
[1] = '/';
1277 lstrcpyW(szPattern
+ 2, tagName
);
1279 hr
= queryresult_create((xmlNodePtr
)get_doc(This
), szPattern
, resultList
);
1280 HeapFree(GetProcessHeap(), 0, szPattern
);
1285 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1291 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1293 return E_INVALIDARG
;
1300 static HRESULT WINAPI
domdoc_createNode(
1301 IXMLDOMDocument2
*iface
,
1305 IXMLDOMNode
** node
)
1307 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1308 DOMNodeType node_type
;
1309 xmlNodePtr xmlnode
= NULL
;
1313 TRACE("(%p)->(type,%s,%s,%p)\n", This
, debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1315 hr
= get_node_type(Type
, &node_type
);
1319 TRACE("node_type %d\n", node_type
);
1321 xml_name
= xmlChar_from_wchar((WCHAR
*)name
);
1326 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, xml_name
, NULL
);
1327 *node
= create_node(xmlnode
);
1328 TRACE("created %p\n", xmlnode
);
1330 case NODE_ATTRIBUTE
:
1331 xmlnode
= (xmlNode
*)xmlNewProp(NULL
, xml_name
, NULL
);
1334 xmlnode
->doc
= get_doc( This
);
1336 *node
= (IXMLDOMNode
*)create_attribute(xmlnode
);
1339 TRACE("created %p\n", xmlnode
);
1343 FIXME("unhandled node type %d\n", node_type
);
1347 HeapFree(GetProcessHeap(), 0, xml_name
);
1349 if(xmlnode
&& *node
)
1351 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1358 static HRESULT WINAPI
domdoc_nodeFromID(
1359 IXMLDOMDocument2
*iface
,
1361 IXMLDOMNode
** node
)
1367 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
1372 xmldoc
= doparse( ptr
, len
);
1374 xmldoc
->_private
= create_priv();
1375 return attach_xmldoc(This
->node
, xmldoc
);
1381 static HRESULT
doread( domdoc
*This
, LPWSTR filename
)
1386 hr
= bind_url(filename
, domdoc_onDataAvailable
, This
, &bsc
);
1391 detach_bsc(This
->bsc
);
1397 static HRESULT WINAPI
domdoc_load(
1398 IXMLDOMDocument2
*iface
,
1400 VARIANT_BOOL
* isSuccessful
)
1402 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1403 LPWSTR filename
= NULL
;
1404 HRESULT hr
= S_FALSE
;
1405 IXMLDOMDocument2
*pNewDoc
= NULL
;
1406 IStream
*pStream
= NULL
;
1409 TRACE("type %d\n", V_VT(&xmlSource
) );
1411 *isSuccessful
= VARIANT_FALSE
;
1413 assert( This
->node
);
1415 switch( V_VT(&xmlSource
) )
1418 filename
= V_BSTR(&xmlSource
);
1421 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IXMLDOMDocument2
, (void**)&pNewDoc
);
1426 domdoc
*newDoc
= impl_from_IXMLDOMDocument2( pNewDoc
);
1427 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
1428 hr
= attach_xmldoc(This
->node
, xmldoc
);
1431 *isSuccessful
= VARIANT_TRUE
;
1436 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IStream
, (void**)&pStream
);
1439 IPersistStream
*pDocStream
;
1440 hr
= IUnknown_QueryInterface(iface
, &IID_IPersistStream
, (void**)&pDocStream
);
1443 hr
= xmldoc_IPersistStream_Load(pDocStream
, pStream
);
1444 IStream_Release(pStream
);
1447 *isSuccessful
= VARIANT_TRUE
;
1449 TRACE("Using ID_IStream to load Document\n");
1454 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr
);
1459 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr
);
1464 /* ISequentialStream */
1465 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr
, pNewDoc
, V_UNKNOWN(&xmlSource
)->lpVtbl
);
1469 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource
));
1472 TRACE("filename (%s)\n", debugstr_w(filename
));
1476 hr
= doread( This
, filename
);
1479 This
->error
= E_FAIL
;
1482 hr
= This
->error
= S_OK
;
1483 *isSuccessful
= VARIANT_TRUE
;
1487 if(!filename
|| FAILED(hr
)) {
1488 xmldoc
= xmlNewDoc(NULL
);
1489 xmldoc
->_private
= create_priv();
1490 hr
= attach_xmldoc(This
->node
, xmldoc
);
1495 TRACE("ret (%d)\n", hr
);
1501 static HRESULT WINAPI
domdoc_get_readyState(
1502 IXMLDOMDocument2
*iface
,
1510 static HRESULT WINAPI
domdoc_get_parseError(
1511 IXMLDOMDocument2
*iface
,
1512 IXMLDOMParseError
** errorObj
)
1514 BSTR error_string
= NULL
;
1515 static const WCHAR err
[] = {'e','r','r','o','r',0};
1516 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1518 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
1521 error_string
= SysAllocString(err
);
1523 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
1524 if(!*errorObj
) return E_OUTOFMEMORY
;
1529 static HRESULT WINAPI
domdoc_get_url(
1530 IXMLDOMDocument2
*iface
,
1538 static HRESULT WINAPI
domdoc_get_async(
1539 IXMLDOMDocument2
*iface
,
1540 VARIANT_BOOL
* isAsync
)
1542 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1544 TRACE("%p <- %d\n", isAsync
, This
->async
);
1545 *isAsync
= This
->async
;
1550 static HRESULT WINAPI
domdoc_put_async(
1551 IXMLDOMDocument2
*iface
,
1552 VARIANT_BOOL isAsync
)
1554 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1556 TRACE("%d\n", isAsync
);
1557 This
->async
= isAsync
;
1562 static HRESULT WINAPI
domdoc_abort(
1563 IXMLDOMDocument2
*iface
)
1570 static BOOL
bstr_to_utf8( BSTR bstr
, char **pstr
, int *plen
)
1572 UINT len
, blen
= SysStringLen( bstr
);
1575 len
= WideCharToMultiByte( CP_UTF8
, 0, bstr
, blen
, NULL
, 0, NULL
, NULL
);
1576 str
= HeapAlloc( GetProcessHeap(), 0, len
);
1579 WideCharToMultiByte( CP_UTF8
, 0, bstr
, blen
, str
, len
, NULL
, NULL
);
1585 static HRESULT WINAPI
domdoc_loadXML(
1586 IXMLDOMDocument2
*iface
,
1588 VARIANT_BOOL
* isSuccessful
)
1590 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1591 xmlDocPtr xmldoc
= NULL
;
1594 HRESULT hr
= S_FALSE
, hr2
;
1596 TRACE("%p %s %p\n", This
, debugstr_w( bstrXML
), isSuccessful
);
1598 assert ( This
->node
);
1602 *isSuccessful
= VARIANT_FALSE
;
1604 if ( bstrXML
&& bstr_to_utf8( bstrXML
, &str
, &len
) )
1606 xmldoc
= doparse( str
, len
);
1607 HeapFree( GetProcessHeap(), 0, str
);
1609 This
->error
= E_FAIL
;
1612 hr
= This
->error
= S_OK
;
1613 *isSuccessful
= VARIANT_TRUE
;
1618 xmldoc
= xmlNewDoc(NULL
);
1620 xmldoc
->_private
= create_priv();
1621 hr2
= attach_xmldoc( This
->node
, xmldoc
);
1629 static HRESULT WINAPI
domdoc_save(
1630 IXMLDOMDocument2
*iface
,
1631 VARIANT destination
)
1633 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1640 TRACE("(%p)->(var(vt %d, %s))\n", This
, V_VT(&destination
),
1641 V_VT(&destination
) == VT_BSTR
? debugstr_w(V_BSTR(&destination
)) : NULL
);
1643 if(V_VT(&destination
) != VT_BSTR
&& V_VT(&destination
) != VT_UNKNOWN
)
1645 FIXME("Unhandled vt %d\n", V_VT(&destination
));
1649 if(V_VT(&destination
) == VT_UNKNOWN
)
1651 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
1652 IXMLDOMDocument
*pDocument
;
1654 ret
= IXMLDOMDocument_QueryInterface(pUnk
, &IID_IXMLDOMDocument2
, (void**)&pDocument
);
1658 VARIANT_BOOL bSuccessful
;
1660 ret
= IXMLDOMDocument_get_xml(iface
, &bXML
);
1663 ret
= IXMLDOMDocument_loadXML(pDocument
, bXML
, &bSuccessful
);
1665 SysFreeString(bXML
);
1668 IXMLDOMDocument_Release(pDocument
);
1671 TRACE("ret %d\n", ret
);
1676 handle
= CreateFileW( V_BSTR(&destination
), GENERIC_WRITE
, 0,
1677 NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1678 if( handle
== INVALID_HANDLE_VALUE
)
1680 WARN("failed to create file\n");
1684 xmlDocDumpMemory(get_doc(This
), &mem
, &size
);
1687 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1688 * MSXML adds XML declaration only for processing instruction nodes.
1689 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1692 if(size
> 2 && p
[0] == '<' && p
[1] == '?') {
1693 while(p
< mem
+size
&& (p
[0] != '?' || p
[1] != '>'))
1696 while(p
< mem
+size
&& isspace(*p
))
1701 if(!WriteFile(handle
, p
, (DWORD
)size
, &written
, NULL
) || written
!= (DWORD
)size
)
1703 WARN("write error\n");
1708 CloseHandle(handle
);
1712 static HRESULT WINAPI
domdoc_get_validateOnParse(
1713 IXMLDOMDocument2
*iface
,
1714 VARIANT_BOOL
* isValidating
)
1716 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1718 TRACE("%p <- %d\n", isValidating
, This
->validating
);
1719 *isValidating
= This
->validating
;
1724 static HRESULT WINAPI
domdoc_put_validateOnParse(
1725 IXMLDOMDocument2
*iface
,
1726 VARIANT_BOOL isValidating
)
1728 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1730 TRACE("%d\n", isValidating
);
1731 This
->validating
= isValidating
;
1736 static HRESULT WINAPI
domdoc_get_resolveExternals(
1737 IXMLDOMDocument2
*iface
,
1738 VARIANT_BOOL
* isResolving
)
1740 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1742 TRACE("%p <- %d\n", isResolving
, This
->resolving
);
1743 *isResolving
= This
->resolving
;
1748 static HRESULT WINAPI
domdoc_put_resolveExternals(
1749 IXMLDOMDocument2
*iface
,
1750 VARIANT_BOOL isResolving
)
1752 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1754 TRACE("%d\n", isResolving
);
1755 This
->resolving
= isResolving
;
1760 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
1761 IXMLDOMDocument2
*iface
,
1762 VARIANT_BOOL
* isPreserving
)
1764 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1766 TRACE("%p <- %d\n", isPreserving
, This
->preserving
);
1767 *isPreserving
= This
->preserving
;
1772 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
1773 IXMLDOMDocument2
*iface
,
1774 VARIANT_BOOL isPreserving
)
1776 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1778 TRACE("%d\n", isPreserving
);
1779 This
->preserving
= isPreserving
;
1784 static HRESULT WINAPI
domdoc_put_onReadyStateChange(
1785 IXMLDOMDocument2
*iface
,
1786 VARIANT readyStateChangeSink
)
1793 static HRESULT WINAPI
domdoc_put_onDataAvailable(
1794 IXMLDOMDocument2
*iface
,
1795 VARIANT onDataAvailableSink
)
1801 static HRESULT WINAPI
domdoc_put_onTransformNode(
1802 IXMLDOMDocument2
*iface
,
1803 VARIANT onTransformNodeSink
)
1809 static HRESULT WINAPI
domdoc_get_namespaces(
1810 IXMLDOMDocument2
* iface
,
1811 IXMLDOMSchemaCollection
** schemaCollection
)
1817 static HRESULT WINAPI
domdoc_get_schemas(
1818 IXMLDOMDocument2
* iface
,
1821 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1822 HRESULT hr
= S_FALSE
;
1823 IXMLDOMSchemaCollection
*cur_schema
= This
->schema
;
1825 TRACE("(%p)->(%p)\n", This
, var1
);
1827 VariantInit(var1
); /* Test shows we don't call VariantClear here */
1828 V_VT(var1
) = VT_NULL
;
1832 hr
= IXMLDOMSchemaCollection_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(var1
));
1834 V_VT(var1
) = VT_DISPATCH
;
1839 static HRESULT WINAPI
domdoc_putref_schemas(
1840 IXMLDOMDocument2
* iface
,
1843 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1844 HRESULT hr
= E_FAIL
;
1845 IXMLDOMSchemaCollection
*new_schema
= NULL
;
1847 FIXME("(%p): semi-stub\n", This
);
1851 hr
= IUnknown_QueryInterface(V_UNKNOWN(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
1855 hr
= IDispatch_QueryInterface(V_DISPATCH(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
1864 WARN("Can't get schema from vt %x\n", V_VT(&var1
));
1869 IXMLDOMSchemaCollection
*old_schema
= InterlockedExchangePointer((void**)&This
->schema
, new_schema
);
1870 if(old_schema
) IXMLDOMSchemaCollection_Release(old_schema
);
1876 static HRESULT WINAPI
domdoc_validate(
1877 IXMLDOMDocument2
* iface
,
1878 IXMLDOMParseError
** err
)
1884 static HRESULT WINAPI
domdoc_setProperty(
1885 IXMLDOMDocument2
* iface
,
1889 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1891 if (lstrcmpiW(p
, SZ_PROPERTY_SELECTION_LANGUAGE
) == 0)
1897 V_VT(&varStr
) = VT_EMPTY
;
1898 if (V_VT(&var
) != VT_BSTR
)
1900 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
1902 bstr
= V_BSTR(&varStr
);
1905 bstr
= V_BSTR(&var
);
1908 if (lstrcmpiW(bstr
, SZ_VALUE_XPATH
) == 0)
1909 This
->bUseXPath
= TRUE
;
1910 else if (lstrcmpiW(bstr
, SZ_VALUE_XSLPATTERN
) == 0)
1911 This
->bUseXPath
= FALSE
;
1915 VariantClear(&varStr
);
1919 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
1923 static HRESULT WINAPI
domdoc_getProperty(
1924 IXMLDOMDocument2
* iface
,
1928 domdoc
*This
= impl_from_IXMLDOMDocument2( iface
);
1931 return E_INVALIDARG
;
1932 if (lstrcmpiW(p
, SZ_PROPERTY_SELECTION_LANGUAGE
) == 0)
1934 V_VT(var
) = VT_BSTR
;
1935 if (This
->bUseXPath
)
1936 V_BSTR(var
) = SysAllocString(SZ_VALUE_XPATH
);
1938 V_BSTR(var
) = SysAllocString(SZ_VALUE_XSLPATTERN
);
1942 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
1946 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl
=
1948 domdoc_QueryInterface
,
1951 domdoc_GetTypeInfoCount
,
1953 domdoc_GetIDsOfNames
,
1955 domdoc_get_nodeName
,
1956 domdoc_get_nodeValue
,
1957 domdoc_put_nodeValue
,
1958 domdoc_get_nodeType
,
1959 domdoc_get_parentNode
,
1960 domdoc_get_childNodes
,
1961 domdoc_get_firstChild
,
1962 domdoc_get_lastChild
,
1963 domdoc_get_previousSibling
,
1964 domdoc_get_nextSibling
,
1965 domdoc_get_attributes
,
1966 domdoc_insertBefore
,
1967 domdoc_replaceChild
,
1970 domdoc_hasChildNodes
,
1971 domdoc_get_ownerDocument
,
1973 domdoc_get_nodeTypeString
,
1976 domdoc_get_specified
,
1977 domdoc_get_definition
,
1978 domdoc_get_nodeTypedValue
,
1979 domdoc_put_nodeTypedValue
,
1980 domdoc_get_dataType
,
1981 domdoc_put_dataType
,
1983 domdoc_transformNode
,
1985 domdoc_selectSingleNode
,
1987 domdoc_get_namespaceURI
,
1989 domdoc_get_baseName
,
1990 domdoc_transformNodeToObject
,
1992 domdoc_get_implementation
,
1993 domdoc_get_documentElement
,
1994 domdoc_put_documentElement
,
1995 domdoc_createElement
,
1996 domdoc_createDocumentFragment
,
1997 domdoc_createTextNode
,
1998 domdoc_createComment
,
1999 domdoc_createCDATASection
,
2000 domdoc_createProcessingInstruction
,
2001 domdoc_createAttribute
,
2002 domdoc_createEntityReference
,
2003 domdoc_getElementsByTagName
,
2007 domdoc_get_readyState
,
2008 domdoc_get_parseError
,
2015 domdoc_get_validateOnParse
,
2016 domdoc_put_validateOnParse
,
2017 domdoc_get_resolveExternals
,
2018 domdoc_put_resolveExternals
,
2019 domdoc_get_preserveWhiteSpace
,
2020 domdoc_put_preserveWhiteSpace
,
2021 domdoc_put_onReadyStateChange
,
2022 domdoc_put_onDataAvailable
,
2023 domdoc_put_onTransformNode
,
2024 domdoc_get_namespaces
,
2026 domdoc_putref_schemas
,
2032 /* xmldoc implementation of IObjectWithSite */
2033 static HRESULT WINAPI
2034 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
2036 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2037 return IXMLDocument_QueryInterface( (IXMLDocument
*)This
, riid
, ppvObject
);
2041 xmldoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
2043 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2044 return IXMLDocument_AddRef((IXMLDocument
*)This
);
2048 xmldoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
2050 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2051 return IXMLDocument_Release((IXMLDocument
*)This
);
2054 static HRESULT WINAPI
2055 xmldoc_GetSite( IObjectWithSite
*iface
, REFIID iid
, void ** ppvSite
)
2057 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2059 TRACE("%p %s %p\n", This
, debugstr_guid( iid
), ppvSite
);
2064 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
2067 static HRESULT WINAPI
2068 xmldoc_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
2070 domdoc
*This
= impl_from_IObjectWithSite(iface
);
2072 TRACE("%p %p\n", iface
, punk
);
2078 IUnknown_Release( This
->site
);
2086 IUnknown_AddRef( punk
);
2089 IUnknown_Release( This
->site
);
2096 static const IObjectWithSiteVtbl domdocObjectSite
=
2098 xmldoc_ObjectWithSite_QueryInterface
,
2099 xmldoc_ObjectWithSite_AddRef
,
2100 xmldoc_ObjectWithSite_Release
,
2105 static HRESULT WINAPI
xmldoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
2107 domdoc
*This
= impl_from_IObjectSafety(iface
);
2108 return IXMLDocument_QueryInterface( (IXMLDocument
*)This
, riid
, ppv
);
2111 static ULONG WINAPI
xmldoc_Safety_AddRef(IObjectSafety
*iface
)
2113 domdoc
*This
= impl_from_IObjectSafety(iface
);
2114 return IXMLDocument_AddRef((IXMLDocument
*)This
);
2117 static ULONG WINAPI
xmldoc_Safety_Release(IObjectSafety
*iface
)
2119 domdoc
*This
= impl_from_IObjectSafety(iface
);
2120 return IXMLDocument_Release((IXMLDocument
*)This
);
2123 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2125 static HRESULT WINAPI
xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
2126 DWORD
*pdwSupportedOptions
, DWORD
*pdwEnabledOptions
)
2128 domdoc
*This
= impl_from_IObjectSafety(iface
);
2130 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), pdwSupportedOptions
, pdwEnabledOptions
);
2132 if(!pdwSupportedOptions
|| !pdwEnabledOptions
)
2135 *pdwSupportedOptions
= SUPPORTED_OPTIONS
;
2136 *pdwEnabledOptions
= This
->safeopt
;
2141 static HRESULT WINAPI
xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
2142 DWORD dwOptionSetMask
, DWORD dwEnabledOptions
)
2144 domdoc
*This
= impl_from_IObjectSafety(iface
);
2146 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), dwOptionSetMask
, dwEnabledOptions
);
2148 if(dwOptionSetMask
& ~SUPPORTED_OPTIONS
)
2151 This
->safeopt
= dwEnabledOptions
& dwEnabledOptions
;
2155 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
2156 xmldoc_Safety_QueryInterface
,
2157 xmldoc_Safety_AddRef
,
2158 xmldoc_Safety_Release
,
2159 xmldoc_Safety_GetInterfaceSafetyOptions
,
2160 xmldoc_Safety_SetInterfaceSafetyOptions
2164 static const tid_t domdoc_iface_tids
[] = {
2166 IXMLDOMDocument_tid
,
2167 IXMLDOMDocument2_tid
,
2170 static dispex_static_data_t domdoc_dispex
= {
2172 IXMLDOMDocument2_tid
,
2177 HRESULT
DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument2
**document
)
2182 doc
= HeapAlloc( GetProcessHeap(), 0, sizeof (*doc
) );
2184 return E_OUTOFMEMORY
;
2186 doc
->lpVtbl
= &domdoc_vtbl
;
2187 doc
->lpvtblIPersistStream
= &xmldoc_IPersistStream_VTable
;
2188 doc
->lpvtblIObjectWithSite
= &domdocObjectSite
;
2189 doc
->lpvtblIObjectSafety
= &domdocObjectSafetyVtbl
;
2190 doc
->lpvtblISupportErrorInfo
= &support_error_vtbl
;
2193 doc
->validating
= 0;
2195 doc
->preserving
= 0;
2196 doc
->bUseXPath
= FALSE
;
2204 doc
->node_unk
= create_basic_node( (xmlNodePtr
)xmldoc
, (IUnknown
*)&doc
->lpVtbl
);
2207 HeapFree(GetProcessHeap(), 0, doc
);
2211 hr
= IUnknown_QueryInterface(doc
->node_unk
, &IID_IXMLDOMNode
, (LPVOID
*)&doc
->node
);
2214 IUnknown_Release(doc
->node_unk
);
2215 HeapFree( GetProcessHeap(), 0, doc
);
2219 init_dispex(&doc
->dispex
, (IUnknown
*)&doc
->lpVtbl
, &domdoc_dispex
);
2221 /* The ref on doc->node is actually looped back into this object, so release it */
2222 IXMLDOMNode_Release(doc
->node
);
2224 *document
= (IXMLDOMDocument2
*)&doc
->lpVtbl
;
2226 TRACE("returning iface %p\n", *document
);
2230 HRESULT
DOMDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
2235 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
2237 xmldoc
= xmlNewDoc(NULL
);
2239 return E_OUTOFMEMORY
;
2241 xmldoc
->_private
= create_priv();
2243 hr
= DOMDocument_create_from_xmldoc(xmldoc
, (IXMLDOMDocument2
**)ppObj
);
2250 IUnknown
* create_domdoc( xmlNodePtr document
)
2255 TRACE("(%p)\n", document
);
2257 hr
= DOMDocument_create_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument2
**)&pObj
);
2261 return (IUnknown
*)pObj
;
2266 HRESULT
DOMDocument_create(IUnknown
*pUnkOuter
, LPVOID
*ppObj
)
2268 MESSAGE("This program tried to use a DOMDocument object, but\n"
2269 "libxml2 support was not present at compile time.\n");