2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
5 * Copyright 2010 Adam Martinson for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define NONAMELESSUNION
43 #include "wine/debug.h"
44 #include "wine/list.h"
46 #include "msxml_private.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
52 #include <libxml/xpathInternals.h>
53 #include <libxml/xmlsave.h>
54 #include <libxml/SAX2.h>
55 #include <libxml/parserInternals.h>
57 /* not defined in older versions */
58 #define XML_SAVE_FORMAT 1
59 #define XML_SAVE_NO_DECL 2
60 #define XML_SAVE_NO_EMPTY 4
61 #define XML_SAVE_NO_XHTML 8
62 #define XML_SAVE_XHTML 16
63 #define XML_SAVE_AS_XML 32
64 #define XML_SAVE_AS_HTML 64
66 static const WCHAR PropertySelectionLanguageW
[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
67 static const WCHAR PropertySelectionNamespacesW
[] = {'S','e','l','e','c','t','i','o','n','N','a','m','e','s','p','a','c','e','s',0};
68 static const WCHAR PropertyProhibitDTDW
[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
69 static const WCHAR PropertyNewParserW
[] = {'N','e','w','P','a','r','s','e','r',0};
70 static const WCHAR PropValueXPathW
[] = {'X','P','a','t','h',0};
71 static const WCHAR PropValueXSLPatternW
[] = {'X','S','L','P','a','t','t','e','r','n',0};
73 /* Data used by domdoc_getProperty()/domdoc_setProperty().
74 * We need to preserve this when reloading a document,
75 * and also need access to it from the libxml backend. */
76 typedef struct _domdoc_properties
{
77 VARIANT_BOOL preserving
;
78 struct list selectNsList
;
79 xmlChar
const* selectNsStr
;
84 typedef struct ConnectionPoint ConnectionPoint
;
85 typedef struct domdoc domdoc
;
87 struct ConnectionPoint
89 const IConnectionPointVtbl
*lpVtblConnectionPoint
;
92 ConnectionPoint
*next
;
93 IConnectionPointContainer
*container
;
100 IPropertyNotifySink
*propnotif
;
108 const struct IXMLDOMDocument3Vtbl
*lpVtbl
;
109 const struct IPersistStreamInitVtbl
*lpvtblIPersistStreamInit
;
110 const struct IObjectWithSiteVtbl
*lpvtblIObjectWithSite
;
111 const struct IObjectSafetyVtbl
*lpvtblIObjectSafety
;
112 const struct ISupportErrorInfoVtbl
*lpvtblISupportErrorInfo
;
113 const struct IConnectionPointContainerVtbl
*lpVtblConnectionPointContainer
;
116 VARIANT_BOOL validating
;
117 VARIANT_BOOL resolving
;
118 domdoc_properties
* properties
;
119 IXMLDOMSchemaCollection2
* schema
;
132 /* connection list */
133 ConnectionPoint
*cp_list
;
134 ConnectionPoint cp_domdocevents
;
135 ConnectionPoint cp_propnotif
;
136 ConnectionPoint cp_dispatch
;
139 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
141 return (ConnectionPoint
*)((char*)iface
- FIELD_OFFSET(ConnectionPoint
, lpVtblConnectionPoint
));
145 In native windows, the whole lifetime management of XMLDOMNodes is
146 managed automatically using reference counts. Wine emulates that by
147 maintaining a reference count to the document that is increased for
148 each IXMLDOMNode pointer passed out for this document. If all these
149 pointers are gone, the document is unreachable and gets freed, that
150 is, all nodes in the tree of the document get freed.
152 You are able to create nodes that are associated to a document (in
153 fact, in msxml's XMLDOM model, all nodes are associated to a document),
154 but not in the tree of that document, for example using the createFoo
155 functions from IXMLDOMDocument. These nodes do not get cleaned up
156 by libxml, so we have to do it ourselves.
158 To catch these nodes, a list of "orphan nodes" is introduced.
159 It contains pointers to all roots of node trees that are
160 associated with the document without being part of the document
161 tree. All nodes with parent==NULL (except for the document root nodes)
162 should be in the orphan node list of their document. All orphan nodes
163 get freed together with the document itself.
166 typedef struct _xmldoc_priv
{
169 domdoc_properties
* properties
;
172 typedef struct _orphan_entry
{
177 typedef struct _select_ns_entry
{
179 xmlChar
const* prefix
;
185 static inline xmldoc_priv
* priv_from_xmlDocPtr(const xmlDocPtr doc
)
187 return doc
->_private
;
190 static inline domdoc_properties
* properties_from_xmlDocPtr(xmlDocPtr doc
)
192 return priv_from_xmlDocPtr(doc
)->properties
;
195 BOOL
is_xpathmode(const xmlDocPtr doc
)
197 return properties_from_xmlDocPtr(doc
)->XPath
;
200 int registerNamespaces(xmlXPathContextPtr ctxt
)
203 const select_ns_entry
* ns
= NULL
;
204 const struct list
* pNsList
= &properties_from_xmlDocPtr(ctxt
->doc
)->selectNsList
;
206 TRACE("(%p)\n", ctxt
);
208 LIST_FOR_EACH_ENTRY( ns
, pNsList
, select_ns_entry
, entry
)
210 xmlXPathRegisterNs(ctxt
, ns
->prefix
, ns
->href
);
217 static inline void clear_selectNsList(struct list
* pNsList
)
219 select_ns_entry
*ns
, *ns2
;
220 LIST_FOR_EACH_ENTRY_SAFE( ns
, ns2
, pNsList
, select_ns_entry
, entry
)
227 static xmldoc_priv
* create_priv(void)
230 priv
= heap_alloc( sizeof (*priv
) );
235 list_init( &priv
->orphans
);
236 priv
->properties
= NULL
;
242 static domdoc_properties
* create_properties(const GUID
*clsid
)
244 domdoc_properties
*properties
= heap_alloc(sizeof(domdoc_properties
));
246 list_init( &properties
->selectNsList
);
247 properties
->preserving
= VARIANT_FALSE
;
248 properties
->selectNsStr
= heap_alloc_zero(sizeof(xmlChar
));
249 properties
->selectNsStr_len
= 0;
250 properties
->XPath
= FALSE
;
252 /* properties that are dependent on object versions */
253 if (IsEqualCLSID( clsid
, &CLSID_DOMDocument40
) ||
254 IsEqualCLSID( clsid
, &CLSID_DOMDocument60
))
256 properties
->XPath
= TRUE
;
262 static domdoc_properties
* copy_properties(domdoc_properties
const* properties
)
264 domdoc_properties
* pcopy
= heap_alloc(sizeof(domdoc_properties
));
265 select_ns_entry
const* ns
= NULL
;
266 select_ns_entry
* new_ns
= NULL
;
267 int len
= (properties
->selectNsStr_len
+1)*sizeof(xmlChar
);
272 pcopy
->preserving
= properties
->preserving
;
273 pcopy
->XPath
= properties
->XPath
;
274 pcopy
->selectNsStr_len
= properties
->selectNsStr_len
;
275 list_init( &pcopy
->selectNsList
);
276 pcopy
->selectNsStr
= heap_alloc(len
);
277 memcpy((xmlChar
*)pcopy
->selectNsStr
, properties
->selectNsStr
, len
);
278 offset
= pcopy
->selectNsStr
- properties
->selectNsStr
;
280 LIST_FOR_EACH_ENTRY( ns
, (&properties
->selectNsList
), select_ns_entry
, entry
)
282 new_ns
= heap_alloc(sizeof(select_ns_entry
));
283 memcpy(new_ns
, ns
, sizeof(select_ns_entry
));
284 new_ns
->href
+= offset
;
285 new_ns
->prefix
+= offset
;
286 list_add_tail(&pcopy
->selectNsList
, &new_ns
->entry
);
294 static void free_properties(domdoc_properties
* properties
)
298 clear_selectNsList(&properties
->selectNsList
);
299 heap_free((xmlChar
*)properties
->selectNsStr
);
300 heap_free(properties
);
304 static BOOL
xmldoc_has_decl(xmlDocPtr doc
)
306 return doc
->children
&& (xmlStrEqual(doc
->children
->name
, (xmlChar
*)"xml") == 1);
309 /* links a "<?xml" node as a first child */
310 void xmldoc_link_xmldecl(xmlDocPtr doc
, xmlNodePtr node
)
313 if (doc
->standalone
!= -1) xmlAddPrevSibling( doc
->children
, node
);
316 /* unlinks a first "<?xml" child if it was created */
317 xmlNodePtr
xmldoc_unlink_xmldecl(xmlDocPtr doc
)
323 if (doc
->standalone
!= -1)
325 node
= doc
->children
;
326 xmlUnlinkNode( node
);
334 BOOL
is_preserving_whitespace(xmlNodePtr node
)
336 domdoc_properties
* properties
= NULL
;
337 /* during parsing the xmlDoc._private stuff is not there */
338 if (priv_from_xmlDocPtr(node
->doc
))
339 properties
= properties_from_xmlDocPtr(node
->doc
);
340 return ((properties
&& properties
->preserving
== VARIANT_TRUE
) ||
341 xmlNodeGetSpacePreserve(node
) == 1);
344 static inline BOOL
strn_isspace(xmlChar
const* str
, int len
)
346 for (; str
&& len
> 0 && *str
; ++str
, --len
)
353 static void sax_characters(void *ctx
, const xmlChar
*ch
, int len
)
355 xmlParserCtxtPtr pctx
;
358 pctx
= (xmlParserCtxtPtr
) ctx
;
359 This
= (domdoc
const*) pctx
->_private
;
361 /* during domdoc_loadXML() the xmlDocPtr->_private data is not available */
362 if (!This
->properties
->preserving
&&
363 !is_preserving_whitespace(pctx
->node
) &&
364 strn_isspace(ch
, len
))
367 xmlSAX2Characters(ctx
, ch
, len
);
370 static void LIBXML2_LOG_CALLBACK
sax_error(void* ctx
, char const* msg
, ...)
374 LIBXML2_CALLBACK_ERR(doparse
, msg
, ap
);
378 static void LIBXML2_LOG_CALLBACK
sax_warning(void* ctx
, char const* msg
, ...)
382 LIBXML2_CALLBACK_WARN(doparse
, msg
, ap
);
386 static void sax_serror(void* ctx
, xmlErrorPtr err
)
388 LIBXML2_CALLBACK_SERROR(doparse
, err
);
391 static xmlDocPtr
doparse(domdoc
* This
, char *ptr
, int len
, xmlChar
const* encoding
)
393 xmlDocPtr doc
= NULL
;
394 xmlParserCtxtPtr pctx
;
395 static xmlSAXHandler sax_handler
= {
396 xmlSAX2InternalSubset
, /* internalSubset */
397 xmlSAX2IsStandalone
, /* isStandalone */
398 xmlSAX2HasInternalSubset
, /* hasInternalSubset */
399 xmlSAX2HasExternalSubset
, /* hasExternalSubset */
400 xmlSAX2ResolveEntity
, /* resolveEntity */
401 xmlSAX2GetEntity
, /* getEntity */
402 xmlSAX2EntityDecl
, /* entityDecl */
403 xmlSAX2NotationDecl
, /* notationDecl */
404 xmlSAX2AttributeDecl
, /* attributeDecl */
405 xmlSAX2ElementDecl
, /* elementDecl */
406 xmlSAX2UnparsedEntityDecl
, /* unparsedEntityDecl */
407 xmlSAX2SetDocumentLocator
, /* setDocumentLocator */
408 xmlSAX2StartDocument
, /* startDocument */
409 xmlSAX2EndDocument
, /* endDocument */
410 xmlSAX2StartElement
, /* startElement */
411 xmlSAX2EndElement
, /* endElement */
412 xmlSAX2Reference
, /* reference */
413 sax_characters
, /* characters */
414 sax_characters
, /* ignorableWhitespace */
415 xmlSAX2ProcessingInstruction
, /* processingInstruction */
416 xmlSAX2Comment
, /* comment */
417 sax_warning
, /* warning */
418 sax_error
, /* error */
419 sax_error
, /* fatalError */
420 xmlSAX2GetParameterEntity
, /* getParameterEntity */
421 xmlSAX2CDataBlock
, /* cdataBlock */
422 xmlSAX2ExternalSubset
, /* externalSubset */
425 xmlSAX2StartElementNs
, /* startElementNs */
426 xmlSAX2EndElementNs
, /* endElementNs */
427 sax_serror
/* serror */
431 pctx
= xmlCreateMemoryParserCtxt(ptr
, len
);
434 ERR("Failed to create parser context\n");
438 if (pctx
->sax
) xmlFree(pctx
->sax
);
439 pctx
->sax
= &sax_handler
;
440 pctx
->_private
= This
;
442 pctx
->encoding
= xmlStrdup(encoding
);
443 xmlParseDocument(pctx
);
445 if (pctx
->wellFormed
)
451 xmlFreeDoc(pctx
->myDoc
);
455 xmlFreeParserCtxt(pctx
);
457 /* TODO: put this in one of the SAX callbacks */
458 /* create first child as a <?xml...?> */
459 if (doc
&& doc
->standalone
!= -1)
463 xmlChar
*xmlbuff
= (xmlChar
*)buff
;
465 node
= xmlNewDocPI( doc
, (xmlChar
*)"xml", NULL
);
467 /* version attribute can't be omitted */
468 sprintf(buff
, "version=\"%s\"", doc
->version
? (char*)doc
->version
: "1.0");
469 xmlNodeAddContent( node
, xmlbuff
);
473 sprintf(buff
, " encoding=\"%s\"", doc
->encoding
);
474 xmlNodeAddContent( node
, xmlbuff
);
477 if (doc
->standalone
!= -2)
479 sprintf(buff
, " standalone=\"%s\"", doc
->standalone
== 0 ? "no" : "yes");
480 xmlNodeAddContent( node
, xmlbuff
);
483 xmldoc_link_xmldecl( doc
, node
);
489 void xmldoc_init(xmlDocPtr doc
, const GUID
*clsid
)
491 doc
->_private
= create_priv();
492 priv_from_xmlDocPtr(doc
)->properties
= create_properties(clsid
);
495 LONG
xmldoc_add_ref(xmlDocPtr doc
)
497 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
498 TRACE("(%p)->(%d)\n", doc
, ref
);
502 LONG
xmldoc_release(xmlDocPtr doc
)
504 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
505 LONG ref
= InterlockedDecrement(&priv
->refs
);
506 TRACE("(%p)->(%d)\n", doc
, ref
);
509 orphan_entry
*orphan
, *orphan2
;
510 TRACE("freeing docptr %p\n", doc
);
512 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
514 xmlFreeNode( orphan
->node
);
517 free_properties(priv
->properties
);
518 heap_free(doc
->_private
);
526 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
528 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
531 entry
= heap_alloc( sizeof (*entry
) );
533 return E_OUTOFMEMORY
;
536 list_add_head( &priv
->orphans
, &entry
->entry
);
540 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
542 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
543 orphan_entry
*entry
, *entry2
;
545 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
547 if( entry
->node
== node
)
549 list_remove( &entry
->entry
);
558 static inline xmlDocPtr
get_doc( domdoc
*This
)
560 return (xmlDocPtr
)This
->node
.node
;
563 static HRESULT
attach_xmldoc(domdoc
*This
, xmlDocPtr xml
)
567 priv_from_xmlDocPtr(get_doc(This
))->properties
= NULL
;
568 if (xmldoc_release(get_doc(This
)) != 0)
569 priv_from_xmlDocPtr(get_doc(This
))->properties
=
570 copy_properties(This
->properties
);
573 This
->node
.node
= (xmlNodePtr
) xml
;
577 xmldoc_add_ref(get_doc(This
));
578 priv_from_xmlDocPtr(get_doc(This
))->properties
= This
->properties
;
584 static inline domdoc
*impl_from_IXMLDOMDocument3( IXMLDOMDocument3
*iface
)
586 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpVtbl
));
589 static inline domdoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
591 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIPersistStreamInit
));
594 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
596 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectWithSite
));
599 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
601 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectSafety
));
604 static inline domdoc
*impl_from_ISupportErrorInfo(ISupportErrorInfo
*iface
)
606 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblISupportErrorInfo
));
609 static inline domdoc
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
611 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpVtblConnectionPointContainer
));
614 /************************************************************************
615 * domdoc implementation of IPersistStream.
617 static HRESULT WINAPI
domdoc_IPersistStreamInit_QueryInterface(
618 IPersistStreamInit
*iface
, REFIID riid
, void **ppvObj
)
620 domdoc
*this = impl_from_IPersistStreamInit(iface
);
621 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2
*)this, riid
, ppvObj
);
624 static ULONG WINAPI
domdoc_IPersistStreamInit_AddRef(
625 IPersistStreamInit
*iface
)
627 domdoc
*this = impl_from_IPersistStreamInit(iface
);
628 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2
*)this);
631 static ULONG WINAPI
domdoc_IPersistStreamInit_Release(
632 IPersistStreamInit
*iface
)
634 domdoc
*this = impl_from_IPersistStreamInit(iface
);
635 return IXMLDOMDocument2_Release((IXMLDOMDocument2
*)this);
638 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetClassID(
639 IPersistStreamInit
*iface
, CLSID
*classid
)
641 TRACE("(%p,%p): stub!\n", iface
, classid
);
646 *classid
= CLSID_DOMDocument2
;
651 static HRESULT WINAPI
domdoc_IPersistStreamInit_IsDirty(
652 IPersistStreamInit
*iface
)
654 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
655 FIXME("(%p): stub!\n", This
);
659 static HRESULT WINAPI
domdoc_IPersistStreamInit_Load(
660 IPersistStreamInit
*iface
, LPSTREAM pStm
)
662 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
665 DWORD read
, written
, len
;
668 xmlDocPtr xmldoc
= NULL
;
670 TRACE("(%p)->(%p)\n", This
, pStm
);
675 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
681 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
682 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
683 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
687 ERR("Failed to copy stream\n");
691 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
695 len
= GlobalSize(hglobal
);
696 ptr
= GlobalLock(hglobal
);
698 xmldoc
= doparse(This
, ptr
, len
, NULL
);
699 GlobalUnlock(hglobal
);
703 ERR("Failed to parse xml\n");
707 xmldoc
->_private
= create_priv();
709 return attach_xmldoc(This
, xmldoc
);
712 static HRESULT WINAPI
domdoc_IPersistStreamInit_Save(
713 IPersistStreamInit
*iface
, IStream
*stream
, BOOL clr_dirty
)
715 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
719 TRACE("(%p)->(%p %d)\n", This
, stream
, clr_dirty
);
721 hr
= IXMLDOMDocument3_get_xml( (IXMLDOMDocument3
*)&This
->lpVtbl
, &xmlString
);
724 DWORD len
= SysStringLen(xmlString
) * sizeof(WCHAR
);
726 hr
= IStream_Write( stream
, xmlString
, len
, NULL
);
727 SysFreeString(xmlString
);
730 TRACE("ret 0x%08x\n", hr
);
735 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetSizeMax(
736 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
738 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
739 TRACE("(%p)->(%p): stub!\n", This
, pcbSize
);
743 static HRESULT WINAPI
domdoc_IPersistStreamInit_InitNew(
744 IPersistStreamInit
*iface
)
746 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
747 TRACE("(%p)\n", This
);
751 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
753 domdoc_IPersistStreamInit_QueryInterface
,
754 domdoc_IPersistStreamInit_AddRef
,
755 domdoc_IPersistStreamInit_Release
,
756 domdoc_IPersistStreamInit_GetClassID
,
757 domdoc_IPersistStreamInit_IsDirty
,
758 domdoc_IPersistStreamInit_Load
,
759 domdoc_IPersistStreamInit_Save
,
760 domdoc_IPersistStreamInit_GetSizeMax
,
761 domdoc_IPersistStreamInit_InitNew
764 /* ISupportErrorInfo interface */
765 static HRESULT WINAPI
support_error_QueryInterface(
766 ISupportErrorInfo
*iface
,
767 REFIID riid
, void** ppvObj
)
769 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
770 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3
*)This
, riid
, ppvObj
);
773 static ULONG WINAPI
support_error_AddRef(
774 ISupportErrorInfo
*iface
)
776 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
777 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
780 static ULONG WINAPI
support_error_Release(
781 ISupportErrorInfo
*iface
)
783 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
784 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
787 static HRESULT WINAPI
support_error_InterfaceSupportsErrorInfo(
788 ISupportErrorInfo
*iface
,
791 FIXME("(%p)->(%s)\n", iface
, debugstr_guid(riid
));
795 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
797 support_error_QueryInterface
,
798 support_error_AddRef
,
799 support_error_Release
,
800 support_error_InterfaceSupportsErrorInfo
803 /* IXMLDOMDocument2 interface */
804 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument3
*iface
, REFIID riid
, void** ppvObject
)
806 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
808 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppvObject
);
812 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
813 IsEqualGUID( riid
, &IID_IDispatch
) ||
814 IsEqualGUID( riid
, &IID_IXMLDOMNode
) ||
815 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
816 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
)||
817 IsEqualGUID( riid
, &IID_IXMLDOMDocument3
))
821 else if (IsEqualGUID(&IID_IPersistStream
, riid
) ||
822 IsEqualGUID(&IID_IPersistStreamInit
, riid
))
824 *ppvObject
= &(This
->lpvtblIPersistStreamInit
);
826 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
828 *ppvObject
= &(This
->lpvtblIObjectWithSite
);
830 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
832 *ppvObject
= &(This
->lpvtblIObjectSafety
);
834 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
836 *ppvObject
= &This
->lpvtblISupportErrorInfo
;
838 else if(node_query_interface(&This
->node
, riid
, ppvObject
))
840 return *ppvObject
? S_OK
: E_NOINTERFACE
;
842 else if (IsEqualGUID( riid
, &IID_IConnectionPointContainer
))
844 *ppvObject
= &This
->lpVtblConnectionPointContainer
;
846 else if(IsEqualGUID(&IID_IRunnableObject
, riid
))
848 TRACE("IID_IRunnableObject not supported returning NULL\n");
849 return E_NOINTERFACE
;
853 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
854 return E_NOINTERFACE
;
857 IUnknown_AddRef((IUnknown
*)*ppvObject
);
863 static ULONG WINAPI
domdoc_AddRef(
864 IXMLDOMDocument3
*iface
)
866 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
867 ULONG ref
= InterlockedIncrement( &This
->ref
);
868 TRACE("(%p)->(%d)\n", This
, ref
);
873 static ULONG WINAPI
domdoc_Release(
874 IXMLDOMDocument3
*iface
)
876 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
877 LONG ref
= InterlockedDecrement( &This
->ref
);
879 TRACE("(%p)->(%d)\n", This
, ref
);
884 detach_bsc(This
->bsc
);
887 IUnknown_Release( This
->site
);
888 destroy_xmlnode(&This
->node
);
889 if(This
->schema
) IXMLDOMSchemaCollection2_Release(This
->schema
);
890 if (This
->stream
) IStream_Release(This
->stream
);
897 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument3
*iface
, UINT
* pctinfo
)
899 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
901 TRACE("(%p)->(%p)\n", This
, pctinfo
);
908 static HRESULT WINAPI
domdoc_GetTypeInfo(
909 IXMLDOMDocument3
*iface
,
910 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
912 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
915 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
917 hr
= get_typeinfo(IXMLDOMDocument2_tid
, ppTInfo
);
922 static HRESULT WINAPI
domdoc_GetIDsOfNames(
923 IXMLDOMDocument3
*iface
,
930 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
934 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
937 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
940 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
943 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
944 ITypeInfo_Release(typeinfo
);
951 static HRESULT WINAPI
domdoc_Invoke(
952 IXMLDOMDocument3
*iface
,
957 DISPPARAMS
* pDispParams
,
959 EXCEPINFO
* pExcepInfo
,
962 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
966 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
967 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
969 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
972 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
973 pVarResult
, pExcepInfo
, puArgErr
);
974 ITypeInfo_Release(typeinfo
);
981 static HRESULT WINAPI
domdoc_get_nodeName(
982 IXMLDOMDocument3
*iface
,
985 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
987 static const WCHAR documentW
[] = {'#','d','o','c','u','m','e','n','t',0};
989 TRACE("(%p)->(%p)\n", This
, name
);
991 return return_bstr(documentW
, name
);
995 static HRESULT WINAPI
domdoc_get_nodeValue(
996 IXMLDOMDocument3
*iface
,
999 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1001 TRACE("(%p)->(%p)\n", This
, value
);
1004 return E_INVALIDARG
;
1006 V_VT(value
) = VT_NULL
;
1007 V_BSTR(value
) = NULL
; /* tests show that we should do this */
1012 static HRESULT WINAPI
domdoc_put_nodeValue(
1013 IXMLDOMDocument3
*iface
,
1016 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1017 TRACE("(%p)->(v%d)\n", This
, V_VT(&value
));
1022 static HRESULT WINAPI
domdoc_get_nodeType(
1023 IXMLDOMDocument3
*iface
,
1026 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1028 TRACE("(%p)->(%p)\n", This
, type
);
1030 *type
= NODE_DOCUMENT
;
1035 static HRESULT WINAPI
domdoc_get_parentNode(
1036 IXMLDOMDocument3
*iface
,
1037 IXMLDOMNode
** parent
)
1039 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1041 TRACE("(%p)->(%p)\n", This
, parent
);
1043 return node_get_parent(&This
->node
, parent
);
1047 static HRESULT WINAPI
domdoc_get_childNodes(
1048 IXMLDOMDocument3
*iface
,
1049 IXMLDOMNodeList
** childList
)
1051 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1053 TRACE("(%p)->(%p)\n", This
, childList
);
1055 return node_get_child_nodes(&This
->node
, childList
);
1059 static HRESULT WINAPI
domdoc_get_firstChild(
1060 IXMLDOMDocument3
*iface
,
1061 IXMLDOMNode
** firstChild
)
1063 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1065 TRACE("(%p)->(%p)\n", This
, firstChild
);
1067 return node_get_first_child(&This
->node
, firstChild
);
1071 static HRESULT WINAPI
domdoc_get_lastChild(
1072 IXMLDOMDocument3
*iface
,
1073 IXMLDOMNode
** lastChild
)
1075 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1077 TRACE("(%p)->(%p)\n", This
, lastChild
);
1079 return node_get_last_child(&This
->node
, lastChild
);
1083 static HRESULT WINAPI
domdoc_get_previousSibling(
1084 IXMLDOMDocument3
*iface
,
1085 IXMLDOMNode
** previousSibling
)
1087 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1089 TRACE("(%p)->(%p)\n", This
, previousSibling
);
1091 return return_null_node(previousSibling
);
1095 static HRESULT WINAPI
domdoc_get_nextSibling(
1096 IXMLDOMDocument3
*iface
,
1097 IXMLDOMNode
** nextSibling
)
1099 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1101 TRACE("(%p)->(%p)\n", This
, nextSibling
);
1103 return return_null_node(nextSibling
);
1107 static HRESULT WINAPI
domdoc_get_attributes(
1108 IXMLDOMDocument3
*iface
,
1109 IXMLDOMNamedNodeMap
** attributeMap
)
1111 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1113 TRACE("(%p)->(%p)\n", This
, attributeMap
);
1115 return return_null_ptr((void**)attributeMap
);
1119 static HRESULT WINAPI
domdoc_insertBefore(
1120 IXMLDOMDocument3
*iface
,
1121 IXMLDOMNode
* newChild
,
1123 IXMLDOMNode
** outNewChild
)
1125 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1127 TRACE("(%p)->(%p x%d %p)\n", This
, newChild
, V_VT(&refChild
), outNewChild
);
1129 return node_insert_before(&This
->node
, newChild
, &refChild
, outNewChild
);
1133 static HRESULT WINAPI
domdoc_replaceChild(
1134 IXMLDOMDocument3
*iface
,
1135 IXMLDOMNode
* newChild
,
1136 IXMLDOMNode
* oldChild
,
1137 IXMLDOMNode
** outOldChild
)
1139 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1141 TRACE("(%p)->(%p %p %p)\n", This
, newChild
, oldChild
, outOldChild
);
1143 return node_replace_child(&This
->node
, newChild
, oldChild
, outOldChild
);
1147 static HRESULT WINAPI
domdoc_removeChild(
1148 IXMLDOMDocument3
*iface
,
1149 IXMLDOMNode
* childNode
,
1150 IXMLDOMNode
** oldChild
)
1152 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1153 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This
->node
), childNode
, oldChild
);
1157 static HRESULT WINAPI
domdoc_appendChild(
1158 IXMLDOMDocument3
*iface
,
1159 IXMLDOMNode
* newChild
,
1160 IXMLDOMNode
** outNewChild
)
1162 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1163 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This
->node
), newChild
, outNewChild
);
1167 static HRESULT WINAPI
domdoc_hasChildNodes(
1168 IXMLDOMDocument3
*iface
,
1169 VARIANT_BOOL
* hasChild
)
1171 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1172 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This
->node
), hasChild
);
1176 static HRESULT WINAPI
domdoc_get_ownerDocument(
1177 IXMLDOMDocument3
*iface
,
1178 IXMLDOMDocument
** DOMDocument
)
1180 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1181 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This
->node
), DOMDocument
);
1185 static HRESULT WINAPI
domdoc_cloneNode(
1186 IXMLDOMDocument3
*iface
,
1188 IXMLDOMNode
** outNode
)
1190 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1191 TRACE("(%p)->(%d %p)\n", This
, deep
, outNode
);
1192 return node_clone( &This
->node
, deep
, outNode
);
1196 static HRESULT WINAPI
domdoc_get_nodeTypeString(
1197 IXMLDOMDocument3
*iface
,
1200 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1201 static const WCHAR documentW
[] = {'d','o','c','u','m','e','n','t',0};
1203 TRACE("(%p)->(%p)\n", This
, p
);
1205 return return_bstr(documentW
, p
);
1209 static HRESULT WINAPI
domdoc_get_text(
1210 IXMLDOMDocument3
*iface
,
1213 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1214 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This
->node
), text
);
1218 static HRESULT WINAPI
domdoc_put_text(
1219 IXMLDOMDocument3
*iface
,
1222 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1223 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
1228 static HRESULT WINAPI
domdoc_get_specified(
1229 IXMLDOMDocument3
*iface
,
1230 VARIANT_BOOL
* isSpecified
)
1232 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1233 FIXME("(%p)->(%p) stub!\n", This
, isSpecified
);
1234 *isSpecified
= VARIANT_TRUE
;
1239 static HRESULT WINAPI
domdoc_get_definition(
1240 IXMLDOMDocument3
*iface
,
1241 IXMLDOMNode
** definitionNode
)
1243 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1244 FIXME("(%p)->(%p)\n", This
, definitionNode
);
1249 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
1250 IXMLDOMDocument3
*iface
,
1251 VARIANT
* typedValue
)
1253 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1254 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
1257 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
1258 IXMLDOMDocument3
*iface
,
1259 VARIANT typedValue
)
1261 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1262 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
1266 static HRESULT WINAPI
domdoc_get_dataType(
1267 IXMLDOMDocument3
*iface
,
1270 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1271 TRACE("(%p)->(%p)\n", This
, typename
);
1272 return return_null_var( typename
);
1276 static HRESULT WINAPI
domdoc_put_dataType(
1277 IXMLDOMDocument3
*iface
,
1280 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1281 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This
->node
), dataTypeName
);
1284 static int XMLCALL
domdoc_get_xml_writecallback(void *ctx
, const char *data
, int len
)
1286 return xmlBufferAdd((xmlBufferPtr
)ctx
, (xmlChar
*)data
, len
) == 0 ? len
: 0;
1289 static HRESULT WINAPI
domdoc_get_xml(
1290 IXMLDOMDocument3
*iface
,
1293 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1294 xmlSaveCtxtPtr ctxt
;
1299 TRACE("(%p)->(%p)\n", This
, p
);
1302 return E_INVALIDARG
;
1306 buf
= xmlBufferCreate();
1308 return E_OUTOFMEMORY
;
1310 options
= xmldoc_has_decl(get_doc(This
)) ? XML_SAVE_NO_DECL
: 0;
1311 options
|= XML_SAVE_FORMAT
;
1312 ctxt
= xmlSaveToIO(domdoc_get_xml_writecallback
, NULL
, buf
, "UTF-8", options
);
1317 return E_OUTOFMEMORY
;
1320 ret
= xmlSaveDoc(ctxt
, get_doc(This
));
1321 /* flushes on close */
1324 TRACE("%ld, len=%d\n", ret
, xmlBufferLength(buf
));
1325 if(ret
!= -1 && xmlBufferLength(buf
) > 0)
1329 content
= bstr_from_xmlChar(xmlBufferContent(buf
));
1330 content
= EnsureCorrectEOL(content
);
1336 *p
= SysAllocStringLen(NULL
, 0);
1341 return *p
? S_OK
: E_OUTOFMEMORY
;
1345 static HRESULT WINAPI
domdoc_transformNode(
1346 IXMLDOMDocument3
*iface
,
1347 IXMLDOMNode
* styleSheet
,
1350 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1351 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This
->node
), styleSheet
, xmlString
);
1355 static HRESULT WINAPI
domdoc_selectNodes(
1356 IXMLDOMDocument3
*iface
,
1358 IXMLDOMNodeList
** resultList
)
1360 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1361 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultList
);
1365 static HRESULT WINAPI
domdoc_selectSingleNode(
1366 IXMLDOMDocument3
*iface
,
1368 IXMLDOMNode
** resultNode
)
1370 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1371 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultNode
);
1375 static HRESULT WINAPI
domdoc_get_parsed(
1376 IXMLDOMDocument3
*iface
,
1377 VARIANT_BOOL
* isParsed
)
1379 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1380 FIXME("(%p)->(%p) stub!\n", This
, isParsed
);
1381 *isParsed
= VARIANT_TRUE
;
1386 static HRESULT WINAPI
domdoc_get_namespaceURI(
1387 IXMLDOMDocument3
*iface
,
1388 BSTR
* namespaceURI
)
1390 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1391 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This
->node
), namespaceURI
);
1395 static HRESULT WINAPI
domdoc_get_prefix(
1396 IXMLDOMDocument3
*iface
,
1399 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1400 TRACE("(%p)->(%p)\n", This
, prefix
);
1401 return return_null_bstr( prefix
);
1405 static HRESULT WINAPI
domdoc_get_baseName(
1406 IXMLDOMDocument3
*iface
,
1409 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1410 TRACE("(%p)->(%p)\n", This
, name
);
1411 return return_null_bstr( name
);
1415 static HRESULT WINAPI
domdoc_transformNodeToObject(
1416 IXMLDOMDocument3
*iface
,
1417 IXMLDOMNode
* stylesheet
,
1418 VARIANT outputObject
)
1420 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1421 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This
->node
), stylesheet
, outputObject
);
1425 static HRESULT WINAPI
domdoc_get_doctype(
1426 IXMLDOMDocument3
*iface
,
1427 IXMLDOMDocumentType
** documentType
)
1429 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1430 FIXME("(%p)\n", This
);
1435 static HRESULT WINAPI
domdoc_get_implementation(
1436 IXMLDOMDocument3
*iface
,
1437 IXMLDOMImplementation
** impl
)
1439 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1441 TRACE("(%p)->(%p)\n", This
, impl
);
1444 return E_INVALIDARG
;
1446 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
1451 static HRESULT WINAPI
domdoc_get_documentElement(
1452 IXMLDOMDocument3
*iface
,
1453 IXMLDOMElement
** DOMElement
)
1455 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1456 IXMLDOMNode
*element_node
;
1460 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1463 return E_INVALIDARG
;
1467 root
= xmlDocGetRootElement( get_doc(This
) );
1471 element_node
= create_node( root
);
1472 if(!element_node
) return S_FALSE
;
1474 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (void**)DOMElement
);
1475 IXMLDOMNode_Release(element_node
);
1481 static HRESULT WINAPI
domdoc_put_documentElement(
1482 IXMLDOMDocument3
*iface
,
1483 IXMLDOMElement
* DOMElement
)
1485 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1486 IXMLDOMNode
*elementNode
;
1491 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1493 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1497 xmlNode
= get_node_obj( elementNode
);
1499 FIXME("elementNode is not our object\n");
1503 if(!xmlNode
->node
->parent
)
1504 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1505 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1507 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1508 IXMLDOMNode_Release( elementNode
);
1511 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1517 static HRESULT WINAPI
domdoc_createElement(
1518 IXMLDOMDocument3
*iface
,
1520 IXMLDOMElement
** element
)
1522 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1527 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagname
), element
);
1529 if (!element
|| !tagname
) return E_INVALIDARG
;
1531 V_VT(&type
) = VT_I1
;
1532 V_I1(&type
) = NODE_ELEMENT
;
1534 hr
= IXMLDOMDocument3_createNode(iface
, type
, tagname
, NULL
, &node
);
1537 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMElement
, (void**)element
);
1538 IXMLDOMNode_Release(node
);
1545 static HRESULT WINAPI
domdoc_createDocumentFragment(
1546 IXMLDOMDocument3
*iface
,
1547 IXMLDOMDocumentFragment
** frag
)
1549 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1554 TRACE("(%p)->(%p)\n", This
, frag
);
1556 if (!frag
) return E_INVALIDARG
;
1560 V_VT(&type
) = VT_I1
;
1561 V_I1(&type
) = NODE_DOCUMENT_FRAGMENT
;
1563 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1566 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentFragment
, (void**)frag
);
1567 IXMLDOMNode_Release(node
);
1574 static HRESULT WINAPI
domdoc_createTextNode(
1575 IXMLDOMDocument3
*iface
,
1577 IXMLDOMText
** text
)
1579 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1584 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), text
);
1586 if (!text
) return E_INVALIDARG
;
1590 V_VT(&type
) = VT_I1
;
1591 V_I1(&type
) = NODE_TEXT
;
1593 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1596 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)text
);
1597 IXMLDOMNode_Release(node
);
1598 hr
= IXMLDOMText_put_data(*text
, data
);
1605 static HRESULT WINAPI
domdoc_createComment(
1606 IXMLDOMDocument3
*iface
,
1608 IXMLDOMComment
** comment
)
1610 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1615 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), comment
);
1617 if (!comment
) return E_INVALIDARG
;
1621 V_VT(&type
) = VT_I1
;
1622 V_I1(&type
) = NODE_COMMENT
;
1624 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1627 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)comment
);
1628 IXMLDOMNode_Release(node
);
1629 hr
= IXMLDOMComment_put_data(*comment
, data
);
1636 static HRESULT WINAPI
domdoc_createCDATASection(
1637 IXMLDOMDocument3
*iface
,
1639 IXMLDOMCDATASection
** cdata
)
1641 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1646 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), cdata
);
1648 if (!cdata
) return E_INVALIDARG
;
1652 V_VT(&type
) = VT_I1
;
1653 V_I1(&type
) = NODE_CDATA_SECTION
;
1655 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1658 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)cdata
);
1659 IXMLDOMNode_Release(node
);
1660 hr
= IXMLDOMCDATASection_put_data(*cdata
, data
);
1667 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1668 IXMLDOMDocument3
*iface
,
1671 IXMLDOMProcessingInstruction
** pi
)
1673 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1678 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(target
), debugstr_w(data
), pi
);
1680 if (!pi
) return E_INVALIDARG
;
1684 V_VT(&type
) = VT_I1
;
1685 V_I1(&type
) = NODE_PROCESSING_INSTRUCTION
;
1687 hr
= IXMLDOMDocument3_createNode(iface
, type
, target
, NULL
, &node
);
1692 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1693 node_obj
= get_node_obj(node
);
1694 hr
= node_set_content(node_obj
, data
);
1696 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMProcessingInstruction
, (void**)pi
);
1697 IXMLDOMNode_Release(node
);
1704 static HRESULT WINAPI
domdoc_createAttribute(
1705 IXMLDOMDocument3
*iface
,
1707 IXMLDOMAttribute
** attribute
)
1709 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1714 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), attribute
);
1716 if (!attribute
|| !name
) return E_INVALIDARG
;
1718 V_VT(&type
) = VT_I1
;
1719 V_I1(&type
) = NODE_ATTRIBUTE
;
1721 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1724 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMAttribute
, (void**)attribute
);
1725 IXMLDOMNode_Release(node
);
1732 static HRESULT WINAPI
domdoc_createEntityReference(
1733 IXMLDOMDocument3
*iface
,
1735 IXMLDOMEntityReference
** entityref
)
1737 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1742 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), entityref
);
1744 if (!entityref
) return E_INVALIDARG
;
1748 V_VT(&type
) = VT_I1
;
1749 V_I1(&type
) = NODE_ENTITY_REFERENCE
;
1751 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1754 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMEntityReference
, (void**)entityref
);
1755 IXMLDOMNode_Release(node
);
1762 static HRESULT WINAPI
domdoc_getElementsByTagName(
1763 IXMLDOMDocument3
*iface
,
1765 IXMLDOMNodeList
** resultList
)
1767 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1770 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagName
), resultList
);
1772 if (!tagName
|| !resultList
) return E_INVALIDARG
;
1774 if (tagName
[0] == '*' && tagName
[1] == 0)
1776 static const WCHAR formatallW
[] = {'/','/','*',0};
1777 hr
= queryresult_create((xmlNodePtr
)get_doc(This
), formatallW
, resultList
);
1781 static const WCHAR xpathformat
[] =
1782 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
1783 static const WCHAR closeW
[] = { '\'',']',0 };
1789 length
= lstrlenW(tagName
);
1791 /* without two WCHARs from format specifier */
1792 ptr
= pattern
= heap_alloc(sizeof(xpathformat
) + length
*sizeof(WCHAR
) + sizeof(closeW
));
1794 memcpy(ptr
, xpathformat
, sizeof(xpathformat
));
1795 ptr
+= sizeof(xpathformat
)/sizeof(WCHAR
);
1796 memcpy(ptr
, tagName
, length
*sizeof(WCHAR
));
1798 memcpy(ptr
, closeW
, sizeof(closeW
));
1800 hr
= queryresult_create((xmlNodePtr
)get_doc(This
), pattern
, resultList
);
1807 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1813 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1815 return E_INVALIDARG
;
1822 static HRESULT WINAPI
domdoc_createNode(
1823 IXMLDOMDocument3
*iface
,
1827 IXMLDOMNode
** node
)
1829 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1830 DOMNodeType node_type
;
1832 xmlChar
*xml_name
, *href
;
1835 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1837 if(!node
) return E_INVALIDARG
;
1839 hr
= get_node_type(Type
, &node_type
);
1840 if(FAILED(hr
)) return hr
;
1842 if(namespaceURI
&& namespaceURI
[0] && node_type
!= NODE_ELEMENT
)
1843 FIXME("nodes with namespaces currently not supported.\n");
1845 TRACE("node_type %d\n", node_type
);
1847 /* exit earlier for types that need name */
1851 case NODE_ATTRIBUTE
:
1852 case NODE_ENTITY_REFERENCE
:
1853 case NODE_PROCESSING_INSTRUCTION
:
1854 if (!name
|| *name
== 0) return E_FAIL
;
1859 xml_name
= xmlChar_from_wchar(name
);
1860 /* prevent empty href to be allocated */
1861 href
= namespaceURI
? xmlChar_from_wchar(namespaceURI
) : NULL
;
1867 xmlChar
*local
, *prefix
;
1869 local
= xmlSplitQName2(xml_name
, &prefix
);
1871 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, local
? local
: xml_name
, NULL
);
1873 /* allow to create default namespace xmlns= */
1874 if (local
|| (href
&& *href
))
1876 xmlNsPtr ns
= xmlNewNs(xmlnode
, href
, prefix
);
1877 xmlSetNs(xmlnode
, ns
);
1885 case NODE_ATTRIBUTE
:
1886 xmlnode
= (xmlNodePtr
)xmlNewDocProp(get_doc(This
), xml_name
, NULL
);
1889 xmlnode
= (xmlNodePtr
)xmlNewDocText(get_doc(This
), NULL
);
1891 case NODE_CDATA_SECTION
:
1892 xmlnode
= xmlNewCDataBlock(get_doc(This
), NULL
, 0);
1894 case NODE_ENTITY_REFERENCE
:
1895 xmlnode
= xmlNewReference(get_doc(This
), xml_name
);
1897 case NODE_PROCESSING_INSTRUCTION
:
1898 #ifdef HAVE_XMLNEWDOCPI
1899 xmlnode
= xmlNewDocPI(get_doc(This
), xml_name
, NULL
);
1901 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1906 xmlnode
= xmlNewDocComment(get_doc(This
), NULL
);
1908 case NODE_DOCUMENT_FRAGMENT
:
1909 xmlnode
= xmlNewDocFragment(get_doc(This
));
1911 /* unsupported types */
1913 case NODE_DOCUMENT_TYPE
:
1916 heap_free(xml_name
);
1917 return E_INVALIDARG
;
1919 FIXME("unhandled node type %d\n", node_type
);
1924 *node
= create_node(xmlnode
);
1925 heap_free(xml_name
);
1930 TRACE("created node (%d, %p, %p)\n", node_type
, *node
, xmlnode
);
1931 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1938 static HRESULT WINAPI
domdoc_nodeFromID(
1939 IXMLDOMDocument3
*iface
,
1941 IXMLDOMNode
** node
)
1943 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1944 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(idString
), node
);
1948 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
1953 xmldoc
= doparse(This
, ptr
, len
, NULL
);
1955 xmldoc
->_private
= create_priv();
1956 return attach_xmldoc(This
, xmldoc
);
1962 static HRESULT
doread( domdoc
*This
, LPWSTR filename
)
1967 hr
= bind_url(filename
, domdoc_onDataAvailable
, This
, &bsc
);
1972 detach_bsc(This
->bsc
);
1978 static HRESULT WINAPI
domdoc_load(
1979 IXMLDOMDocument3
*iface
,
1981 VARIANT_BOOL
* isSuccessful
)
1983 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1984 LPWSTR filename
= NULL
;
1985 HRESULT hr
= S_FALSE
;
1986 IXMLDOMDocument3
*pNewDoc
= NULL
;
1987 IStream
*pStream
= NULL
;
1990 TRACE("(%p)->type %d\n", This
, V_VT(&xmlSource
) );
1992 *isSuccessful
= VARIANT_FALSE
;
1994 assert( &This
->node
);
1996 switch( V_VT(&xmlSource
) )
1999 filename
= V_BSTR(&xmlSource
);
2002 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IXMLDOMDocument3
, (void**)&pNewDoc
);
2007 domdoc
*newDoc
= impl_from_IXMLDOMDocument3( pNewDoc
);
2008 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
2009 hr
= attach_xmldoc(This
, xmldoc
);
2012 *isSuccessful
= VARIANT_TRUE
;
2017 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IStream
, (void**)&pStream
);
2020 IPersistStream
*pDocStream
;
2021 hr
= IUnknown_QueryInterface(iface
, &IID_IPersistStream
, (void**)&pDocStream
);
2024 hr
= IPersistStream_Load(pDocStream
, pStream
);
2025 IStream_Release(pStream
);
2028 *isSuccessful
= VARIANT_TRUE
;
2030 TRACE("Using IStream to load Document\n");
2035 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr
);
2040 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr
);
2045 /* ISequentialStream */
2046 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr
, pNewDoc
, V_UNKNOWN(&xmlSource
)->lpVtbl
);
2050 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource
));
2053 TRACE("filename (%s)\n", debugstr_w(filename
));
2057 hr
= doread( This
, filename
);
2060 This
->error
= E_FAIL
;
2063 hr
= This
->error
= S_OK
;
2064 *isSuccessful
= VARIANT_TRUE
;
2068 if(!filename
|| FAILED(hr
)) {
2069 xmldoc
= xmlNewDoc(NULL
);
2070 xmldoc
->_private
= create_priv();
2071 hr
= attach_xmldoc(This
, xmldoc
);
2076 TRACE("ret (%d)\n", hr
);
2082 static HRESULT WINAPI
domdoc_get_readyState(
2083 IXMLDOMDocument3
*iface
,
2086 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2087 FIXME("stub! (%p)->(%p)\n", This
, value
);
2090 return E_INVALIDARG
;
2092 *value
= READYSTATE_COMPLETE
;
2097 static HRESULT WINAPI
domdoc_get_parseError(
2098 IXMLDOMDocument3
*iface
,
2099 IXMLDOMParseError
** errorObj
)
2101 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2102 static const WCHAR err
[] = {'e','r','r','o','r',0};
2103 BSTR error_string
= NULL
;
2105 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
2108 error_string
= SysAllocString(err
);
2110 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
2111 if(!*errorObj
) return E_OUTOFMEMORY
;
2116 static HRESULT WINAPI
domdoc_get_url(
2117 IXMLDOMDocument3
*iface
,
2120 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2121 FIXME("(%p)->(%p)\n", This
, urlString
);
2126 static HRESULT WINAPI
domdoc_get_async(
2127 IXMLDOMDocument3
*iface
,
2128 VARIANT_BOOL
* isAsync
)
2130 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2132 TRACE("(%p)->(%p: %d)\n", This
, isAsync
, This
->async
);
2133 *isAsync
= This
->async
;
2138 static HRESULT WINAPI
domdoc_put_async(
2139 IXMLDOMDocument3
*iface
,
2140 VARIANT_BOOL isAsync
)
2142 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2144 TRACE("(%p)->(%d)\n", This
, isAsync
);
2145 This
->async
= isAsync
;
2150 static HRESULT WINAPI
domdoc_abort(
2151 IXMLDOMDocument3
*iface
)
2153 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2154 FIXME("%p\n", This
);
2159 static BOOL
bstr_to_utf8( BSTR bstr
, char **pstr
, int *plen
)
2164 len
= WideCharToMultiByte( CP_UTF8
, 0, bstr
, -1, NULL
, 0, NULL
, NULL
);
2165 str
= heap_alloc( len
);
2168 WideCharToMultiByte( CP_UTF8
, 0, bstr
, -1, str
, len
, NULL
, NULL
);
2174 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2175 static HRESULT WINAPI
domdoc_loadXML(
2176 IXMLDOMDocument3
*iface
,
2178 VARIANT_BOOL
* isSuccessful
)
2180 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2181 static const xmlChar encoding
[] = "UTF-8";
2182 xmlDocPtr xmldoc
= NULL
;
2183 HRESULT hr
= S_FALSE
, hr2
;
2187 TRACE("(%p)->(%s %p)\n", This
, debugstr_w( bstrXML
), isSuccessful
);
2189 assert ( &This
->node
);
2193 *isSuccessful
= VARIANT_FALSE
;
2195 if ( bstrXML
&& bstr_to_utf8( bstrXML
, &str
, &len
) )
2197 xmldoc
= doparse(This
, str
, len
, encoding
);
2201 This
->error
= E_FAIL
;
2202 TRACE("failed to parse document\n");
2206 hr
= This
->error
= S_OK
;
2207 *isSuccessful
= VARIANT_TRUE
;
2208 TRACE("parsed document %p\n", xmldoc
);
2213 xmldoc
= xmlNewDoc(NULL
);
2215 xmldoc
->_private
= create_priv();
2217 hr2
= attach_xmldoc(This
, xmldoc
);
2224 static int XMLCALL
domdoc_save_writecallback(void *ctx
, const char *buffer
, int len
)
2228 if(!WriteFile(ctx
, buffer
, len
, &written
, NULL
))
2230 WARN("write error\n");
2237 static int XMLCALL
domdoc_save_closecallback(void *ctx
)
2239 return CloseHandle(ctx
) ? 0 : -1;
2242 static int XMLCALL
domdoc_stream_save_writecallback(void *ctx
, const char *buffer
, int len
)
2247 hr
= IStream_Write((IStream
*)ctx
, buffer
, len
, &written
);
2250 WARN("stream write error: 0x%08x\n", hr
);
2257 static int XMLCALL
domdoc_stream_save_closecallback(void *ctx
)
2259 IStream_Release((IStream
*)ctx
);
2263 static HRESULT WINAPI
domdoc_save(
2264 IXMLDOMDocument3
*iface
,
2265 VARIANT destination
)
2267 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2268 xmlSaveCtxtPtr ctx
= NULL
;
2272 TRACE("(%p)->(var(vt %d, %s))\n", This
, V_VT(&destination
),
2273 V_VT(&destination
) == VT_BSTR
? debugstr_w(V_BSTR(&destination
)) : NULL
);
2275 if(V_VT(&destination
) != VT_BSTR
&& V_VT(&destination
) != VT_UNKNOWN
)
2277 FIXME("Unhandled vt %d\n", V_VT(&destination
));
2281 if(V_VT(&destination
) == VT_UNKNOWN
)
2283 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
2284 IXMLDOMDocument2
*document
;
2287 ret
= IUnknown_QueryInterface(pUnk
, &IID_IXMLDOMDocument3
, (void**)&document
);
2290 VARIANT_BOOL success
;
2293 ret
= IXMLDOMDocument3_get_xml(iface
, &xml
);
2296 ret
= IXMLDOMDocument3_loadXML(document
, xml
, &success
);
2300 IXMLDOMDocument3_Release(document
);
2304 ret
= IUnknown_QueryInterface(pUnk
, &IID_IStream
, (void**)&stream
);
2307 ctx
= xmlSaveToIO(domdoc_stream_save_writecallback
,
2308 domdoc_stream_save_closecallback
, stream
, NULL
, XML_SAVE_NO_DECL
);
2312 IStream_Release(stream
);
2319 /* save with file path */
2320 HANDLE handle
= CreateFileW( V_BSTR(&destination
), GENERIC_WRITE
, 0,
2321 NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2322 if( handle
== INVALID_HANDLE_VALUE
)
2324 WARN("failed to create file\n");
2328 /* disable top XML declaration */
2329 ctx
= xmlSaveToIO(domdoc_save_writecallback
, domdoc_save_closecallback
,
2330 handle
, NULL
, XML_SAVE_NO_DECL
);
2333 CloseHandle(handle
);
2338 xmldecl
= xmldoc_unlink_xmldecl(get_doc(This
));
2339 if (xmlSaveDoc(ctx
, get_doc(This
)) == -1) ret
= S_FALSE
;
2340 xmldoc_link_xmldecl(get_doc(This
), xmldecl
);
2342 /* will release resources through close callback */
2348 static HRESULT WINAPI
domdoc_get_validateOnParse(
2349 IXMLDOMDocument3
*iface
,
2350 VARIANT_BOOL
* isValidating
)
2352 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2353 TRACE("(%p)->(%p: %d)\n", This
, isValidating
, This
->validating
);
2354 *isValidating
= This
->validating
;
2359 static HRESULT WINAPI
domdoc_put_validateOnParse(
2360 IXMLDOMDocument3
*iface
,
2361 VARIANT_BOOL isValidating
)
2363 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2364 TRACE("(%p)->(%d)\n", This
, isValidating
);
2365 This
->validating
= isValidating
;
2370 static HRESULT WINAPI
domdoc_get_resolveExternals(
2371 IXMLDOMDocument3
*iface
,
2372 VARIANT_BOOL
* isResolving
)
2374 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2375 TRACE("(%p)->(%p: %d)\n", This
, isResolving
, This
->resolving
);
2376 *isResolving
= This
->resolving
;
2381 static HRESULT WINAPI
domdoc_put_resolveExternals(
2382 IXMLDOMDocument3
*iface
,
2383 VARIANT_BOOL isResolving
)
2385 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2386 TRACE("(%p)->(%d)\n", This
, isResolving
);
2387 This
->resolving
= isResolving
;
2392 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
2393 IXMLDOMDocument3
*iface
,
2394 VARIANT_BOOL
* isPreserving
)
2396 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2397 TRACE("(%p)->(%p: %d)\n", This
, isPreserving
, This
->properties
->preserving
);
2398 *isPreserving
= This
->properties
->preserving
;
2403 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
2404 IXMLDOMDocument3
*iface
,
2405 VARIANT_BOOL isPreserving
)
2407 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2408 TRACE("(%p)->(%d)\n", This
, isPreserving
);
2409 This
->properties
->preserving
= isPreserving
;
2414 static HRESULT WINAPI
domdoc_put_onReadyStateChange(
2415 IXMLDOMDocument3
*iface
,
2416 VARIANT readyStateChangeSink
)
2418 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2419 FIXME("%p\n", This
);
2424 static HRESULT WINAPI
domdoc_put_onDataAvailable(
2425 IXMLDOMDocument3
*iface
,
2426 VARIANT onDataAvailableSink
)
2428 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2429 FIXME("%p\n", This
);
2433 static HRESULT WINAPI
domdoc_put_onTransformNode(
2434 IXMLDOMDocument3
*iface
,
2435 VARIANT onTransformNodeSink
)
2437 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2438 FIXME("%p\n", This
);
2442 static HRESULT WINAPI
domdoc_get_namespaces(
2443 IXMLDOMDocument3
* iface
,
2444 IXMLDOMSchemaCollection
** schemaCollection
)
2446 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2447 FIXME("(%p)->(%p)\n", This
, schemaCollection
);
2451 static HRESULT WINAPI
domdoc_get_schemas(
2452 IXMLDOMDocument3
* iface
,
2455 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2456 HRESULT hr
= S_FALSE
;
2457 IXMLDOMSchemaCollection2
* cur_schema
= This
->schema
;
2459 TRACE("(%p)->(%p)\n", This
, var1
);
2461 VariantInit(var1
); /* Test shows we don't call VariantClear here */
2462 V_VT(var1
) = VT_NULL
;
2466 hr
= IXMLDOMSchemaCollection2_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(var1
));
2468 V_VT(var1
) = VT_DISPATCH
;
2473 static HRESULT WINAPI
domdoc_putref_schemas(
2474 IXMLDOMDocument3
* iface
,
2477 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2478 HRESULT hr
= E_FAIL
;
2479 IXMLDOMSchemaCollection2
* new_schema
= NULL
;
2481 FIXME("(%p): semi-stub\n", This
);
2485 hr
= IUnknown_QueryInterface(V_UNKNOWN(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2489 hr
= IDispatch_QueryInterface(V_DISPATCH(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2498 WARN("Can't get schema from vt %x\n", V_VT(&var1
));
2503 IXMLDOMSchemaCollection2
* old_schema
= InterlockedExchangePointer((void**)&This
->schema
, new_schema
);
2504 if(old_schema
) IXMLDOMSchemaCollection2_Release(old_schema
);
2510 static inline BOOL
is_wellformed(xmlDocPtr doc
)
2512 #ifdef HAVE_XMLDOC_PROPERTIES
2513 return doc
->properties
& XML_DOC_WELLFORMED
;
2515 /* Not a full check, but catches the worst violations */
2519 for (child
= doc
->children
; child
!= NULL
; child
= child
->next
)
2521 switch (child
->type
)
2523 case XML_ELEMENT_NODE
:
2528 case XML_CDATA_SECTION_NODE
:
2540 static void LIBXML2_LOG_CALLBACK
validate_error(void* ctx
, char const* msg
, ...)
2544 LIBXML2_CALLBACK_ERR(domdoc_validateNode
, msg
, ap
);
2548 static void LIBXML2_LOG_CALLBACK
validate_warning(void* ctx
, char const* msg
, ...)
2552 LIBXML2_CALLBACK_WARN(domdoc_validateNode
, msg
, ap
);
2556 static HRESULT WINAPI
domdoc_validateNode(
2557 IXMLDOMDocument3
* iface
,
2559 IXMLDOMParseError
** err
)
2561 domdoc
* This
= impl_from_IXMLDOMDocument3(iface
);
2562 LONG state
, err_code
= 0;
2566 TRACE("(%p)->(%p, %p)\n", This
, node
, err
);
2567 domdoc_get_readyState(iface
, &state
);
2568 if (state
!= READYSTATE_COMPLETE
)
2571 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2578 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2582 if (!get_node_obj(node
)->node
|| get_node_obj(node
)->node
->doc
!= get_doc(This
))
2585 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2589 if (!is_wellformed(get_doc(This
)))
2591 ERR("doc not well-formed");
2593 *err
= create_parseError(E_XML_NOTWF
, NULL
, NULL
, NULL
, 0, 0, 0);
2597 /* DTD validation */
2598 if (get_doc(This
)->intSubset
|| get_doc(This
)->extSubset
)
2600 xmlValidCtxtPtr vctx
= xmlNewValidCtxt();
2601 vctx
->error
= validate_error
;
2602 vctx
->warning
= validate_warning
;
2605 if (!((node
== (IXMLDOMNode
*)iface
)?
2606 xmlValidateDocument(vctx
, get_doc(This
)) :
2607 xmlValidateElement(vctx
, get_doc(This
), get_node_obj(node
)->node
)))
2609 /* TODO: get a real error code here */
2610 TRACE("DTD validation failed\n");
2611 err_code
= E_XML_INVALID
;
2614 xmlFreeValidCtxt(vctx
);
2617 /* Schema validation */
2618 if (hr
== S_OK
&& This
->schema
!= NULL
)
2621 hr
= SchemaCache_validate_tree(This
->schema
, get_node_obj(node
)->node
);
2625 /* TODO: get a real error code here */
2626 TRACE("schema validation failed\n");
2628 err_code
= E_XML_INVALID
;
2632 /* not really OK, just didn't find a schema for the ns */
2639 TRACE("no DTD or schema found\n");
2640 err_code
= E_XML_NODTD
;
2645 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2650 static HRESULT WINAPI
domdoc_validate(
2651 IXMLDOMDocument3
* iface
,
2652 IXMLDOMParseError
** err
)
2654 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2655 TRACE("(%p)->(%p)\n", This
, err
);
2656 return domdoc_validateNode(iface
, (IXMLDOMNode
*)iface
, err
);
2659 static HRESULT WINAPI
domdoc_setProperty(
2660 IXMLDOMDocument3
* iface
,
2664 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2666 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
2668 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2674 V_VT(&varStr
) = VT_EMPTY
;
2675 if (V_VT(&var
) != VT_BSTR
)
2677 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2679 bstr
= V_BSTR(&varStr
);
2682 bstr
= V_BSTR(&var
);
2685 if (lstrcmpiW(bstr
, PropValueXPathW
) == 0)
2686 This
->properties
->XPath
= TRUE
;
2687 else if (lstrcmpiW(bstr
, PropValueXSLPatternW
) == 0)
2688 This
->properties
->XPath
= FALSE
;
2692 VariantClear(&varStr
);
2695 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2700 xmlChar
*pTokBegin
, *pTokEnd
, *pTokInner
;
2701 xmlChar
*nsStr
= (xmlChar
*)This
->properties
->selectNsStr
;
2702 xmlXPathContextPtr ctx
;
2703 struct list
*pNsList
;
2704 select_ns_entry
* pNsEntry
= NULL
;
2706 V_VT(&varStr
) = VT_EMPTY
;
2707 if (V_VT(&var
) != VT_BSTR
)
2709 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2711 bstr
= V_BSTR(&varStr
);
2714 bstr
= V_BSTR(&var
);
2718 pNsList
= &(This
->properties
->selectNsList
);
2719 clear_selectNsList(pNsList
);
2721 nsStr
= xmlChar_from_wchar(bstr
);
2724 TRACE("Setting SelectionNamespaces property to: %s\n", nsStr
);
2726 This
->properties
->selectNsStr
= nsStr
;
2727 This
->properties
->selectNsStr_len
= xmlStrlen(nsStr
);
2730 ctx
= xmlXPathNewContext(This
->node
.node
->doc
);
2733 for (; *pTokBegin
; pTokBegin
= pTokEnd
)
2735 if (pNsEntry
!= NULL
)
2736 memset(pNsEntry
, 0, sizeof(select_ns_entry
));
2738 pNsEntry
= heap_alloc_zero(sizeof(select_ns_entry
));
2740 while (*pTokBegin
== ' ')
2742 pTokEnd
= pTokBegin
;
2743 while (*pTokEnd
!= ' ' && *pTokEnd
!= 0)
2746 if (xmlStrncmp(pTokBegin
, (xmlChar
const*)"xmlns", 5) != 0)
2749 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2750 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2755 if (*pTokBegin
== '=')
2757 /*valid for XSLPattern?*/
2758 FIXME("Setting default xmlns not supported - skipping.\n");
2759 pTokBegin
= pTokEnd
;
2762 else if (*pTokBegin
== ':')
2764 pNsEntry
->prefix
= ++pTokBegin
;
2765 for (pTokInner
= pTokBegin
; pTokInner
!= pTokEnd
&& *pTokInner
!= '='; ++pTokInner
)
2768 if (pTokInner
== pTokEnd
)
2771 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2772 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2776 pNsEntry
->prefix_end
= *pTokInner
;
2780 if (pTokEnd
-pTokInner
> 1 &&
2781 ((*pTokInner
== '\'' && *(pTokEnd
-1) == '\'') ||
2782 (*pTokInner
== '"' && *(pTokEnd
-1) == '"')))
2784 pNsEntry
->href
= ++pTokInner
;
2785 pNsEntry
->href_end
= *(pTokEnd
-1);
2787 list_add_tail(pNsList
, &pNsEntry
->entry
);
2788 /*let libxml figure out if they're valid from here ;)*/
2789 if (xmlXPathRegisterNs(ctx
, pNsEntry
->prefix
, pNsEntry
->href
) != 0)
2798 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2799 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokInner
, pTokEnd
-pTokInner
));
2800 list_add_tail(pNsList
, &pNsEntry
->entry
);
2813 heap_free(pNsEntry
);
2814 xmlXPathFreeContext(ctx
);
2817 VariantClear(&varStr
);
2820 else if (lstrcmpiW(p
, PropertyProhibitDTDW
) == 0 ||
2821 lstrcmpiW(p
, PropertyNewParserW
) == 0)
2824 FIXME("Ignoring property %s, value %d\n", debugstr_w(p
), V_BOOL(&var
));
2828 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2832 static HRESULT WINAPI
domdoc_getProperty(
2833 IXMLDOMDocument3
* iface
,
2837 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2839 TRACE("(%p)->(%p)\n", This
, debugstr_w(p
));
2842 return E_INVALIDARG
;
2844 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2846 V_VT(var
) = VT_BSTR
;
2847 V_BSTR(var
) = This
->properties
->XPath
?
2848 SysAllocString(PropValueXPathW
) :
2849 SysAllocString(PropValueXSLPatternW
);
2850 return V_BSTR(var
) ? S_OK
: E_OUTOFMEMORY
;
2852 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2855 BSTR rebuiltStr
, cur
;
2856 const xmlChar
*nsStr
;
2857 struct list
*pNsList
;
2858 select_ns_entry
* pNsEntry
;
2860 V_VT(var
) = VT_BSTR
;
2861 nsStr
= This
->properties
->selectNsStr
;
2862 pNsList
= &This
->properties
->selectNsList
;
2863 lenA
= This
->properties
->selectNsStr_len
;
2864 lenW
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, NULL
, 0);
2865 rebuiltStr
= heap_alloc(lenW
*sizeof(WCHAR
));
2866 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, rebuiltStr
, lenW
);
2868 /* this is fine because all of the chars that end tokens are ASCII*/
2869 LIST_FOR_EACH_ENTRY(pNsEntry
, pNsList
, select_ns_entry
, entry
)
2871 while (*cur
!= 0) ++cur
;
2872 if (pNsEntry
->prefix_end
)
2874 *cur
= pNsEntry
->prefix_end
;
2875 while (*cur
!= 0) ++cur
;
2878 if (pNsEntry
->href_end
)
2880 *cur
= pNsEntry
->href_end
;
2883 V_BSTR(var
) = SysAllocString(rebuiltStr
);
2884 heap_free(rebuiltStr
);
2888 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2892 static HRESULT WINAPI
domdoc_importNode(
2893 IXMLDOMDocument3
* iface
,
2896 IXMLDOMNode
** clone
)
2898 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2899 FIXME("(%p)->(%p %d %p): stub\n", This
, node
, deep
, clone
);
2903 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl
=
2905 domdoc_QueryInterface
,
2908 domdoc_GetTypeInfoCount
,
2910 domdoc_GetIDsOfNames
,
2912 domdoc_get_nodeName
,
2913 domdoc_get_nodeValue
,
2914 domdoc_put_nodeValue
,
2915 domdoc_get_nodeType
,
2916 domdoc_get_parentNode
,
2917 domdoc_get_childNodes
,
2918 domdoc_get_firstChild
,
2919 domdoc_get_lastChild
,
2920 domdoc_get_previousSibling
,
2921 domdoc_get_nextSibling
,
2922 domdoc_get_attributes
,
2923 domdoc_insertBefore
,
2924 domdoc_replaceChild
,
2927 domdoc_hasChildNodes
,
2928 domdoc_get_ownerDocument
,
2930 domdoc_get_nodeTypeString
,
2933 domdoc_get_specified
,
2934 domdoc_get_definition
,
2935 domdoc_get_nodeTypedValue
,
2936 domdoc_put_nodeTypedValue
,
2937 domdoc_get_dataType
,
2938 domdoc_put_dataType
,
2940 domdoc_transformNode
,
2942 domdoc_selectSingleNode
,
2944 domdoc_get_namespaceURI
,
2946 domdoc_get_baseName
,
2947 domdoc_transformNodeToObject
,
2949 domdoc_get_implementation
,
2950 domdoc_get_documentElement
,
2951 domdoc_put_documentElement
,
2952 domdoc_createElement
,
2953 domdoc_createDocumentFragment
,
2954 domdoc_createTextNode
,
2955 domdoc_createComment
,
2956 domdoc_createCDATASection
,
2957 domdoc_createProcessingInstruction
,
2958 domdoc_createAttribute
,
2959 domdoc_createEntityReference
,
2960 domdoc_getElementsByTagName
,
2964 domdoc_get_readyState
,
2965 domdoc_get_parseError
,
2972 domdoc_get_validateOnParse
,
2973 domdoc_put_validateOnParse
,
2974 domdoc_get_resolveExternals
,
2975 domdoc_put_resolveExternals
,
2976 domdoc_get_preserveWhiteSpace
,
2977 domdoc_put_preserveWhiteSpace
,
2978 domdoc_put_onReadyStateChange
,
2979 domdoc_put_onDataAvailable
,
2980 domdoc_put_onTransformNode
,
2981 domdoc_get_namespaces
,
2983 domdoc_putref_schemas
,
2987 domdoc_validateNode
,
2991 /* IConnectionPointContainer */
2992 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
2993 REFIID riid
, void **ppv
)
2995 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
2996 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3
*)This
, riid
, ppv
);
2999 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
3001 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3002 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
3005 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
3007 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3008 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
3011 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
3012 IEnumConnectionPoints
**ppEnum
)
3014 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3015 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3019 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
3020 REFIID riid
, IConnectionPoint
**cp
)
3022 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3023 ConnectionPoint
*iter
;
3025 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), cp
);
3029 for(iter
= This
->cp_list
; iter
; iter
= iter
->next
)
3031 if (IsEqualGUID(iter
->iid
, riid
))
3032 *cp
= (IConnectionPoint
*)&iter
->lpVtblConnectionPoint
;
3037 IConnectionPoint_AddRef(*cp
);
3041 FIXME("unsupported riid %s\n", debugstr_guid(riid
));
3042 return CONNECT_E_NOCONNECTION
;
3046 static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
3048 ConnectionPointContainer_QueryInterface
,
3049 ConnectionPointContainer_AddRef
,
3050 ConnectionPointContainer_Release
,
3051 ConnectionPointContainer_EnumConnectionPoints
,
3052 ConnectionPointContainer_FindConnectionPoint
3055 /* IConnectionPoint */
3056 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
3057 REFIID riid
, void **ppv
)
3059 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3061 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
3065 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
3066 IsEqualGUID(&IID_IConnectionPoint
, riid
))
3073 IConnectionPoint_AddRef(iface
);
3077 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
3078 return E_NOINTERFACE
;
3081 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
3083 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3084 return IConnectionPointContainer_AddRef(This
->container
);
3087 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
3089 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3090 return IConnectionPointContainer_Release(This
->container
);
3093 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*iid
)
3095 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3097 TRACE("(%p)->(%p)\n", This
, iid
);
3099 if (!iid
) return E_POINTER
;
3105 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
3106 IConnectionPointContainer
**container
)
3108 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3110 TRACE("(%p)->(%p)\n", This
, container
);
3112 if (!container
) return E_POINTER
;
3114 *container
= This
->container
;
3115 IConnectionPointContainer_AddRef(*container
);
3119 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
3122 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3123 FIXME("(%p)->(%p %p): stub\n", This
, pUnkSink
, pdwCookie
);
3127 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD cookie
)
3129 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3131 TRACE("(%p)->(%d)\n", This
, cookie
);
3133 if (cookie
== 0 || cookie
> This
->sinks_size
|| !This
->sinks
[cookie
-1].unk
)
3134 return CONNECT_E_NOCONNECTION
;
3136 IUnknown_Release(This
->sinks
[cookie
-1].unk
);
3137 This
->sinks
[cookie
-1].unk
= NULL
;
3142 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
3143 IEnumConnections
**ppEnum
)
3145 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3146 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3150 static const IConnectionPointVtbl ConnectionPointVtbl
=
3152 ConnectionPoint_QueryInterface
,
3153 ConnectionPoint_AddRef
,
3154 ConnectionPoint_Release
,
3155 ConnectionPoint_GetConnectionInterface
,
3156 ConnectionPoint_GetConnectionPointContainer
,
3157 ConnectionPoint_Advise
,
3158 ConnectionPoint_Unadvise
,
3159 ConnectionPoint_EnumConnections
3162 void ConnectionPoint_Init(ConnectionPoint
*cp
, struct domdoc
*doc
, REFIID riid
)
3164 cp
->lpVtblConnectionPoint
= &ConnectionPointVtbl
;
3170 cp
->next
= doc
->cp_list
;
3173 cp
->container
= (IConnectionPointContainer
*)&doc
->lpVtblConnectionPointContainer
;
3176 /* domdoc implementation of IObjectWithSite */
3177 static HRESULT WINAPI
3178 domdoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
3180 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3181 return IXMLDOMDocument3_QueryInterface( (IXMLDOMDocument3
*)This
, riid
, ppvObject
);
3184 static ULONG WINAPI
domdoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
3186 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3187 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
3190 static ULONG WINAPI
domdoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
3192 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3193 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
3196 static HRESULT WINAPI
domdoc_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
3198 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3200 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
3205 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
3208 static HRESULT WINAPI
domdoc_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
3210 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3212 TRACE("(%p)->(%p)\n", iface
, punk
);
3218 IUnknown_Release( This
->site
);
3225 IUnknown_AddRef( punk
);
3228 IUnknown_Release( This
->site
);
3235 static const IObjectWithSiteVtbl domdocObjectSite
=
3237 domdoc_ObjectWithSite_QueryInterface
,
3238 domdoc_ObjectWithSite_AddRef
,
3239 domdoc_ObjectWithSite_Release
,
3240 domdoc_ObjectWithSite_SetSite
,
3241 domdoc_ObjectWithSite_GetSite
3244 static HRESULT WINAPI
domdoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
3246 domdoc
*This
= impl_from_IObjectSafety(iface
);
3247 return IXMLDOMDocument3_QueryInterface( (IXMLDOMDocument3
*)This
, riid
, ppv
);
3250 static ULONG WINAPI
domdoc_Safety_AddRef(IObjectSafety
*iface
)
3252 domdoc
*This
= impl_from_IObjectSafety(iface
);
3253 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
3256 static ULONG WINAPI
domdoc_Safety_Release(IObjectSafety
*iface
)
3258 domdoc
*This
= impl_from_IObjectSafety(iface
);
3259 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
3262 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
3264 static HRESULT WINAPI
domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3265 DWORD
*supported
, DWORD
*enabled
)
3267 domdoc
*This
= impl_from_IObjectSafety(iface
);
3269 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
3271 if(!supported
|| !enabled
) return E_POINTER
;
3273 *supported
= SAFETY_SUPPORTED_OPTIONS
;
3274 *enabled
= This
->safeopt
;
3279 static HRESULT WINAPI
domdoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3280 DWORD mask
, DWORD enabled
)
3282 domdoc
*This
= impl_from_IObjectSafety(iface
);
3283 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
3285 if ((mask
& ~SAFETY_SUPPORTED_OPTIONS
) != 0)
3288 This
->safeopt
= enabled
& mask
& SAFETY_SUPPORTED_OPTIONS
;
3292 #undef SAFETY_SUPPORTED_OPTIONS
3294 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
3295 domdoc_Safety_QueryInterface
,
3296 domdoc_Safety_AddRef
,
3297 domdoc_Safety_Release
,
3298 domdoc_Safety_GetInterfaceSafetyOptions
,
3299 domdoc_Safety_SetInterfaceSafetyOptions
3302 static const tid_t domdoc_iface_tids
[] = {
3304 IXMLDOMDocument_tid
,
3305 IXMLDOMDocument2_tid
,
3308 static dispex_static_data_t domdoc_dispex
= {
3310 IXMLDOMDocument2_tid
,
3315 HRESULT
DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument3
**document
)
3319 doc
= heap_alloc( sizeof (*doc
) );
3321 return E_OUTOFMEMORY
;
3323 doc
->lpVtbl
= &domdoc_vtbl
;
3324 doc
->lpvtblIPersistStreamInit
= &xmldoc_IPersistStreamInit_VTable
;
3325 doc
->lpvtblIObjectWithSite
= &domdocObjectSite
;
3326 doc
->lpvtblIObjectSafety
= &domdocObjectSafetyVtbl
;
3327 doc
->lpvtblISupportErrorInfo
= &support_error_vtbl
;
3328 doc
->lpVtblConnectionPointContainer
= &ConnectionPointContainerVtbl
;
3330 doc
->async
= VARIANT_TRUE
;
3331 doc
->validating
= 0;
3333 doc
->properties
= properties_from_xmlDocPtr(xmldoc
);
3340 doc
->cp_list
= NULL
;
3342 /* events connection points */
3343 ConnectionPoint_Init(&doc
->cp_dispatch
, doc
, &IID_IDispatch
);
3344 ConnectionPoint_Init(&doc
->cp_propnotif
, doc
, &IID_IPropertyNotifySink
);
3345 ConnectionPoint_Init(&doc
->cp_domdocevents
, doc
, &DIID_XMLDOMDocumentEvents
);
3347 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IXMLDOMNode
*)&doc
->lpVtbl
, &domdoc_dispex
);
3349 *document
= (IXMLDOMDocument3
*)&doc
->lpVtbl
;
3351 TRACE("returning iface %p\n", *document
);
3355 HRESULT
DOMDocument_create(const GUID
*clsid
, IUnknown
*pUnkOuter
, void **ppObj
)
3360 TRACE("(%s, %p, %p)\n", debugstr_guid(clsid
), pUnkOuter
, ppObj
);
3362 xmldoc
= xmlNewDoc(NULL
);
3364 return E_OUTOFMEMORY
;
3366 xmldoc
->_private
= create_priv();
3367 priv_from_xmlDocPtr(xmldoc
)->properties
= create_properties(clsid
);
3369 hr
= DOMDocument_create_from_xmldoc(xmldoc
, (IXMLDOMDocument3
**)ppObj
);
3372 free_properties(properties_from_xmlDocPtr(xmldoc
));
3373 heap_free(xmldoc
->_private
);
3381 IUnknown
* create_domdoc( xmlNodePtr document
)
3386 TRACE("(%p)\n", document
);
3388 hr
= DOMDocument_create_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument3
**)&pObj
);
3397 HRESULT
DOMDocument_create(const GUID
*clsid
, IUnknown
*pUnkOuter
, void **ppObj
)
3399 MESSAGE("This program tried to use a DOMDocument object, but\n"
3400 "libxml2 support was not present at compile time.\n");