2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
5 * Copyright 2010-2011 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
30 # include <libxml/parser.h>
31 # include <libxml/xmlerror.h>
32 # include <libxml/xpathInternals.h>
33 # include <libxml/xmlsave.h>
34 # include <libxml/SAX2.h>
35 # include <libxml/parserInternals.h>
51 #include "wine/debug.h"
52 #include "wine/list.h"
54 #include "msxml_private.h"
56 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
60 /* not defined in older versions */
61 #define XML_SAVE_FORMAT 1
62 #define XML_SAVE_NO_DECL 2
63 #define XML_SAVE_NO_EMPTY 4
64 #define XML_SAVE_NO_XHTML 8
65 #define XML_SAVE_XHTML 16
66 #define XML_SAVE_AS_XML 32
67 #define XML_SAVE_AS_HTML 64
69 static const WCHAR PropertySelectionLanguageW
[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
70 static const WCHAR PropertySelectionNamespacesW
[] = {'S','e','l','e','c','t','i','o','n','N','a','m','e','s','p','a','c','e','s',0};
71 static const WCHAR PropertyProhibitDTDW
[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
72 static const WCHAR PropertyNewParserW
[] = {'N','e','w','P','a','r','s','e','r',0};
73 static const WCHAR PropValueXPathW
[] = {'X','P','a','t','h',0};
74 static const WCHAR PropValueXSLPatternW
[] = {'X','S','L','P','a','t','t','e','r','n',0};
75 static const WCHAR PropertyResolveExternalsW
[] = {'R','e','s','o','l','v','e','E','x','t','e','r','n','a','l','s',0};
77 /* Anything that passes the test_get_ownerDocument()
78 * tests can go here (data shared between all instances).
79 * We need to preserve this when reloading a document,
80 * and also need access to it from the libxml backend. */
81 typedef struct _domdoc_properties
{
82 MSXML_VERSION version
;
83 VARIANT_BOOL preserving
;
84 IXMLDOMSchemaCollection2
* schemaCache
;
85 struct list selectNsList
;
86 xmlChar
const* selectNsStr
;
91 typedef struct ConnectionPoint ConnectionPoint
;
92 typedef struct domdoc domdoc
;
94 struct ConnectionPoint
96 IConnectionPoint IConnectionPoint_iface
;
99 ConnectionPoint
*next
;
100 IConnectionPointContainer
*container
;
107 IPropertyNotifySink
*propnotif
;
113 EVENTID_READYSTATECHANGE
= 0,
114 EVENTID_DATAAVAILABLE
,
115 EVENTID_TRANSFORMNODE
,
122 IXMLDOMDocument3 IXMLDOMDocument3_iface
;
123 IPersistStreamInit IPersistStreamInit_iface
;
124 IObjectWithSite IObjectWithSite_iface
;
125 IObjectSafety IObjectSafety_iface
;
126 ISupportErrorInfo ISupportErrorInfo_iface
;
127 IConnectionPointContainer IConnectionPointContainer_iface
;
130 VARIANT_BOOL validating
;
131 VARIANT_BOOL resolving
;
132 domdoc_properties
* properties
;
145 /* connection list */
146 ConnectionPoint
*cp_list
;
147 ConnectionPoint cp_domdocevents
;
148 ConnectionPoint cp_propnotif
;
149 ConnectionPoint cp_dispatch
;
152 IDispatch
*events
[EVENTID_LAST
];
155 static HRESULT
set_doc_event(domdoc
*doc
, eventid_t eid
, const VARIANT
*v
)
163 IUnknown_QueryInterface(V_UNKNOWN(v
), &IID_IDispatch
, (void**)&disp
);
168 disp
= V_DISPATCH(v
);
169 if (disp
) IDispatch_AddRef(disp
);
172 return DISP_E_TYPEMISMATCH
;
175 if (doc
->events
[eid
]) IDispatch_Release(doc
->events
[eid
]);
176 doc
->events
[eid
] = disp
;
181 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
183 return CONTAINING_RECORD(iface
, ConnectionPoint
, IConnectionPoint_iface
);
187 In native windows, the whole lifetime management of XMLDOMNodes is
188 managed automatically using reference counts. Wine emulates that by
189 maintaining a reference count to the document that is increased for
190 each IXMLDOMNode pointer passed out for this document. If all these
191 pointers are gone, the document is unreachable and gets freed, that
192 is, all nodes in the tree of the document get freed.
194 You are able to create nodes that are associated to a document (in
195 fact, in msxml's XMLDOM model, all nodes are associated to a document),
196 but not in the tree of that document, for example using the createFoo
197 functions from IXMLDOMDocument. These nodes do not get cleaned up
198 by libxml, so we have to do it ourselves.
200 To catch these nodes, a list of "orphan nodes" is introduced.
201 It contains pointers to all roots of node trees that are
202 associated with the document without being part of the document
203 tree. All nodes with parent==NULL (except for the document root nodes)
204 should be in the orphan node list of their document. All orphan nodes
205 get freed together with the document itself.
208 typedef struct _xmldoc_priv
{
211 domdoc_properties
* properties
;
214 typedef struct _orphan_entry
{
219 typedef struct _select_ns_entry
{
221 xmlChar
const* prefix
;
227 static inline xmldoc_priv
* priv_from_xmlDocPtr(const xmlDocPtr doc
)
229 return doc
->_private
;
232 static inline domdoc_properties
* properties_from_xmlDocPtr(xmlDocPtr doc
)
234 return priv_from_xmlDocPtr(doc
)->properties
;
237 BOOL
is_xpathmode(const xmlDocPtr doc
)
239 return properties_from_xmlDocPtr(doc
)->XPath
;
242 void set_xpathmode(xmlDocPtr doc
, BOOL xpath
)
244 properties_from_xmlDocPtr(doc
)->XPath
= xpath
;
247 int registerNamespaces(xmlXPathContextPtr ctxt
)
250 const select_ns_entry
* ns
= NULL
;
251 const struct list
* pNsList
= &properties_from_xmlDocPtr(ctxt
->doc
)->selectNsList
;
253 TRACE("(%p)\n", ctxt
);
255 LIST_FOR_EACH_ENTRY( ns
, pNsList
, select_ns_entry
, entry
)
257 xmlXPathRegisterNs(ctxt
, ns
->prefix
, ns
->href
);
264 static inline void clear_selectNsList(struct list
* pNsList
)
266 select_ns_entry
*ns
, *ns2
;
267 LIST_FOR_EACH_ENTRY_SAFE( ns
, ns2
, pNsList
, select_ns_entry
, entry
)
274 static xmldoc_priv
* create_priv(void)
277 priv
= heap_alloc( sizeof (*priv
) );
282 list_init( &priv
->orphans
);
283 priv
->properties
= NULL
;
289 static domdoc_properties
* create_properties(MSXML_VERSION version
)
291 domdoc_properties
*properties
= heap_alloc(sizeof(domdoc_properties
));
293 list_init(&properties
->selectNsList
);
294 properties
->preserving
= VARIANT_FALSE
;
295 properties
->schemaCache
= NULL
;
296 properties
->selectNsStr
= heap_alloc_zero(sizeof(xmlChar
));
297 properties
->selectNsStr_len
= 0;
299 /* properties that are dependent on object versions */
300 properties
->version
= version
;
301 properties
->XPath
= (version
== MSXML4
|| version
== MSXML6
);
306 static domdoc_properties
* copy_properties(domdoc_properties
const* properties
)
308 domdoc_properties
* pcopy
= heap_alloc(sizeof(domdoc_properties
));
309 select_ns_entry
const* ns
= NULL
;
310 select_ns_entry
* new_ns
= NULL
;
311 int len
= (properties
->selectNsStr_len
+1)*sizeof(xmlChar
);
316 pcopy
->version
= properties
->version
;
317 pcopy
->preserving
= properties
->preserving
;
318 pcopy
->schemaCache
= properties
->schemaCache
;
319 if (pcopy
->schemaCache
)
320 IXMLDOMSchemaCollection2_AddRef(pcopy
->schemaCache
);
321 pcopy
->XPath
= properties
->XPath
;
322 pcopy
->selectNsStr_len
= properties
->selectNsStr_len
;
323 list_init( &pcopy
->selectNsList
);
324 pcopy
->selectNsStr
= heap_alloc(len
);
325 memcpy((xmlChar
*)pcopy
->selectNsStr
, properties
->selectNsStr
, len
);
326 offset
= pcopy
->selectNsStr
- properties
->selectNsStr
;
328 LIST_FOR_EACH_ENTRY( ns
, (&properties
->selectNsList
), select_ns_entry
, entry
)
330 new_ns
= heap_alloc(sizeof(select_ns_entry
));
331 memcpy(new_ns
, ns
, sizeof(select_ns_entry
));
332 new_ns
->href
+= offset
;
333 new_ns
->prefix
+= offset
;
334 list_add_tail(&pcopy
->selectNsList
, &new_ns
->entry
);
342 static void free_properties(domdoc_properties
* properties
)
346 if (properties
->schemaCache
)
347 IXMLDOMSchemaCollection2_Release(properties
->schemaCache
);
348 clear_selectNsList(&properties
->selectNsList
);
349 heap_free((xmlChar
*)properties
->selectNsStr
);
350 heap_free(properties
);
354 /* links a "<?xml" node as a first child */
355 void xmldoc_link_xmldecl(xmlDocPtr doc
, xmlNodePtr node
)
358 if (doc
->standalone
!= -1) xmlAddPrevSibling( doc
->children
, node
);
361 /* unlinks a first "<?xml" child if it was created */
362 xmlNodePtr
xmldoc_unlink_xmldecl(xmlDocPtr doc
)
368 if (doc
->standalone
!= -1)
370 node
= doc
->children
;
371 xmlUnlinkNode( node
);
379 BOOL
is_preserving_whitespace(xmlNodePtr node
)
381 domdoc_properties
* properties
= NULL
;
382 /* during parsing the xmlDoc._private stuff is not there */
383 if (priv_from_xmlDocPtr(node
->doc
))
384 properties
= properties_from_xmlDocPtr(node
->doc
);
385 return ((properties
&& properties
->preserving
== VARIANT_TRUE
) ||
386 xmlNodeGetSpacePreserve(node
) == 1);
389 static inline BOOL
strn_isspace(xmlChar
const* str
, int len
)
391 for (; str
&& len
> 0 && *str
; ++str
, --len
)
398 static void sax_characters(void *ctx
, const xmlChar
*ch
, int len
)
400 xmlParserCtxtPtr ctxt
;
403 ctxt
= (xmlParserCtxtPtr
) ctx
;
404 This
= (const domdoc
*) ctxt
->_private
;
408 /* during domdoc_loadXML() the xmlDocPtr->_private data is not available */
409 if (!This
->properties
->preserving
&&
410 !is_preserving_whitespace(ctxt
->node
) &&
411 strn_isspace(ch
, len
))
415 xmlSAX2Characters(ctxt
, ch
, len
);
418 static void LIBXML2_LOG_CALLBACK
sax_error(void* ctx
, char const* msg
, ...)
422 LIBXML2_CALLBACK_ERR(doparse
, msg
, ap
);
426 static void LIBXML2_LOG_CALLBACK
sax_warning(void* ctx
, char const* msg
, ...)
430 LIBXML2_CALLBACK_WARN(doparse
, msg
, ap
);
434 static void sax_serror(void* ctx
, xmlErrorPtr err
)
436 LIBXML2_CALLBACK_SERROR(doparse
, err
);
439 static xmlDocPtr
doparse(domdoc
* This
, char const* ptr
, int len
, xmlCharEncoding encoding
)
441 xmlDocPtr doc
= NULL
;
442 xmlParserCtxtPtr pctx
;
443 static xmlSAXHandler sax_handler
= {
444 xmlSAX2InternalSubset
, /* internalSubset */
445 xmlSAX2IsStandalone
, /* isStandalone */
446 xmlSAX2HasInternalSubset
, /* hasInternalSubset */
447 xmlSAX2HasExternalSubset
, /* hasExternalSubset */
448 xmlSAX2ResolveEntity
, /* resolveEntity */
449 xmlSAX2GetEntity
, /* getEntity */
450 xmlSAX2EntityDecl
, /* entityDecl */
451 xmlSAX2NotationDecl
, /* notationDecl */
452 xmlSAX2AttributeDecl
, /* attributeDecl */
453 xmlSAX2ElementDecl
, /* elementDecl */
454 xmlSAX2UnparsedEntityDecl
, /* unparsedEntityDecl */
455 xmlSAX2SetDocumentLocator
, /* setDocumentLocator */
456 xmlSAX2StartDocument
, /* startDocument */
457 xmlSAX2EndDocument
, /* endDocument */
458 xmlSAX2StartElement
, /* startElement */
459 xmlSAX2EndElement
, /* endElement */
460 xmlSAX2Reference
, /* reference */
461 sax_characters
, /* characters */
462 sax_characters
, /* ignorableWhitespace */
463 xmlSAX2ProcessingInstruction
, /* processingInstruction */
464 xmlSAX2Comment
, /* comment */
465 sax_warning
, /* warning */
466 sax_error
, /* error */
467 sax_error
, /* fatalError */
468 xmlSAX2GetParameterEntity
, /* getParameterEntity */
469 xmlSAX2CDataBlock
, /* cdataBlock */
470 xmlSAX2ExternalSubset
, /* externalSubset */
473 xmlSAX2StartElementNs
, /* startElementNs */
474 xmlSAX2EndElementNs
, /* endElementNs */
475 sax_serror
/* serror */
479 pctx
= xmlCreateMemoryParserCtxt(ptr
, len
);
482 ERR("Failed to create parser context\n");
486 if (pctx
->sax
) xmlFree(pctx
->sax
);
487 pctx
->sax
= &sax_handler
;
488 pctx
->_private
= This
;
491 if (encoding
!= XML_CHAR_ENCODING_NONE
)
492 xmlSwitchEncoding(pctx
, encoding
);
494 xmlParseDocument(pctx
);
496 if (pctx
->wellFormed
)
502 xmlFreeDoc(pctx
->myDoc
);
506 xmlFreeParserCtxt(pctx
);
508 /* TODO: put this in one of the SAX callbacks */
509 /* create first child as a <?xml...?> */
510 if (doc
&& doc
->standalone
!= -1)
514 xmlChar
*xmlbuff
= (xmlChar
*)buff
;
516 node
= xmlNewDocPI( doc
, (xmlChar
*)"xml", NULL
);
518 /* version attribute can't be omitted */
519 sprintf(buff
, "version=\"%s\"", doc
->version
? (char*)doc
->version
: "1.0");
520 xmlNodeAddContent( node
, xmlbuff
);
524 sprintf(buff
, " encoding=\"%s\"", doc
->encoding
);
525 xmlNodeAddContent( node
, xmlbuff
);
528 if (doc
->standalone
!= -2)
530 sprintf(buff
, " standalone=\"%s\"", doc
->standalone
== 0 ? "no" : "yes");
531 xmlNodeAddContent( node
, xmlbuff
);
534 xmldoc_link_xmldecl( doc
, node
);
540 void xmldoc_init(xmlDocPtr doc
, MSXML_VERSION version
)
542 doc
->_private
= create_priv();
543 priv_from_xmlDocPtr(doc
)->properties
= create_properties(version
);
546 LONG
xmldoc_add_ref(xmlDocPtr doc
)
548 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
549 TRACE("(%p)->(%d)\n", doc
, ref
);
553 LONG
xmldoc_release(xmlDocPtr doc
)
555 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
556 LONG ref
= InterlockedDecrement(&priv
->refs
);
557 TRACE("(%p)->(%d)\n", doc
, ref
);
560 orphan_entry
*orphan
, *orphan2
;
561 TRACE("freeing docptr %p\n", doc
);
563 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
565 xmlFreeNode( orphan
->node
);
568 free_properties(priv
->properties
);
569 heap_free(doc
->_private
);
577 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
579 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
582 entry
= heap_alloc( sizeof (*entry
) );
584 return E_OUTOFMEMORY
;
587 list_add_head( &priv
->orphans
, &entry
->entry
);
591 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
593 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
594 orphan_entry
*entry
, *entry2
;
596 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
598 if( entry
->node
== node
)
600 list_remove( &entry
->entry
);
609 static inline xmlDocPtr
get_doc( domdoc
*This
)
611 return (xmlDocPtr
)This
->node
.node
;
614 static HRESULT
attach_xmldoc(domdoc
*This
, xmlDocPtr xml
)
618 priv_from_xmlDocPtr(get_doc(This
))->properties
= NULL
;
619 if (xmldoc_release(get_doc(This
)) != 0)
620 priv_from_xmlDocPtr(get_doc(This
))->properties
=
621 copy_properties(This
->properties
);
624 This
->node
.node
= (xmlNodePtr
) xml
;
628 xmldoc_add_ref(get_doc(This
));
629 priv_from_xmlDocPtr(get_doc(This
))->properties
= This
->properties
;
635 static inline domdoc
*impl_from_IXMLDOMDocument3( IXMLDOMDocument3
*iface
)
637 return CONTAINING_RECORD(iface
, domdoc
, IXMLDOMDocument3_iface
);
640 static inline domdoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
642 return CONTAINING_RECORD(iface
, domdoc
, IPersistStreamInit_iface
);
645 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
647 return CONTAINING_RECORD(iface
, domdoc
, IObjectWithSite_iface
);
650 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
652 return CONTAINING_RECORD(iface
, domdoc
, IObjectSafety_iface
);
655 static inline domdoc
*impl_from_ISupportErrorInfo(ISupportErrorInfo
*iface
)
657 return CONTAINING_RECORD(iface
, domdoc
, ISupportErrorInfo_iface
);
660 static inline domdoc
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
662 return CONTAINING_RECORD(iface
, domdoc
, IConnectionPointContainer_iface
);
665 /************************************************************************
666 * domdoc implementation of IPersistStream.
668 static HRESULT WINAPI
domdoc_IPersistStreamInit_QueryInterface(
669 IPersistStreamInit
*iface
, REFIID riid
, void **ppvObj
)
671 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
672 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObj
);
675 static ULONG WINAPI
domdoc_IPersistStreamInit_AddRef(
676 IPersistStreamInit
*iface
)
678 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
679 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
682 static ULONG WINAPI
domdoc_IPersistStreamInit_Release(
683 IPersistStreamInit
*iface
)
685 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
686 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
689 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetClassID(
690 IPersistStreamInit
*iface
, CLSID
*classid
)
692 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
693 TRACE("(%p)->(%p)\n", This
, classid
);
698 *classid
= *DOMDocument_version(This
->properties
->version
);
703 static HRESULT WINAPI
domdoc_IPersistStreamInit_IsDirty(
704 IPersistStreamInit
*iface
)
706 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
707 FIXME("(%p): stub!\n", This
);
711 static HRESULT WINAPI
domdoc_IPersistStreamInit_Load(
712 IPersistStreamInit
*iface
, LPSTREAM pStm
)
714 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
717 DWORD read
, written
, len
;
720 xmlDocPtr xmldoc
= NULL
;
722 TRACE("(%p)->(%p)\n", This
, pStm
);
727 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
733 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
734 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
735 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
739 ERR("Failed to copy stream\n");
743 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
747 len
= GlobalSize(hglobal
);
748 ptr
= GlobalLock(hglobal
);
750 xmldoc
= doparse(This
, ptr
, len
, XML_CHAR_ENCODING_NONE
);
751 GlobalUnlock(hglobal
);
755 ERR("Failed to parse xml\n");
759 xmldoc
->_private
= create_priv();
761 return attach_xmldoc(This
, xmldoc
);
764 static HRESULT WINAPI
domdoc_IPersistStreamInit_Save(
765 IPersistStreamInit
*iface
, IStream
*stream
, BOOL clr_dirty
)
767 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
771 TRACE("(%p)->(%p %d)\n", This
, stream
, clr_dirty
);
773 hr
= IXMLDOMDocument3_get_xml(&This
->IXMLDOMDocument3_iface
, &xmlString
);
776 DWORD len
= SysStringLen(xmlString
) * sizeof(WCHAR
);
778 hr
= IStream_Write( stream
, xmlString
, len
, NULL
);
779 SysFreeString(xmlString
);
782 TRACE("ret 0x%08x\n", hr
);
787 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetSizeMax(
788 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
790 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
791 TRACE("(%p)->(%p): stub!\n", This
, pcbSize
);
795 static HRESULT WINAPI
domdoc_IPersistStreamInit_InitNew(
796 IPersistStreamInit
*iface
)
798 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
799 TRACE("(%p)\n", This
);
803 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
805 domdoc_IPersistStreamInit_QueryInterface
,
806 domdoc_IPersistStreamInit_AddRef
,
807 domdoc_IPersistStreamInit_Release
,
808 domdoc_IPersistStreamInit_GetClassID
,
809 domdoc_IPersistStreamInit_IsDirty
,
810 domdoc_IPersistStreamInit_Load
,
811 domdoc_IPersistStreamInit_Save
,
812 domdoc_IPersistStreamInit_GetSizeMax
,
813 domdoc_IPersistStreamInit_InitNew
816 /* ISupportErrorInfo interface */
817 static HRESULT WINAPI
support_error_QueryInterface(
818 ISupportErrorInfo
*iface
,
819 REFIID riid
, void** ppvObj
)
821 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
822 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObj
);
825 static ULONG WINAPI
support_error_AddRef(
826 ISupportErrorInfo
*iface
)
828 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
829 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
832 static ULONG WINAPI
support_error_Release(
833 ISupportErrorInfo
*iface
)
835 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
836 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
839 static HRESULT WINAPI
support_error_InterfaceSupportsErrorInfo(
840 ISupportErrorInfo
*iface
,
843 FIXME("(%p)->(%s)\n", iface
, debugstr_guid(riid
));
847 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
849 support_error_QueryInterface
,
850 support_error_AddRef
,
851 support_error_Release
,
852 support_error_InterfaceSupportsErrorInfo
855 /* IXMLDOMDocument2 interface */
856 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument3
*iface
, REFIID riid
, void** ppvObject
)
858 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
860 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppvObject
);
864 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
865 IsEqualGUID( riid
, &IID_IDispatch
) ||
866 IsEqualGUID( riid
, &IID_IXMLDOMNode
) ||
867 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
868 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
)||
869 IsEqualGUID( riid
, &IID_IXMLDOMDocument3
))
873 else if (IsEqualGUID(&IID_IPersistStream
, riid
) ||
874 IsEqualGUID(&IID_IPersistStreamInit
, riid
))
876 *ppvObject
= &This
->IPersistStreamInit_iface
;
878 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
880 *ppvObject
= &This
->IObjectWithSite_iface
;
882 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
884 *ppvObject
= &This
->IObjectSafety_iface
;
886 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
888 *ppvObject
= &This
->ISupportErrorInfo_iface
;
890 else if(node_query_interface(&This
->node
, riid
, ppvObject
))
892 return *ppvObject
? S_OK
: E_NOINTERFACE
;
894 else if (IsEqualGUID( riid
, &IID_IConnectionPointContainer
))
896 *ppvObject
= &This
->IConnectionPointContainer_iface
;
900 TRACE("interface %s not implemented\n", debugstr_guid(riid
));
901 return E_NOINTERFACE
;
904 IUnknown_AddRef((IUnknown
*)*ppvObject
);
910 static ULONG WINAPI
domdoc_AddRef(
911 IXMLDOMDocument3
*iface
)
913 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
914 ULONG ref
= InterlockedIncrement( &This
->ref
);
915 TRACE("(%p)->(%d)\n", This
, ref
);
920 static ULONG WINAPI
domdoc_Release(
921 IXMLDOMDocument3
*iface
)
923 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
924 LONG ref
= InterlockedDecrement( &This
->ref
);
926 TRACE("(%p)->(%d)\n", This
, ref
);
933 detach_bsc(This
->bsc
);
936 IUnknown_Release( This
->site
);
937 destroy_xmlnode(&This
->node
);
939 IStream_Release(This
->stream
);
941 for (eid
= 0; eid
< EVENTID_LAST
; eid
++)
942 if (This
->events
[eid
]) IDispatch_Release(This
->events
[eid
]);
950 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument3
*iface
, UINT
* pctinfo
)
952 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
954 TRACE("(%p)->(%p)\n", This
, pctinfo
);
961 static HRESULT WINAPI
domdoc_GetTypeInfo(
962 IXMLDOMDocument3
*iface
,
963 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
965 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
968 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
970 hr
= get_typeinfo(IXMLDOMDocument2_tid
, ppTInfo
);
975 static HRESULT WINAPI
domdoc_GetIDsOfNames(
976 IXMLDOMDocument3
*iface
,
983 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
987 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
990 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
993 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
996 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
997 ITypeInfo_Release(typeinfo
);
1004 static HRESULT WINAPI
domdoc_Invoke(
1005 IXMLDOMDocument3
*iface
,
1006 DISPID dispIdMember
,
1010 DISPPARAMS
* pDispParams
,
1011 VARIANT
* pVarResult
,
1012 EXCEPINFO
* pExcepInfo
,
1015 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1016 ITypeInfo
*typeinfo
;
1019 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1020 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1022 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
1025 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IXMLDOMDocument3_iface
, dispIdMember
, wFlags
,
1026 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1027 ITypeInfo_Release(typeinfo
);
1034 static HRESULT WINAPI
domdoc_get_nodeName(
1035 IXMLDOMDocument3
*iface
,
1038 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1040 static const WCHAR documentW
[] = {'#','d','o','c','u','m','e','n','t',0};
1042 TRACE("(%p)->(%p)\n", This
, name
);
1044 return return_bstr(documentW
, name
);
1048 static HRESULT WINAPI
domdoc_get_nodeValue(
1049 IXMLDOMDocument3
*iface
,
1052 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1054 TRACE("(%p)->(%p)\n", This
, value
);
1057 return E_INVALIDARG
;
1059 V_VT(value
) = VT_NULL
;
1060 V_BSTR(value
) = NULL
; /* tests show that we should do this */
1065 static HRESULT WINAPI
domdoc_put_nodeValue(
1066 IXMLDOMDocument3
*iface
,
1069 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1070 TRACE("(%p)->(v%d)\n", This
, V_VT(&value
));
1075 static HRESULT WINAPI
domdoc_get_nodeType(
1076 IXMLDOMDocument3
*iface
,
1079 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1081 TRACE("(%p)->(%p)\n", This
, type
);
1083 *type
= NODE_DOCUMENT
;
1088 static HRESULT WINAPI
domdoc_get_parentNode(
1089 IXMLDOMDocument3
*iface
,
1090 IXMLDOMNode
** parent
)
1092 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1094 TRACE("(%p)->(%p)\n", This
, parent
);
1096 return node_get_parent(&This
->node
, parent
);
1100 static HRESULT WINAPI
domdoc_get_childNodes(
1101 IXMLDOMDocument3
*iface
,
1102 IXMLDOMNodeList
** childList
)
1104 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1106 TRACE("(%p)->(%p)\n", This
, childList
);
1108 return node_get_child_nodes(&This
->node
, childList
);
1112 static HRESULT WINAPI
domdoc_get_firstChild(
1113 IXMLDOMDocument3
*iface
,
1114 IXMLDOMNode
** firstChild
)
1116 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1118 TRACE("(%p)->(%p)\n", This
, firstChild
);
1120 return node_get_first_child(&This
->node
, firstChild
);
1124 static HRESULT WINAPI
domdoc_get_lastChild(
1125 IXMLDOMDocument3
*iface
,
1126 IXMLDOMNode
** lastChild
)
1128 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1130 TRACE("(%p)->(%p)\n", This
, lastChild
);
1132 return node_get_last_child(&This
->node
, lastChild
);
1136 static HRESULT WINAPI
domdoc_get_previousSibling(
1137 IXMLDOMDocument3
*iface
,
1138 IXMLDOMNode
** previousSibling
)
1140 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1142 TRACE("(%p)->(%p)\n", This
, previousSibling
);
1144 return return_null_node(previousSibling
);
1148 static HRESULT WINAPI
domdoc_get_nextSibling(
1149 IXMLDOMDocument3
*iface
,
1150 IXMLDOMNode
** nextSibling
)
1152 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1154 TRACE("(%p)->(%p)\n", This
, nextSibling
);
1156 return return_null_node(nextSibling
);
1160 static HRESULT WINAPI
domdoc_get_attributes(
1161 IXMLDOMDocument3
*iface
,
1162 IXMLDOMNamedNodeMap
** attributeMap
)
1164 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1166 TRACE("(%p)->(%p)\n", This
, attributeMap
);
1168 return return_null_ptr((void**)attributeMap
);
1172 static HRESULT WINAPI
domdoc_insertBefore(
1173 IXMLDOMDocument3
*iface
,
1174 IXMLDOMNode
* newChild
,
1176 IXMLDOMNode
** outNewChild
)
1178 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1180 TRACE("(%p)->(%p x%d %p)\n", This
, newChild
, V_VT(&refChild
), outNewChild
);
1182 return node_insert_before(&This
->node
, newChild
, &refChild
, outNewChild
);
1186 static HRESULT WINAPI
domdoc_replaceChild(
1187 IXMLDOMDocument3
*iface
,
1188 IXMLDOMNode
* newChild
,
1189 IXMLDOMNode
* oldChild
,
1190 IXMLDOMNode
** outOldChild
)
1192 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1194 TRACE("(%p)->(%p %p %p)\n", This
, newChild
, oldChild
, outOldChild
);
1196 return node_replace_child(&This
->node
, newChild
, oldChild
, outOldChild
);
1200 static HRESULT WINAPI
domdoc_removeChild(
1201 IXMLDOMDocument3
*iface
,
1203 IXMLDOMNode
**oldChild
)
1205 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1206 TRACE("(%p)->(%p %p)\n", This
, child
, oldChild
);
1207 return node_remove_child(&This
->node
, child
, oldChild
);
1211 static HRESULT WINAPI
domdoc_appendChild(
1212 IXMLDOMDocument3
*iface
,
1214 IXMLDOMNode
**outChild
)
1216 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1217 TRACE("(%p)->(%p %p)\n", This
, child
, outChild
);
1218 return node_append_child(&This
->node
, child
, outChild
);
1222 static HRESULT WINAPI
domdoc_hasChildNodes(
1223 IXMLDOMDocument3
*iface
,
1226 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1227 TRACE("(%p)->(%p)\n", This
, ret
);
1228 return node_has_childnodes(&This
->node
, ret
);
1232 static HRESULT WINAPI
domdoc_get_ownerDocument(
1233 IXMLDOMDocument3
*iface
,
1234 IXMLDOMDocument
**doc
)
1236 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1237 TRACE("(%p)->(%p)\n", This
, doc
);
1238 return node_get_owner_doc(&This
->node
, doc
);
1242 static HRESULT WINAPI
domdoc_cloneNode(
1243 IXMLDOMDocument3
*iface
,
1245 IXMLDOMNode
** outNode
)
1247 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1248 TRACE("(%p)->(%d %p)\n", This
, deep
, outNode
);
1249 return node_clone( &This
->node
, deep
, outNode
);
1253 static HRESULT WINAPI
domdoc_get_nodeTypeString(
1254 IXMLDOMDocument3
*iface
,
1257 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1258 static const WCHAR documentW
[] = {'d','o','c','u','m','e','n','t',0};
1260 TRACE("(%p)->(%p)\n", This
, p
);
1262 return return_bstr(documentW
, p
);
1266 static HRESULT WINAPI
domdoc_get_text(
1267 IXMLDOMDocument3
*iface
,
1270 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1271 TRACE("(%p)->(%p)\n", This
, p
);
1272 return node_get_text(&This
->node
, p
);
1276 static HRESULT WINAPI
domdoc_put_text(
1277 IXMLDOMDocument3
*iface
,
1280 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1281 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
1286 static HRESULT WINAPI
domdoc_get_specified(
1287 IXMLDOMDocument3
*iface
,
1288 VARIANT_BOOL
* isSpecified
)
1290 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1291 FIXME("(%p)->(%p) stub!\n", This
, isSpecified
);
1292 *isSpecified
= VARIANT_TRUE
;
1297 static HRESULT WINAPI
domdoc_get_definition(
1298 IXMLDOMDocument3
*iface
,
1299 IXMLDOMNode
** definitionNode
)
1301 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1302 FIXME("(%p)->(%p)\n", This
, definitionNode
);
1307 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
1308 IXMLDOMDocument3
*iface
,
1311 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1312 TRACE("(%p)->(%p)\n", This
, v
);
1313 return return_null_var(v
);
1316 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
1317 IXMLDOMDocument3
*iface
,
1318 VARIANT typedValue
)
1320 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1321 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&typedValue
));
1326 static HRESULT WINAPI
domdoc_get_dataType(
1327 IXMLDOMDocument3
*iface
,
1330 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1331 TRACE("(%p)->(%p)\n", This
, typename
);
1332 return return_null_var( typename
);
1336 static HRESULT WINAPI
domdoc_put_dataType(
1337 IXMLDOMDocument3
*iface
,
1340 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1342 FIXME("(%p)->(%s)\n", This
, debugstr_w(dataTypeName
));
1345 return E_INVALIDARG
;
1350 static int XMLCALL
domdoc_get_xml_writecallback(void *ctx
, const char *data
, int len
)
1352 return xmlBufferAdd((xmlBufferPtr
)ctx
, (xmlChar
*)data
, len
) == 0 ? len
: 0;
1355 static HRESULT WINAPI
domdoc_get_xml(
1356 IXMLDOMDocument3
*iface
,
1359 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1360 xmlSaveCtxtPtr ctxt
;
1365 TRACE("(%p)->(%p)\n", This
, p
);
1368 return E_INVALIDARG
;
1372 buf
= xmlBufferCreate();
1374 return E_OUTOFMEMORY
;
1376 options
= XML_SAVE_FORMAT
| XML_SAVE_NO_DECL
;
1377 ctxt
= xmlSaveToIO(domdoc_get_xml_writecallback
, NULL
, buf
, "UTF-8", options
);
1382 return E_OUTOFMEMORY
;
1385 ret
= xmlSaveDoc(ctxt
, get_doc(This
));
1386 /* flushes on close */
1389 TRACE("%ld, len=%d\n", ret
, xmlBufferLength(buf
));
1390 if(ret
!= -1 && xmlBufferLength(buf
) > 0)
1394 content
= bstr_from_xmlChar(xmlBufferContent(buf
));
1395 content
= EnsureCorrectEOL(content
);
1401 *p
= SysAllocStringLen(NULL
, 0);
1406 return *p
? S_OK
: E_OUTOFMEMORY
;
1410 static HRESULT WINAPI
domdoc_transformNode(
1411 IXMLDOMDocument3
*iface
,
1415 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1416 TRACE("(%p)->(%p %p)\n", This
, node
, p
);
1417 return node_transform_node(&This
->node
, node
, p
);
1421 static HRESULT WINAPI
domdoc_selectNodes(
1422 IXMLDOMDocument3
*iface
,
1424 IXMLDOMNodeList
**outList
)
1426 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1427 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outList
);
1428 return node_select_nodes(&This
->node
, p
, outList
);
1432 static HRESULT WINAPI
domdoc_selectSingleNode(
1433 IXMLDOMDocument3
*iface
,
1435 IXMLDOMNode
**outNode
)
1437 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1438 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outNode
);
1439 return node_select_singlenode(&This
->node
, p
, outNode
);
1443 static HRESULT WINAPI
domdoc_get_parsed(
1444 IXMLDOMDocument3
*iface
,
1445 VARIANT_BOOL
* isParsed
)
1447 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1448 FIXME("(%p)->(%p) stub!\n", This
, isParsed
);
1449 *isParsed
= VARIANT_TRUE
;
1454 static HRESULT WINAPI
domdoc_get_namespaceURI(
1455 IXMLDOMDocument3
*iface
,
1456 BSTR
* namespaceURI
)
1458 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1459 TRACE("(%p)->(%p)\n", This
, namespaceURI
);
1460 return node_get_namespaceURI(&This
->node
, namespaceURI
);
1464 static HRESULT WINAPI
domdoc_get_prefix(
1465 IXMLDOMDocument3
*iface
,
1468 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1469 TRACE("(%p)->(%p)\n", This
, prefix
);
1470 return return_null_bstr( prefix
);
1474 static HRESULT WINAPI
domdoc_get_baseName(
1475 IXMLDOMDocument3
*iface
,
1478 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1479 TRACE("(%p)->(%p)\n", This
, name
);
1480 return return_null_bstr( name
);
1484 static HRESULT WINAPI
domdoc_transformNodeToObject(
1485 IXMLDOMDocument3
*iface
,
1486 IXMLDOMNode
* stylesheet
,
1487 VARIANT outputObject
)
1489 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1490 FIXME("(%p)->(%p %s)\n", This
, stylesheet
, debugstr_variant(&outputObject
));
1495 static HRESULT WINAPI
domdoc_get_doctype(
1496 IXMLDOMDocument3
*iface
,
1497 IXMLDOMDocumentType
** doctype
)
1499 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1504 TRACE("(%p)->(%p)\n", This
, doctype
);
1506 if (!doctype
) return E_INVALIDARG
;
1510 dtd
= xmlGetIntSubset(get_doc(This
));
1511 if (!dtd
) return S_FALSE
;
1513 node
= create_node((xmlNodePtr
)dtd
);
1514 if (!node
) return S_FALSE
;
1516 hr
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentType
, (void**)doctype
);
1517 IXMLDOMNode_Release(node
);
1523 static HRESULT WINAPI
domdoc_get_implementation(
1524 IXMLDOMDocument3
*iface
,
1525 IXMLDOMImplementation
** impl
)
1527 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1529 TRACE("(%p)->(%p)\n", This
, impl
);
1532 return E_INVALIDARG
;
1534 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
1539 static HRESULT WINAPI
domdoc_get_documentElement(
1540 IXMLDOMDocument3
*iface
,
1541 IXMLDOMElement
** DOMElement
)
1543 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1544 IXMLDOMNode
*element_node
;
1548 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1551 return E_INVALIDARG
;
1555 root
= xmlDocGetRootElement( get_doc(This
) );
1559 element_node
= create_node( root
);
1560 if(!element_node
) return S_FALSE
;
1562 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (void**)DOMElement
);
1563 IXMLDOMNode_Release(element_node
);
1569 static HRESULT WINAPI
domdoc_put_documentElement(
1570 IXMLDOMDocument3
*iface
,
1571 IXMLDOMElement
* DOMElement
)
1573 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1574 IXMLDOMNode
*elementNode
;
1579 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1581 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1585 xmlNode
= get_node_obj( elementNode
);
1586 if(!xmlNode
) return E_FAIL
;
1588 if(!xmlNode
->node
->parent
)
1589 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1590 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1592 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1593 IXMLDOMNode_Release( elementNode
);
1596 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1602 static HRESULT WINAPI
domdoc_createElement(
1603 IXMLDOMDocument3
*iface
,
1605 IXMLDOMElement
** element
)
1607 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1612 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagname
), element
);
1614 if (!element
|| !tagname
) return E_INVALIDARG
;
1616 V_VT(&type
) = VT_I1
;
1617 V_I1(&type
) = NODE_ELEMENT
;
1619 hr
= IXMLDOMDocument3_createNode(iface
, type
, tagname
, NULL
, &node
);
1622 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMElement
, (void**)element
);
1623 IXMLDOMNode_Release(node
);
1630 static HRESULT WINAPI
domdoc_createDocumentFragment(
1631 IXMLDOMDocument3
*iface
,
1632 IXMLDOMDocumentFragment
** frag
)
1634 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1639 TRACE("(%p)->(%p)\n", This
, frag
);
1641 if (!frag
) return E_INVALIDARG
;
1645 V_VT(&type
) = VT_I1
;
1646 V_I1(&type
) = NODE_DOCUMENT_FRAGMENT
;
1648 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1651 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentFragment
, (void**)frag
);
1652 IXMLDOMNode_Release(node
);
1659 static HRESULT WINAPI
domdoc_createTextNode(
1660 IXMLDOMDocument3
*iface
,
1662 IXMLDOMText
** text
)
1664 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1669 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), text
);
1671 if (!text
) return E_INVALIDARG
;
1675 V_VT(&type
) = VT_I1
;
1676 V_I1(&type
) = NODE_TEXT
;
1678 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1681 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)text
);
1682 IXMLDOMNode_Release(node
);
1683 hr
= IXMLDOMText_put_data(*text
, data
);
1690 static HRESULT WINAPI
domdoc_createComment(
1691 IXMLDOMDocument3
*iface
,
1693 IXMLDOMComment
** comment
)
1695 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1700 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), comment
);
1702 if (!comment
) return E_INVALIDARG
;
1706 V_VT(&type
) = VT_I1
;
1707 V_I1(&type
) = NODE_COMMENT
;
1709 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1712 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)comment
);
1713 IXMLDOMNode_Release(node
);
1714 hr
= IXMLDOMComment_put_data(*comment
, data
);
1721 static HRESULT WINAPI
domdoc_createCDATASection(
1722 IXMLDOMDocument3
*iface
,
1724 IXMLDOMCDATASection
** cdata
)
1726 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1731 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), cdata
);
1733 if (!cdata
) return E_INVALIDARG
;
1737 V_VT(&type
) = VT_I1
;
1738 V_I1(&type
) = NODE_CDATA_SECTION
;
1740 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1743 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)cdata
);
1744 IXMLDOMNode_Release(node
);
1745 hr
= IXMLDOMCDATASection_put_data(*cdata
, data
);
1752 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1753 IXMLDOMDocument3
*iface
,
1756 IXMLDOMProcessingInstruction
** pi
)
1758 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1763 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(target
), debugstr_w(data
), pi
);
1765 if (!pi
) return E_INVALIDARG
;
1769 V_VT(&type
) = VT_I1
;
1770 V_I1(&type
) = NODE_PROCESSING_INSTRUCTION
;
1772 hr
= IXMLDOMDocument3_createNode(iface
, type
, target
, NULL
, &node
);
1777 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1778 node_obj
= get_node_obj(node
);
1779 hr
= node_set_content(node_obj
, data
);
1781 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMProcessingInstruction
, (void**)pi
);
1782 IXMLDOMNode_Release(node
);
1789 static HRESULT WINAPI
domdoc_createAttribute(
1790 IXMLDOMDocument3
*iface
,
1792 IXMLDOMAttribute
** attribute
)
1794 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1799 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), attribute
);
1801 if (!attribute
|| !name
) return E_INVALIDARG
;
1803 V_VT(&type
) = VT_I1
;
1804 V_I1(&type
) = NODE_ATTRIBUTE
;
1806 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1809 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMAttribute
, (void**)attribute
);
1810 IXMLDOMNode_Release(node
);
1817 static HRESULT WINAPI
domdoc_createEntityReference(
1818 IXMLDOMDocument3
*iface
,
1820 IXMLDOMEntityReference
** entityref
)
1822 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1827 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), entityref
);
1829 if (!entityref
) return E_INVALIDARG
;
1833 V_VT(&type
) = VT_I1
;
1834 V_I1(&type
) = NODE_ENTITY_REFERENCE
;
1836 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1839 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMEntityReference
, (void**)entityref
);
1840 IXMLDOMNode_Release(node
);
1846 xmlChar
* tagName_to_XPath(const BSTR tagName
)
1848 xmlChar
*query
, *tmp
;
1849 static const xmlChar mod_pre
[] = "*[local-name()='";
1850 static const xmlChar mod_post
[] = "']";
1851 static const xmlChar prefix
[] = "descendant::";
1852 const WCHAR
*tokBegin
, *tokEnd
;
1855 query
= xmlStrdup(prefix
);
1858 while (tokBegin
&& *tokBegin
)
1863 query
= xmlStrcat(query
, BAD_CAST
"/");
1867 query
= xmlStrcat(query
, BAD_CAST
"*");
1871 query
= xmlStrcat(query
, mod_pre
);
1873 while (*tokEnd
&& *tokEnd
!= '/')
1875 len
= WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, NULL
, 0, NULL
, NULL
);
1876 tmp
= xmlMalloc(len
);
1877 WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, (char*)tmp
, len
, NULL
, NULL
);
1878 query
= xmlStrncat(query
, tmp
, len
);
1881 query
= xmlStrcat(query
, mod_post
);
1888 static HRESULT WINAPI
domdoc_getElementsByTagName(
1889 IXMLDOMDocument3
*iface
,
1891 IXMLDOMNodeList
** resultList
)
1893 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1898 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(tagName
), resultList
);
1900 if (!tagName
|| !resultList
) return E_INVALIDARG
;
1902 XPath
= This
->properties
->XPath
;
1903 This
->properties
->XPath
= TRUE
;
1904 query
= tagName_to_XPath(tagName
);
1905 hr
= create_selection((xmlNodePtr
)get_doc(This
), query
, resultList
);
1907 This
->properties
->XPath
= XPath
;
1912 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1918 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1920 return E_INVALIDARG
;
1927 static HRESULT WINAPI
domdoc_createNode(
1928 IXMLDOMDocument3
*iface
,
1932 IXMLDOMNode
** node
)
1934 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1935 DOMNodeType node_type
;
1937 xmlChar
*xml_name
, *href
;
1940 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1942 if(!node
) return E_INVALIDARG
;
1944 hr
= get_node_type(Type
, &node_type
);
1945 if(FAILED(hr
)) return hr
;
1947 if(namespaceURI
&& namespaceURI
[0] && node_type
!= NODE_ELEMENT
)
1948 FIXME("nodes with namespaces currently not supported.\n");
1950 TRACE("node_type %d\n", node_type
);
1952 /* exit earlier for types that need name */
1956 case NODE_ATTRIBUTE
:
1957 case NODE_ENTITY_REFERENCE
:
1958 case NODE_PROCESSING_INSTRUCTION
:
1959 if (!name
|| *name
== 0) return E_FAIL
;
1965 xml_name
= xmlchar_from_wchar(name
);
1966 /* prevent empty href to be allocated */
1967 href
= namespaceURI
? xmlchar_from_wchar(namespaceURI
) : NULL
;
1973 xmlChar
*local
, *prefix
;
1975 local
= xmlSplitQName2(xml_name
, &prefix
);
1977 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, local
? local
: xml_name
, NULL
);
1979 /* allow to create default namespace xmlns= */
1980 if (local
|| (href
&& *href
))
1982 xmlNsPtr ns
= xmlNewNs(xmlnode
, href
, prefix
);
1983 xmlSetNs(xmlnode
, ns
);
1991 case NODE_ATTRIBUTE
:
1992 xmlnode
= (xmlNodePtr
)xmlNewDocProp(get_doc(This
), xml_name
, NULL
);
1995 xmlnode
= (xmlNodePtr
)xmlNewDocText(get_doc(This
), NULL
);
1997 case NODE_CDATA_SECTION
:
1998 xmlnode
= xmlNewCDataBlock(get_doc(This
), NULL
, 0);
2000 case NODE_ENTITY_REFERENCE
:
2001 xmlnode
= xmlNewReference(get_doc(This
), xml_name
);
2003 case NODE_PROCESSING_INSTRUCTION
:
2004 #ifdef HAVE_XMLNEWDOCPI
2005 xmlnode
= xmlNewDocPI(get_doc(This
), xml_name
, NULL
);
2007 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
2012 xmlnode
= xmlNewDocComment(get_doc(This
), NULL
);
2014 case NODE_DOCUMENT_FRAGMENT
:
2015 xmlnode
= xmlNewDocFragment(get_doc(This
));
2017 /* unsupported types */
2019 case NODE_DOCUMENT_TYPE
:
2022 heap_free(xml_name
);
2023 return E_INVALIDARG
;
2025 FIXME("unhandled node type %d\n", node_type
);
2030 *node
= create_node(xmlnode
);
2031 heap_free(xml_name
);
2036 TRACE("created node (%d, %p, %p)\n", node_type
, *node
, xmlnode
);
2037 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
2044 static HRESULT WINAPI
domdoc_nodeFromID(
2045 IXMLDOMDocument3
*iface
,
2047 IXMLDOMNode
** node
)
2049 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2050 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(idString
), node
);
2054 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2059 xmldoc
= doparse(This
, ptr
, len
, XML_CHAR_ENCODING_NONE
);
2061 xmldoc
->_private
= create_priv();
2062 return attach_xmldoc(This
, xmldoc
);
2068 static HRESULT
doread( domdoc
*This
, LPWSTR filename
)
2073 hr
= bind_url(filename
, domdoc_onDataAvailable
, This
, &bsc
);
2078 hr
= detach_bsc(This
->bsc
);
2087 static HRESULT WINAPI
domdoc_load(
2088 IXMLDOMDocument3
*iface
,
2090 VARIANT_BOOL
* isSuccessful
)
2092 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2093 LPWSTR filename
= NULL
;
2094 HRESULT hr
= S_FALSE
;
2095 IXMLDOMDocument3
*pNewDoc
= NULL
;
2096 IStream
*pStream
= NULL
;
2099 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&source
));
2103 *isSuccessful
= VARIANT_FALSE
;
2105 assert( &This
->node
);
2107 switch( V_VT(&source
) )
2110 filename
= V_BSTR(&source
);
2112 case VT_BSTR
|VT_BYREF
:
2113 if (!V_BSTRREF(&source
)) return E_INVALIDARG
;
2114 filename
= *V_BSTRREF(&source
);
2116 case VT_ARRAY
|VT_UI1
:
2118 SAFEARRAY
*psa
= V_ARRAY(&source
);
2121 UINT dim
= SafeArrayGetDim(psa
);
2126 ERR("SAFEARRAY == NULL\n");
2127 hr
= This
->error
= E_INVALIDARG
;
2130 /* Only takes UTF-8 strings.
2131 * NOT NULL-terminated. */
2132 SafeArrayAccessData(psa
, (void**)&str
);
2133 SafeArrayGetUBound(psa
, 1, &len
);
2135 if ((xmldoc
= doparse(This
, str
, ++len
, XML_CHAR_ENCODING_UTF8
)))
2137 hr
= This
->error
= S_OK
;
2138 *isSuccessful
= VARIANT_TRUE
;
2139 TRACE("parsed document %p\n", xmldoc
);
2143 This
->error
= E_FAIL
;
2144 TRACE("failed to parse document\n");
2147 SafeArrayUnaccessData(psa
);
2151 xmldoc
->_private
= create_priv();
2152 return attach_xmldoc(This
, xmldoc
);
2156 FIXME("unhandled SAFEARRAY dim: %d\n", dim
);
2157 hr
= This
->error
= E_NOTIMPL
;
2162 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IXMLDOMDocument3
, (void**)&pNewDoc
);
2167 domdoc
*newDoc
= impl_from_IXMLDOMDocument3( pNewDoc
);
2168 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
2169 hr
= attach_xmldoc(This
, xmldoc
);
2172 *isSuccessful
= VARIANT_TRUE
;
2177 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IStream
, (void**)&pStream
);
2180 IPersistStream
*pDocStream
;
2181 hr
= IUnknown_QueryInterface(iface
, &IID_IPersistStream
, (void**)&pDocStream
);
2184 hr
= IPersistStream_Load(pDocStream
, pStream
);
2185 IStream_Release(pStream
);
2188 *isSuccessful
= VARIANT_TRUE
;
2190 TRACE("Using IStream to load Document\n");
2195 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr
);
2200 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr
);
2205 /* ISequentialStream */
2206 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr
, pNewDoc
, V_UNKNOWN(&source
)->lpVtbl
);
2210 FIXME("VT type not supported (%d)\n", V_VT(&source
));
2215 hr
= doread( This
, filename
);
2218 This
->error
= E_FAIL
;
2221 hr
= This
->error
= S_OK
;
2222 *isSuccessful
= VARIANT_TRUE
;
2226 if(!filename
|| FAILED(hr
)) {
2227 xmldoc
= xmlNewDoc(NULL
);
2228 xmldoc
->_private
= create_priv();
2229 hr
= attach_xmldoc(This
, xmldoc
);
2234 TRACE("ret (%d)\n", hr
);
2240 static HRESULT WINAPI
domdoc_get_readyState(
2241 IXMLDOMDocument3
*iface
,
2244 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2245 FIXME("stub! (%p)->(%p)\n", This
, value
);
2248 return E_INVALIDARG
;
2250 *value
= READYSTATE_COMPLETE
;
2255 static HRESULT WINAPI
domdoc_get_parseError(
2256 IXMLDOMDocument3
*iface
,
2257 IXMLDOMParseError
** errorObj
)
2259 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2260 static const WCHAR err
[] = {'e','r','r','o','r',0};
2261 BSTR error_string
= NULL
;
2263 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
2266 error_string
= SysAllocString(err
);
2268 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
2269 if(!*errorObj
) return E_OUTOFMEMORY
;
2274 static HRESULT WINAPI
domdoc_get_url(
2275 IXMLDOMDocument3
*iface
,
2278 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2279 FIXME("(%p)->(%p)\n", This
, urlString
);
2284 static HRESULT WINAPI
domdoc_get_async(
2285 IXMLDOMDocument3
*iface
,
2286 VARIANT_BOOL
* isAsync
)
2288 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2290 TRACE("(%p)->(%p: %d)\n", This
, isAsync
, This
->async
);
2291 *isAsync
= This
->async
;
2296 static HRESULT WINAPI
domdoc_put_async(
2297 IXMLDOMDocument3
*iface
,
2298 VARIANT_BOOL isAsync
)
2300 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2302 TRACE("(%p)->(%d)\n", This
, isAsync
);
2303 This
->async
= isAsync
;
2308 static HRESULT WINAPI
domdoc_abort(
2309 IXMLDOMDocument3
*iface
)
2311 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2312 FIXME("%p\n", This
);
2317 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2318 static HRESULT WINAPI
domdoc_loadXML(
2319 IXMLDOMDocument3
*iface
,
2321 VARIANT_BOOL
* isSuccessful
)
2323 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2324 xmlDocPtr xmldoc
= NULL
;
2325 HRESULT hr
= S_FALSE
, hr2
;
2327 TRACE("(%p)->(%s %p)\n", This
, debugstr_w( bstrXML
), isSuccessful
);
2329 assert ( &This
->node
);
2333 *isSuccessful
= VARIANT_FALSE
;
2337 xmldoc
= doparse(This
, (LPCSTR
)bstrXML
, lstrlenW(bstrXML
) * sizeof(*bstrXML
), XML_CHAR_ENCODING_UTF16LE
);
2340 This
->error
= E_FAIL
;
2341 TRACE("failed to parse document\n");
2345 hr
= This
->error
= S_OK
;
2346 *isSuccessful
= VARIANT_TRUE
;
2347 TRACE("parsed document %p\n", xmldoc
);
2352 xmldoc
= xmlNewDoc(NULL
);
2354 xmldoc
->_private
= create_priv();
2356 hr2
= attach_xmldoc(This
, xmldoc
);
2363 static int XMLCALL
domdoc_save_writecallback(void *ctx
, const char *buffer
, int len
)
2367 if(!WriteFile(ctx
, buffer
, len
, &written
, NULL
))
2369 WARN("write error\n");
2376 static int XMLCALL
domdoc_save_closecallback(void *ctx
)
2378 return CloseHandle(ctx
) ? 0 : -1;
2381 static int XMLCALL
domdoc_stream_save_writecallback(void *ctx
, const char *buffer
, int len
)
2386 hr
= IStream_Write((IStream
*)ctx
, buffer
, len
, &written
);
2389 WARN("stream write error: 0x%08x\n", hr
);
2396 static int XMLCALL
domdoc_stream_save_closecallback(void *ctx
)
2398 IStream_Release((IStream
*)ctx
);
2402 static HRESULT WINAPI
domdoc_save(
2403 IXMLDOMDocument3
*iface
,
2404 VARIANT destination
)
2406 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2407 xmlSaveCtxtPtr ctx
= NULL
;
2411 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&destination
));
2413 switch (V_VT(&destination
))
2417 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
2418 IXMLDOMDocument2
*document
;
2421 ret
= IUnknown_QueryInterface(pUnk
, &IID_IXMLDOMDocument3
, (void**)&document
);
2424 VARIANT_BOOL success
;
2427 ret
= IXMLDOMDocument3_get_xml(iface
, &xml
);
2430 ret
= IXMLDOMDocument3_loadXML(document
, xml
, &success
);
2434 IXMLDOMDocument3_Release(document
);
2438 ret
= IUnknown_QueryInterface(pUnk
, &IID_IStream
, (void**)&stream
);
2441 ctx
= xmlSaveToIO(domdoc_stream_save_writecallback
,
2442 domdoc_stream_save_closecallback
, stream
, NULL
, XML_SAVE_NO_DECL
);
2446 IStream_Release(stream
);
2454 case VT_BSTR
| VT_BYREF
:
2456 /* save with file path */
2457 HANDLE handle
= CreateFileW( (V_VT(&destination
) & VT_BYREF
)? *V_BSTRREF(&destination
) : V_BSTR(&destination
),
2458 GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2459 if( handle
== INVALID_HANDLE_VALUE
)
2461 WARN("failed to create file\n");
2465 /* disable top XML declaration */
2466 ctx
= xmlSaveToIO(domdoc_save_writecallback
, domdoc_save_closecallback
,
2467 handle
, NULL
, XML_SAVE_NO_DECL
);
2470 CloseHandle(handle
);
2477 FIXME("Unhandled VARIANT: %s\n", debugstr_variant(&destination
));
2481 xmldecl
= xmldoc_unlink_xmldecl(get_doc(This
));
2482 if (xmlSaveDoc(ctx
, get_doc(This
)) == -1) ret
= S_FALSE
;
2483 xmldoc_link_xmldecl(get_doc(This
), xmldecl
);
2485 /* will release resources through close callback */
2491 static HRESULT WINAPI
domdoc_get_validateOnParse(
2492 IXMLDOMDocument3
*iface
,
2493 VARIANT_BOOL
* isValidating
)
2495 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2496 TRACE("(%p)->(%p: %d)\n", This
, isValidating
, This
->validating
);
2497 *isValidating
= This
->validating
;
2502 static HRESULT WINAPI
domdoc_put_validateOnParse(
2503 IXMLDOMDocument3
*iface
,
2504 VARIANT_BOOL isValidating
)
2506 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2507 TRACE("(%p)->(%d)\n", This
, isValidating
);
2508 This
->validating
= isValidating
;
2513 static HRESULT WINAPI
domdoc_get_resolveExternals(
2514 IXMLDOMDocument3
*iface
,
2515 VARIANT_BOOL
* isResolving
)
2517 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2518 TRACE("(%p)->(%p: %d)\n", This
, isResolving
, This
->resolving
);
2519 *isResolving
= This
->resolving
;
2524 static HRESULT WINAPI
domdoc_put_resolveExternals(
2525 IXMLDOMDocument3
*iface
,
2526 VARIANT_BOOL isResolving
)
2528 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2529 TRACE("(%p)->(%d)\n", This
, isResolving
);
2530 This
->resolving
= isResolving
;
2535 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
2536 IXMLDOMDocument3
*iface
,
2537 VARIANT_BOOL
* isPreserving
)
2539 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2540 TRACE("(%p)->(%p: %d)\n", This
, isPreserving
, This
->properties
->preserving
);
2541 *isPreserving
= This
->properties
->preserving
;
2546 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
2547 IXMLDOMDocument3
*iface
,
2548 VARIANT_BOOL isPreserving
)
2550 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2551 TRACE("(%p)->(%d)\n", This
, isPreserving
);
2552 This
->properties
->preserving
= isPreserving
;
2557 static HRESULT WINAPI
domdoc_put_onreadystatechange(
2558 IXMLDOMDocument3
*iface
,
2561 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2563 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&event
));
2564 return set_doc_event(This
, EVENTID_READYSTATECHANGE
, &event
);
2568 static HRESULT WINAPI
domdoc_put_onDataAvailable(
2569 IXMLDOMDocument3
*iface
,
2570 VARIANT onDataAvailableSink
)
2572 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2573 FIXME("%p\n", This
);
2577 static HRESULT WINAPI
domdoc_put_onTransformNode(
2578 IXMLDOMDocument3
*iface
,
2579 VARIANT onTransformNodeSink
)
2581 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2582 FIXME("%p\n", This
);
2586 static HRESULT WINAPI
domdoc_get_namespaces(
2587 IXMLDOMDocument3
* iface
,
2588 IXMLDOMSchemaCollection
** schemaCollection
)
2590 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2591 FIXME("(%p)->(%p)\n", This
, schemaCollection
);
2595 static HRESULT WINAPI
domdoc_get_schemas(
2596 IXMLDOMDocument3
* iface
,
2599 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2600 HRESULT hr
= S_FALSE
;
2601 IXMLDOMSchemaCollection2
* cur_schema
= This
->properties
->schemaCache
;
2603 TRACE("(%p)->(%p)\n", This
, var1
);
2605 VariantInit(var1
); /* Test shows we don't call VariantClear here */
2606 V_VT(var1
) = VT_NULL
;
2610 hr
= IXMLDOMSchemaCollection2_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(var1
));
2612 V_VT(var1
) = VT_DISPATCH
;
2617 static HRESULT WINAPI
domdoc_putref_schemas(
2618 IXMLDOMDocument3
* iface
,
2621 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2622 HRESULT hr
= E_FAIL
;
2623 IXMLDOMSchemaCollection2
* new_schema
= NULL
;
2625 FIXME("(%p): semi-stub\n", This
);
2629 hr
= IUnknown_QueryInterface(V_UNKNOWN(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2633 hr
= IDispatch_QueryInterface(V_DISPATCH(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2642 WARN("Can't get schema from vt %x\n", V_VT(&var1
));
2647 IXMLDOMSchemaCollection2
* old_schema
= InterlockedExchangePointer((void**)&This
->properties
->schemaCache
, new_schema
);
2648 if(old_schema
) IXMLDOMSchemaCollection2_Release(old_schema
);
2654 static inline BOOL
is_wellformed(xmlDocPtr doc
)
2656 #ifdef HAVE_XMLDOC_PROPERTIES
2657 return doc
->properties
& XML_DOC_WELLFORMED
;
2659 /* Not a full check, but catches the worst violations */
2663 for (child
= doc
->children
; child
!= NULL
; child
= child
->next
)
2665 switch (child
->type
)
2667 case XML_ELEMENT_NODE
:
2672 case XML_CDATA_SECTION_NODE
:
2684 static void LIBXML2_LOG_CALLBACK
validate_error(void* ctx
, char const* msg
, ...)
2688 LIBXML2_CALLBACK_ERR(domdoc_validateNode
, msg
, ap
);
2692 static void LIBXML2_LOG_CALLBACK
validate_warning(void* ctx
, char const* msg
, ...)
2696 LIBXML2_CALLBACK_WARN(domdoc_validateNode
, msg
, ap
);
2700 static HRESULT WINAPI
domdoc_validateNode(
2701 IXMLDOMDocument3
* iface
,
2703 IXMLDOMParseError
** err
)
2705 domdoc
* This
= impl_from_IXMLDOMDocument3(iface
);
2706 LONG state
, err_code
= 0;
2710 TRACE("(%p)->(%p, %p)\n", This
, node
, err
);
2711 domdoc_get_readyState(iface
, &state
);
2712 if (state
!= READYSTATE_COMPLETE
)
2715 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2722 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2726 if (!get_node_obj(node
)->node
|| get_node_obj(node
)->node
->doc
!= get_doc(This
))
2729 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2733 if (!is_wellformed(get_doc(This
)))
2735 ERR("doc not well-formed\n");
2737 *err
= create_parseError(E_XML_NOTWF
, NULL
, NULL
, NULL
, 0, 0, 0);
2741 /* DTD validation */
2742 if (get_doc(This
)->intSubset
|| get_doc(This
)->extSubset
)
2744 xmlValidCtxtPtr vctx
= xmlNewValidCtxt();
2745 vctx
->error
= validate_error
;
2746 vctx
->warning
= validate_warning
;
2749 if (!((node
== (IXMLDOMNode
*)iface
)?
2750 xmlValidateDocument(vctx
, get_doc(This
)) :
2751 xmlValidateElement(vctx
, get_doc(This
), get_node_obj(node
)->node
)))
2753 /* TODO: get a real error code here */
2754 TRACE("DTD validation failed\n");
2755 err_code
= E_XML_INVALID
;
2758 xmlFreeValidCtxt(vctx
);
2761 /* Schema validation */
2762 if (hr
== S_OK
&& This
->properties
->schemaCache
!= NULL
)
2765 hr
= SchemaCache_validate_tree(This
->properties
->schemaCache
, get_node_obj(node
)->node
);
2769 /* TODO: get a real error code here */
2772 TRACE("schema validation succeeded\n");
2776 ERR("schema validation failed\n");
2777 err_code
= E_XML_INVALID
;
2782 /* not really OK, just didn't find a schema for the ns */
2789 ERR("no DTD or schema found\n");
2790 err_code
= E_XML_NODTD
;
2795 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2800 static HRESULT WINAPI
domdoc_validate(
2801 IXMLDOMDocument3
* iface
,
2802 IXMLDOMParseError
** err
)
2804 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2805 TRACE("(%p)->(%p)\n", This
, err
);
2806 return domdoc_validateNode(iface
, (IXMLDOMNode
*)iface
, err
);
2809 static HRESULT WINAPI
domdoc_setProperty(
2810 IXMLDOMDocument3
* iface
,
2814 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2816 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
2818 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2824 V_VT(&varStr
) = VT_EMPTY
;
2825 if (V_VT(&var
) != VT_BSTR
)
2827 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2829 bstr
= V_BSTR(&varStr
);
2832 bstr
= V_BSTR(&var
);
2835 if (lstrcmpiW(bstr
, PropValueXPathW
) == 0)
2836 This
->properties
->XPath
= TRUE
;
2837 else if (lstrcmpiW(bstr
, PropValueXSLPatternW
) == 0)
2838 This
->properties
->XPath
= FALSE
;
2842 VariantClear(&varStr
);
2845 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2850 xmlChar
*pTokBegin
, *pTokEnd
, *pTokInner
;
2851 xmlChar
*nsStr
= (xmlChar
*)This
->properties
->selectNsStr
;
2852 xmlXPathContextPtr ctx
;
2853 struct list
*pNsList
;
2854 select_ns_entry
* pNsEntry
= NULL
;
2856 V_VT(&varStr
) = VT_EMPTY
;
2857 if (V_VT(&var
) != VT_BSTR
)
2859 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2861 bstr
= V_BSTR(&varStr
);
2864 bstr
= V_BSTR(&var
);
2868 pNsList
= &(This
->properties
->selectNsList
);
2869 clear_selectNsList(pNsList
);
2871 nsStr
= xmlchar_from_wchar(bstr
);
2873 TRACE("Setting SelectionNamespaces property to: %s\n", nsStr
);
2875 This
->properties
->selectNsStr
= nsStr
;
2876 This
->properties
->selectNsStr_len
= xmlStrlen(nsStr
);
2879 ctx
= xmlXPathNewContext(This
->node
.node
->doc
);
2881 for (; *pTokBegin
; pTokBegin
= pTokEnd
)
2883 if (pNsEntry
!= NULL
)
2884 memset(pNsEntry
, 0, sizeof(select_ns_entry
));
2886 pNsEntry
= heap_alloc_zero(sizeof(select_ns_entry
));
2888 while (*pTokBegin
== ' ')
2890 pTokEnd
= pTokBegin
;
2891 while (*pTokEnd
!= ' ' && *pTokEnd
!= 0)
2894 if (xmlStrncmp(pTokBegin
, (xmlChar
const*)"xmlns", 5) != 0)
2897 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2898 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2903 if (*pTokBegin
== '=')
2905 /*valid for XSLPattern?*/
2906 FIXME("Setting default xmlns not supported - skipping.\n");
2909 else if (*pTokBegin
== ':')
2911 pNsEntry
->prefix
= ++pTokBegin
;
2912 for (pTokInner
= pTokBegin
; pTokInner
!= pTokEnd
&& *pTokInner
!= '='; ++pTokInner
)
2915 if (pTokInner
== pTokEnd
)
2918 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2919 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2923 pNsEntry
->prefix_end
= *pTokInner
;
2927 if (pTokEnd
-pTokInner
> 1 &&
2928 ((*pTokInner
== '\'' && *(pTokEnd
-1) == '\'') ||
2929 (*pTokInner
== '"' && *(pTokEnd
-1) == '"')))
2931 pNsEntry
->href
= ++pTokInner
;
2932 pNsEntry
->href_end
= *(pTokEnd
-1);
2934 list_add_tail(pNsList
, &pNsEntry
->entry
);
2935 /*let libxml figure out if they're valid from here ;)*/
2936 if (xmlXPathRegisterNs(ctx
, pNsEntry
->prefix
, pNsEntry
->href
) != 0)
2945 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2946 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokInner
, pTokEnd
-pTokInner
));
2947 list_add_tail(pNsList
, &pNsEntry
->entry
);
2960 heap_free(pNsEntry
);
2961 xmlXPathFreeContext(ctx
);
2964 VariantClear(&varStr
);
2967 else if (lstrcmpiW(p
, PropertyProhibitDTDW
) == 0 ||
2968 lstrcmpiW(p
, PropertyNewParserW
) == 0 ||
2969 lstrcmpiW(p
, PropertyResolveExternalsW
) == 0)
2972 FIXME("Ignoring property %s, value %d\n", debugstr_w(p
), V_BOOL(&var
));
2976 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2980 static HRESULT WINAPI
domdoc_getProperty(
2981 IXMLDOMDocument3
* iface
,
2985 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2987 TRACE("(%p)->(%p)\n", This
, debugstr_w(p
));
2990 return E_INVALIDARG
;
2992 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2994 V_VT(var
) = VT_BSTR
;
2995 V_BSTR(var
) = This
->properties
->XPath
?
2996 SysAllocString(PropValueXPathW
) :
2997 SysAllocString(PropValueXSLPatternW
);
2998 return V_BSTR(var
) ? S_OK
: E_OUTOFMEMORY
;
3000 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
3003 BSTR rebuiltStr
, cur
;
3004 const xmlChar
*nsStr
;
3005 struct list
*pNsList
;
3006 select_ns_entry
* pNsEntry
;
3008 V_VT(var
) = VT_BSTR
;
3009 nsStr
= This
->properties
->selectNsStr
;
3010 pNsList
= &This
->properties
->selectNsList
;
3011 lenA
= This
->properties
->selectNsStr_len
;
3012 lenW
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, NULL
, 0);
3013 rebuiltStr
= heap_alloc(lenW
*sizeof(WCHAR
));
3014 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, rebuiltStr
, lenW
);
3016 /* this is fine because all of the chars that end tokens are ASCII*/
3017 LIST_FOR_EACH_ENTRY(pNsEntry
, pNsList
, select_ns_entry
, entry
)
3019 while (*cur
!= 0) ++cur
;
3020 if (pNsEntry
->prefix_end
)
3022 *cur
= pNsEntry
->prefix_end
;
3023 while (*cur
!= 0) ++cur
;
3026 if (pNsEntry
->href_end
)
3028 *cur
= pNsEntry
->href_end
;
3031 V_BSTR(var
) = SysAllocString(rebuiltStr
);
3032 heap_free(rebuiltStr
);
3036 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
3040 static HRESULT WINAPI
domdoc_importNode(
3041 IXMLDOMDocument3
* iface
,
3044 IXMLDOMNode
** clone
)
3046 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
3047 FIXME("(%p)->(%p %d %p): stub\n", This
, node
, deep
, clone
);
3051 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl
=
3053 domdoc_QueryInterface
,
3056 domdoc_GetTypeInfoCount
,
3058 domdoc_GetIDsOfNames
,
3060 domdoc_get_nodeName
,
3061 domdoc_get_nodeValue
,
3062 domdoc_put_nodeValue
,
3063 domdoc_get_nodeType
,
3064 domdoc_get_parentNode
,
3065 domdoc_get_childNodes
,
3066 domdoc_get_firstChild
,
3067 domdoc_get_lastChild
,
3068 domdoc_get_previousSibling
,
3069 domdoc_get_nextSibling
,
3070 domdoc_get_attributes
,
3071 domdoc_insertBefore
,
3072 domdoc_replaceChild
,
3075 domdoc_hasChildNodes
,
3076 domdoc_get_ownerDocument
,
3078 domdoc_get_nodeTypeString
,
3081 domdoc_get_specified
,
3082 domdoc_get_definition
,
3083 domdoc_get_nodeTypedValue
,
3084 domdoc_put_nodeTypedValue
,
3085 domdoc_get_dataType
,
3086 domdoc_put_dataType
,
3088 domdoc_transformNode
,
3090 domdoc_selectSingleNode
,
3092 domdoc_get_namespaceURI
,
3094 domdoc_get_baseName
,
3095 domdoc_transformNodeToObject
,
3097 domdoc_get_implementation
,
3098 domdoc_get_documentElement
,
3099 domdoc_put_documentElement
,
3100 domdoc_createElement
,
3101 domdoc_createDocumentFragment
,
3102 domdoc_createTextNode
,
3103 domdoc_createComment
,
3104 domdoc_createCDATASection
,
3105 domdoc_createProcessingInstruction
,
3106 domdoc_createAttribute
,
3107 domdoc_createEntityReference
,
3108 domdoc_getElementsByTagName
,
3112 domdoc_get_readyState
,
3113 domdoc_get_parseError
,
3120 domdoc_get_validateOnParse
,
3121 domdoc_put_validateOnParse
,
3122 domdoc_get_resolveExternals
,
3123 domdoc_put_resolveExternals
,
3124 domdoc_get_preserveWhiteSpace
,
3125 domdoc_put_preserveWhiteSpace
,
3126 domdoc_put_onreadystatechange
,
3127 domdoc_put_onDataAvailable
,
3128 domdoc_put_onTransformNode
,
3129 domdoc_get_namespaces
,
3131 domdoc_putref_schemas
,
3135 domdoc_validateNode
,
3139 /* IConnectionPointContainer */
3140 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
3141 REFIID riid
, void **ppv
)
3143 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3144 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3147 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
3149 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3150 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3153 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
3155 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3156 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3159 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
3160 IEnumConnectionPoints
**ppEnum
)
3162 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3163 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3167 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
3168 REFIID riid
, IConnectionPoint
**cp
)
3170 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3171 ConnectionPoint
*iter
;
3173 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), cp
);
3177 for(iter
= This
->cp_list
; iter
; iter
= iter
->next
)
3179 if (IsEqualGUID(iter
->iid
, riid
))
3180 *cp
= &iter
->IConnectionPoint_iface
;
3185 IConnectionPoint_AddRef(*cp
);
3189 FIXME("unsupported riid %s\n", debugstr_guid(riid
));
3190 return CONNECT_E_NOCONNECTION
;
3194 static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
3196 ConnectionPointContainer_QueryInterface
,
3197 ConnectionPointContainer_AddRef
,
3198 ConnectionPointContainer_Release
,
3199 ConnectionPointContainer_EnumConnectionPoints
,
3200 ConnectionPointContainer_FindConnectionPoint
3203 /* IConnectionPoint */
3204 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
3205 REFIID riid
, void **ppv
)
3207 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3209 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
3213 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
3214 IsEqualGUID(&IID_IConnectionPoint
, riid
))
3221 IConnectionPoint_AddRef(iface
);
3225 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
3226 return E_NOINTERFACE
;
3229 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
3231 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3232 return IConnectionPointContainer_AddRef(This
->container
);
3235 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
3237 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3238 return IConnectionPointContainer_Release(This
->container
);
3241 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*iid
)
3243 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3245 TRACE("(%p)->(%p)\n", This
, iid
);
3247 if (!iid
) return E_POINTER
;
3253 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
3254 IConnectionPointContainer
**container
)
3256 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3258 TRACE("(%p)->(%p)\n", This
, container
);
3260 if (!container
) return E_POINTER
;
3262 *container
= This
->container
;
3263 IConnectionPointContainer_AddRef(*container
);
3267 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
3270 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3271 FIXME("(%p)->(%p %p): stub\n", This
, pUnkSink
, pdwCookie
);
3275 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD cookie
)
3277 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3279 TRACE("(%p)->(%d)\n", This
, cookie
);
3281 if (cookie
== 0 || cookie
> This
->sinks_size
|| !This
->sinks
[cookie
-1].unk
)
3282 return CONNECT_E_NOCONNECTION
;
3284 IUnknown_Release(This
->sinks
[cookie
-1].unk
);
3285 This
->sinks
[cookie
-1].unk
= NULL
;
3290 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
3291 IEnumConnections
**ppEnum
)
3293 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3294 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3298 static const IConnectionPointVtbl ConnectionPointVtbl
=
3300 ConnectionPoint_QueryInterface
,
3301 ConnectionPoint_AddRef
,
3302 ConnectionPoint_Release
,
3303 ConnectionPoint_GetConnectionInterface
,
3304 ConnectionPoint_GetConnectionPointContainer
,
3305 ConnectionPoint_Advise
,
3306 ConnectionPoint_Unadvise
,
3307 ConnectionPoint_EnumConnections
3310 static void ConnectionPoint_Init(ConnectionPoint
*cp
, struct domdoc
*doc
, REFIID riid
)
3312 cp
->IConnectionPoint_iface
.lpVtbl
= &ConnectionPointVtbl
;
3318 cp
->next
= doc
->cp_list
;
3321 cp
->container
= &doc
->IConnectionPointContainer_iface
;
3324 /* domdoc implementation of IObjectWithSite */
3325 static HRESULT WINAPI
3326 domdoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
3328 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3329 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObject
);
3332 static ULONG WINAPI
domdoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
3334 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3335 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3338 static ULONG WINAPI
domdoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
3340 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3341 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3344 static HRESULT WINAPI
domdoc_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
3346 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3348 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
3353 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
3356 static HRESULT WINAPI
domdoc_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
3358 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3360 TRACE("(%p)->(%p)\n", iface
, punk
);
3366 IUnknown_Release( This
->site
);
3373 IUnknown_AddRef( punk
);
3376 IUnknown_Release( This
->site
);
3383 static const IObjectWithSiteVtbl domdocObjectSite
=
3385 domdoc_ObjectWithSite_QueryInterface
,
3386 domdoc_ObjectWithSite_AddRef
,
3387 domdoc_ObjectWithSite_Release
,
3388 domdoc_ObjectWithSite_SetSite
,
3389 domdoc_ObjectWithSite_GetSite
3392 static HRESULT WINAPI
domdoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
3394 domdoc
*This
= impl_from_IObjectSafety(iface
);
3395 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3398 static ULONG WINAPI
domdoc_Safety_AddRef(IObjectSafety
*iface
)
3400 domdoc
*This
= impl_from_IObjectSafety(iface
);
3401 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3404 static ULONG WINAPI
domdoc_Safety_Release(IObjectSafety
*iface
)
3406 domdoc
*This
= impl_from_IObjectSafety(iface
);
3407 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3410 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
3412 static HRESULT WINAPI
domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3413 DWORD
*supported
, DWORD
*enabled
)
3415 domdoc
*This
= impl_from_IObjectSafety(iface
);
3417 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
3419 if(!supported
|| !enabled
) return E_POINTER
;
3421 *supported
= SAFETY_SUPPORTED_OPTIONS
;
3422 *enabled
= This
->safeopt
;
3427 static HRESULT WINAPI
domdoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3428 DWORD mask
, DWORD enabled
)
3430 domdoc
*This
= impl_from_IObjectSafety(iface
);
3431 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
3433 if ((mask
& ~SAFETY_SUPPORTED_OPTIONS
) != 0)
3436 This
->safeopt
= (This
->safeopt
& ~mask
) | (mask
& enabled
);
3441 #undef SAFETY_SUPPORTED_OPTIONS
3443 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
3444 domdoc_Safety_QueryInterface
,
3445 domdoc_Safety_AddRef
,
3446 domdoc_Safety_Release
,
3447 domdoc_Safety_GetInterfaceSafetyOptions
,
3448 domdoc_Safety_SetInterfaceSafetyOptions
3451 static const tid_t domdoc_iface_tids
[] = {
3453 IXMLDOMDocument_tid
,
3454 IXMLDOMDocument2_tid
,
3457 static dispex_static_data_t domdoc_dispex
= {
3459 IXMLDOMDocument2_tid
,
3464 HRESULT
get_domdoc_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument3
**document
)
3468 doc
= heap_alloc( sizeof (*doc
) );
3470 return E_OUTOFMEMORY
;
3472 doc
->IXMLDOMDocument3_iface
.lpVtbl
= &domdoc_vtbl
;
3473 doc
->IPersistStreamInit_iface
.lpVtbl
= &xmldoc_IPersistStreamInit_VTable
;
3474 doc
->IObjectWithSite_iface
.lpVtbl
= &domdocObjectSite
;
3475 doc
->IObjectSafety_iface
.lpVtbl
= &domdocObjectSafetyVtbl
;
3476 doc
->ISupportErrorInfo_iface
.lpVtbl
= &support_error_vtbl
;
3477 doc
->IConnectionPointContainer_iface
.lpVtbl
= &ConnectionPointContainerVtbl
;
3479 doc
->async
= VARIANT_TRUE
;
3480 doc
->validating
= 0;
3482 doc
->properties
= properties_from_xmlDocPtr(xmldoc
);
3488 doc
->cp_list
= NULL
;
3489 memset(doc
->events
, 0, sizeof(doc
->events
));
3491 /* events connection points */
3492 ConnectionPoint_Init(&doc
->cp_dispatch
, doc
, &IID_IDispatch
);
3493 ConnectionPoint_Init(&doc
->cp_propnotif
, doc
, &IID_IPropertyNotifySink
);
3494 ConnectionPoint_Init(&doc
->cp_domdocevents
, doc
, &DIID_XMLDOMDocumentEvents
);
3496 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IXMLDOMNode
*)&doc
->IXMLDOMDocument3_iface
,
3499 *document
= &doc
->IXMLDOMDocument3_iface
;
3501 TRACE("returning iface %p\n", *document
);
3505 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3510 TRACE("(%d, %p, %p)\n", version
, pUnkOuter
, ppObj
);
3512 xmldoc
= xmlNewDoc(NULL
);
3514 return E_OUTOFMEMORY
;
3516 xmldoc
->_private
= create_priv();
3517 priv_from_xmlDocPtr(xmldoc
)->properties
= create_properties(version
);
3519 hr
= get_domdoc_from_xmldoc(xmldoc
, (IXMLDOMDocument3
**)ppObj
);
3522 free_properties(properties_from_xmlDocPtr(xmldoc
));
3523 heap_free(xmldoc
->_private
);
3531 IUnknown
* create_domdoc( xmlNodePtr document
)
3536 TRACE("(%p)\n", document
);
3538 hr
= get_domdoc_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument3
**)&pObj
);
3547 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3549 MESSAGE("This program tried to use a DOMDocument object, but\n"
3550 "libxml2 support was not present at compile time.\n");