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>
52 #include "wine/debug.h"
53 #include "wine/list.h"
55 #include "msxml_private.h"
57 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
61 /* not defined in older versions */
62 #define XML_SAVE_FORMAT 1
63 #define XML_SAVE_NO_DECL 2
64 #define XML_SAVE_NO_EMPTY 4
65 #define XML_SAVE_NO_XHTML 8
66 #define XML_SAVE_XHTML 16
67 #define XML_SAVE_AS_XML 32
68 #define XML_SAVE_AS_HTML 64
70 static const WCHAR PropertySelectionLanguageW
[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
71 static const WCHAR PropertySelectionNamespacesW
[] = {'S','e','l','e','c','t','i','o','n','N','a','m','e','s','p','a','c','e','s',0};
72 static const WCHAR PropertyProhibitDTDW
[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
73 static const WCHAR PropertyNewParserW
[] = {'N','e','w','P','a','r','s','e','r',0};
74 static const WCHAR PropValueXPathW
[] = {'X','P','a','t','h',0};
75 static const WCHAR PropValueXSLPatternW
[] = {'X','S','L','P','a','t','t','e','r','n',0};
76 static const WCHAR PropertyResolveExternalsW
[] = {'R','e','s','o','l','v','e','E','x','t','e','r','n','a','l','s',0};
78 /* Anything that passes the test_get_ownerDocument()
79 * tests can go here (data shared between all instances).
80 * We need to preserve this when reloading a document,
81 * and also need access to it from the libxml backend. */
82 typedef struct _domdoc_properties
{
83 MSXML_VERSION version
;
84 VARIANT_BOOL preserving
;
85 IXMLDOMSchemaCollection2
* schemaCache
;
86 struct list selectNsList
;
87 xmlChar
const* selectNsStr
;
92 typedef struct ConnectionPoint ConnectionPoint
;
93 typedef struct domdoc domdoc
;
95 struct ConnectionPoint
97 IConnectionPoint IConnectionPoint_iface
;
100 ConnectionPoint
*next
;
101 IConnectionPointContainer
*container
;
108 IPropertyNotifySink
*propnotif
;
114 EVENTID_READYSTATECHANGE
= 0,
115 EVENTID_DATAAVAILABLE
,
116 EVENTID_TRANSFORMNODE
,
123 IXMLDOMDocument3 IXMLDOMDocument3_iface
;
124 IPersistStreamInit IPersistStreamInit_iface
;
125 IObjectWithSite IObjectWithSite_iface
;
126 IObjectSafety IObjectSafety_iface
;
127 ISupportErrorInfo ISupportErrorInfo_iface
;
128 IConnectionPointContainer IConnectionPointContainer_iface
;
131 VARIANT_BOOL validating
;
132 VARIANT_BOOL resolving
;
133 domdoc_properties
* properties
;
146 /* connection list */
147 ConnectionPoint
*cp_list
;
148 ConnectionPoint cp_domdocevents
;
149 ConnectionPoint cp_propnotif
;
150 ConnectionPoint cp_dispatch
;
153 IDispatch
*events
[EVENTID_LAST
];
156 static HRESULT
set_doc_event(domdoc
*doc
, eventid_t eid
, const VARIANT
*v
)
164 IUnknown_QueryInterface(V_UNKNOWN(v
), &IID_IDispatch
, (void**)&disp
);
169 disp
= V_DISPATCH(v
);
170 if (disp
) IDispatch_AddRef(disp
);
173 return DISP_E_TYPEMISMATCH
;
176 if (doc
->events
[eid
]) IDispatch_Release(doc
->events
[eid
]);
177 doc
->events
[eid
] = disp
;
182 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
184 return CONTAINING_RECORD(iface
, ConnectionPoint
, IConnectionPoint_iface
);
188 In native windows, the whole lifetime management of XMLDOMNodes is
189 managed automatically using reference counts. Wine emulates that by
190 maintaining a reference count to the document that is increased for
191 each IXMLDOMNode pointer passed out for this document. If all these
192 pointers are gone, the document is unreachable and gets freed, that
193 is, all nodes in the tree of the document get freed.
195 You are able to create nodes that are associated to a document (in
196 fact, in msxml's XMLDOM model, all nodes are associated to a document),
197 but not in the tree of that document, for example using the createFoo
198 functions from IXMLDOMDocument. These nodes do not get cleaned up
199 by libxml, so we have to do it ourselves.
201 To catch these nodes, a list of "orphan nodes" is introduced.
202 It contains pointers to all roots of node trees that are
203 associated with the document without being part of the document
204 tree. All nodes with parent==NULL (except for the document root nodes)
205 should be in the orphan node list of their document. All orphan nodes
206 get freed together with the document itself.
209 typedef struct _xmldoc_priv
{
212 domdoc_properties
* properties
;
215 typedef struct _orphan_entry
{
220 typedef struct _select_ns_entry
{
222 xmlChar
const* prefix
;
228 static inline xmldoc_priv
* priv_from_xmlDocPtr(const xmlDocPtr doc
)
230 return doc
->_private
;
233 static inline domdoc_properties
* properties_from_xmlDocPtr(xmlDocPtr doc
)
235 return priv_from_xmlDocPtr(doc
)->properties
;
238 BOOL
is_xpathmode(const xmlDocPtr doc
)
240 return properties_from_xmlDocPtr(doc
)->XPath
;
243 void set_xpathmode(xmlDocPtr doc
, BOOL xpath
)
245 properties_from_xmlDocPtr(doc
)->XPath
= xpath
;
248 int registerNamespaces(xmlXPathContextPtr ctxt
)
251 const select_ns_entry
* ns
= NULL
;
252 const struct list
* pNsList
= &properties_from_xmlDocPtr(ctxt
->doc
)->selectNsList
;
254 TRACE("(%p)\n", ctxt
);
256 LIST_FOR_EACH_ENTRY( ns
, pNsList
, select_ns_entry
, entry
)
258 xmlXPathRegisterNs(ctxt
, ns
->prefix
, ns
->href
);
265 static inline void clear_selectNsList(struct list
* pNsList
)
267 select_ns_entry
*ns
, *ns2
;
268 LIST_FOR_EACH_ENTRY_SAFE( ns
, ns2
, pNsList
, select_ns_entry
, entry
)
275 static xmldoc_priv
* create_priv(void)
278 priv
= heap_alloc( sizeof (*priv
) );
283 list_init( &priv
->orphans
);
284 priv
->properties
= NULL
;
290 static domdoc_properties
* create_properties(MSXML_VERSION version
)
292 domdoc_properties
*properties
= heap_alloc(sizeof(domdoc_properties
));
294 list_init(&properties
->selectNsList
);
295 properties
->preserving
= VARIANT_FALSE
;
296 properties
->schemaCache
= NULL
;
297 properties
->selectNsStr
= heap_alloc_zero(sizeof(xmlChar
));
298 properties
->selectNsStr_len
= 0;
300 /* properties that are dependent on object versions */
301 properties
->version
= version
;
302 properties
->XPath
= (version
== MSXML4
|| version
== MSXML6
);
307 static domdoc_properties
* copy_properties(domdoc_properties
const* properties
)
309 domdoc_properties
* pcopy
= heap_alloc(sizeof(domdoc_properties
));
310 select_ns_entry
const* ns
= NULL
;
311 select_ns_entry
* new_ns
= NULL
;
312 int len
= (properties
->selectNsStr_len
+1)*sizeof(xmlChar
);
317 pcopy
->version
= properties
->version
;
318 pcopy
->preserving
= properties
->preserving
;
319 pcopy
->schemaCache
= properties
->schemaCache
;
320 if (pcopy
->schemaCache
)
321 IXMLDOMSchemaCollection2_AddRef(pcopy
->schemaCache
);
322 pcopy
->XPath
= properties
->XPath
;
323 pcopy
->selectNsStr_len
= properties
->selectNsStr_len
;
324 list_init( &pcopy
->selectNsList
);
325 pcopy
->selectNsStr
= heap_alloc(len
);
326 memcpy((xmlChar
*)pcopy
->selectNsStr
, properties
->selectNsStr
, len
);
327 offset
= pcopy
->selectNsStr
- properties
->selectNsStr
;
329 LIST_FOR_EACH_ENTRY( ns
, (&properties
->selectNsList
), select_ns_entry
, entry
)
331 new_ns
= heap_alloc(sizeof(select_ns_entry
));
332 memcpy(new_ns
, ns
, sizeof(select_ns_entry
));
333 new_ns
->href
+= offset
;
334 new_ns
->prefix
+= offset
;
335 list_add_tail(&pcopy
->selectNsList
, &new_ns
->entry
);
343 static void free_properties(domdoc_properties
* properties
)
347 if (properties
->schemaCache
)
348 IXMLDOMSchemaCollection2_Release(properties
->schemaCache
);
349 clear_selectNsList(&properties
->selectNsList
);
350 heap_free((xmlChar
*)properties
->selectNsStr
);
351 heap_free(properties
);
355 /* links a "<?xml" node as a first child */
356 void xmldoc_link_xmldecl(xmlDocPtr doc
, xmlNodePtr node
)
359 if (doc
->standalone
!= -1) xmlAddPrevSibling( doc
->children
, node
);
362 /* unlinks a first "<?xml" child if it was created */
363 xmlNodePtr
xmldoc_unlink_xmldecl(xmlDocPtr doc
)
369 if (doc
->standalone
!= -1)
371 node
= doc
->children
;
372 xmlUnlinkNode( node
);
380 BOOL
is_preserving_whitespace(xmlNodePtr node
)
382 domdoc_properties
* properties
= NULL
;
383 /* during parsing the xmlDoc._private stuff is not there */
384 if (priv_from_xmlDocPtr(node
->doc
))
385 properties
= properties_from_xmlDocPtr(node
->doc
);
386 return ((properties
&& properties
->preserving
== VARIANT_TRUE
) ||
387 xmlNodeGetSpacePreserve(node
) == 1);
390 static inline BOOL
strn_isspace(xmlChar
const* str
, int len
)
392 for (; str
&& len
> 0 && *str
; ++str
, --len
)
399 static void sax_characters(void *ctx
, const xmlChar
*ch
, int len
)
401 xmlParserCtxtPtr ctxt
;
404 ctxt
= (xmlParserCtxtPtr
) ctx
;
405 This
= (const domdoc
*) ctxt
->_private
;
409 /* during domdoc_loadXML() the xmlDocPtr->_private data is not available */
410 if (!This
->properties
->preserving
&&
411 !is_preserving_whitespace(ctxt
->node
) &&
412 strn_isspace(ch
, len
))
416 xmlSAX2Characters(ctxt
, ch
, len
);
419 static void LIBXML2_LOG_CALLBACK
sax_error(void* ctx
, char const* msg
, ...)
423 LIBXML2_CALLBACK_ERR(doparse
, msg
, ap
);
427 static void LIBXML2_LOG_CALLBACK
sax_warning(void* ctx
, char const* msg
, ...)
431 LIBXML2_CALLBACK_WARN(doparse
, msg
, ap
);
435 static void sax_serror(void* ctx
, xmlErrorPtr err
)
437 LIBXML2_CALLBACK_SERROR(doparse
, err
);
440 static xmlDocPtr
doparse(domdoc
* This
, char const* ptr
, int len
, xmlCharEncoding encoding
)
442 xmlDocPtr doc
= NULL
;
443 xmlParserCtxtPtr pctx
;
444 static xmlSAXHandler sax_handler
= {
445 xmlSAX2InternalSubset
, /* internalSubset */
446 xmlSAX2IsStandalone
, /* isStandalone */
447 xmlSAX2HasInternalSubset
, /* hasInternalSubset */
448 xmlSAX2HasExternalSubset
, /* hasExternalSubset */
449 xmlSAX2ResolveEntity
, /* resolveEntity */
450 xmlSAX2GetEntity
, /* getEntity */
451 xmlSAX2EntityDecl
, /* entityDecl */
452 xmlSAX2NotationDecl
, /* notationDecl */
453 xmlSAX2AttributeDecl
, /* attributeDecl */
454 xmlSAX2ElementDecl
, /* elementDecl */
455 xmlSAX2UnparsedEntityDecl
, /* unparsedEntityDecl */
456 xmlSAX2SetDocumentLocator
, /* setDocumentLocator */
457 xmlSAX2StartDocument
, /* startDocument */
458 xmlSAX2EndDocument
, /* endDocument */
459 xmlSAX2StartElement
, /* startElement */
460 xmlSAX2EndElement
, /* endElement */
461 xmlSAX2Reference
, /* reference */
462 sax_characters
, /* characters */
463 sax_characters
, /* ignorableWhitespace */
464 xmlSAX2ProcessingInstruction
, /* processingInstruction */
465 xmlSAX2Comment
, /* comment */
466 sax_warning
, /* warning */
467 sax_error
, /* error */
468 sax_error
, /* fatalError */
469 xmlSAX2GetParameterEntity
, /* getParameterEntity */
470 xmlSAX2CDataBlock
, /* cdataBlock */
471 xmlSAX2ExternalSubset
, /* externalSubset */
474 xmlSAX2StartElementNs
, /* startElementNs */
475 xmlSAX2EndElementNs
, /* endElementNs */
476 sax_serror
/* serror */
480 pctx
= xmlCreateMemoryParserCtxt(ptr
, len
);
483 ERR("Failed to create parser context\n");
487 if (pctx
->sax
) xmlFree(pctx
->sax
);
488 pctx
->sax
= &sax_handler
;
489 pctx
->_private
= This
;
492 if (encoding
!= XML_CHAR_ENCODING_NONE
)
493 xmlSwitchEncoding(pctx
, encoding
);
495 xmlParseDocument(pctx
);
497 if (pctx
->wellFormed
)
503 xmlFreeDoc(pctx
->myDoc
);
507 xmlFreeParserCtxt(pctx
);
509 /* TODO: put this in one of the SAX callbacks */
510 /* create first child as a <?xml...?> */
511 if (doc
&& doc
->standalone
!= -1)
515 xmlChar
*xmlbuff
= (xmlChar
*)buff
;
517 node
= xmlNewDocPI( doc
, (xmlChar
*)"xml", NULL
);
519 /* version attribute can't be omitted */
520 sprintf(buff
, "version=\"%s\"", doc
->version
? (char*)doc
->version
: "1.0");
521 xmlNodeAddContent( node
, xmlbuff
);
525 sprintf(buff
, " encoding=\"%s\"", doc
->encoding
);
526 xmlNodeAddContent( node
, xmlbuff
);
529 if (doc
->standalone
!= -2)
531 sprintf(buff
, " standalone=\"%s\"", doc
->standalone
== 0 ? "no" : "yes");
532 xmlNodeAddContent( node
, xmlbuff
);
535 xmldoc_link_xmldecl( doc
, node
);
541 void xmldoc_init(xmlDocPtr doc
, MSXML_VERSION version
)
543 doc
->_private
= create_priv();
544 priv_from_xmlDocPtr(doc
)->properties
= create_properties(version
);
547 LONG
xmldoc_add_ref(xmlDocPtr doc
)
549 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
550 TRACE("(%p)->(%d)\n", doc
, ref
);
554 LONG
xmldoc_release(xmlDocPtr doc
)
556 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
557 LONG ref
= InterlockedDecrement(&priv
->refs
);
558 TRACE("(%p)->(%d)\n", doc
, ref
);
561 orphan_entry
*orphan
, *orphan2
;
562 TRACE("freeing docptr %p\n", doc
);
564 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
566 xmlFreeNode( orphan
->node
);
569 free_properties(priv
->properties
);
570 heap_free(doc
->_private
);
578 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
580 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
583 entry
= heap_alloc( sizeof (*entry
) );
585 return E_OUTOFMEMORY
;
588 list_add_head( &priv
->orphans
, &entry
->entry
);
592 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
594 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
595 orphan_entry
*entry
, *entry2
;
597 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
599 if( entry
->node
== node
)
601 list_remove( &entry
->entry
);
610 static inline xmlDocPtr
get_doc( domdoc
*This
)
612 return (xmlDocPtr
)This
->node
.node
;
615 static HRESULT
attach_xmldoc(domdoc
*This
, xmlDocPtr xml
)
619 priv_from_xmlDocPtr(get_doc(This
))->properties
= NULL
;
620 if (xmldoc_release(get_doc(This
)) != 0)
621 priv_from_xmlDocPtr(get_doc(This
))->properties
=
622 copy_properties(This
->properties
);
625 This
->node
.node
= (xmlNodePtr
) xml
;
629 xmldoc_add_ref(get_doc(This
));
630 priv_from_xmlDocPtr(get_doc(This
))->properties
= This
->properties
;
636 static inline domdoc
*impl_from_IXMLDOMDocument3( IXMLDOMDocument3
*iface
)
638 return CONTAINING_RECORD(iface
, domdoc
, IXMLDOMDocument3_iface
);
641 static inline domdoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
643 return CONTAINING_RECORD(iface
, domdoc
, IPersistStreamInit_iface
);
646 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
648 return CONTAINING_RECORD(iface
, domdoc
, IObjectWithSite_iface
);
651 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
653 return CONTAINING_RECORD(iface
, domdoc
, IObjectSafety_iface
);
656 static inline domdoc
*impl_from_ISupportErrorInfo(ISupportErrorInfo
*iface
)
658 return CONTAINING_RECORD(iface
, domdoc
, ISupportErrorInfo_iface
);
661 static inline domdoc
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
663 return CONTAINING_RECORD(iface
, domdoc
, IConnectionPointContainer_iface
);
666 /************************************************************************
667 * domdoc implementation of IPersistStream.
669 static HRESULT WINAPI
domdoc_IPersistStreamInit_QueryInterface(
670 IPersistStreamInit
*iface
, REFIID riid
, void **ppvObj
)
672 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
673 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObj
);
676 static ULONG WINAPI
domdoc_IPersistStreamInit_AddRef(
677 IPersistStreamInit
*iface
)
679 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
680 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
683 static ULONG WINAPI
domdoc_IPersistStreamInit_Release(
684 IPersistStreamInit
*iface
)
686 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
687 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
690 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetClassID(
691 IPersistStreamInit
*iface
, CLSID
*classid
)
693 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
694 TRACE("(%p)->(%p)\n", This
, classid
);
699 *classid
= *DOMDocument_version(This
->properties
->version
);
704 static HRESULT WINAPI
domdoc_IPersistStreamInit_IsDirty(
705 IPersistStreamInit
*iface
)
707 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
708 FIXME("(%p): stub!\n", This
);
712 static HRESULT WINAPI
domdoc_IPersistStreamInit_Load(
713 IPersistStreamInit
*iface
, LPSTREAM pStm
)
715 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
718 DWORD read
, written
, len
;
721 xmlDocPtr xmldoc
= NULL
;
723 TRACE("(%p)->(%p)\n", This
, pStm
);
728 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
734 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
735 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
736 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
740 ERR("Failed to copy stream\n");
744 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
748 len
= GlobalSize(hglobal
);
749 ptr
= GlobalLock(hglobal
);
751 xmldoc
= doparse(This
, ptr
, len
, XML_CHAR_ENCODING_NONE
);
752 GlobalUnlock(hglobal
);
756 ERR("Failed to parse xml\n");
760 xmldoc
->_private
= create_priv();
762 return attach_xmldoc(This
, xmldoc
);
765 static HRESULT WINAPI
domdoc_IPersistStreamInit_Save(
766 IPersistStreamInit
*iface
, IStream
*stream
, BOOL clr_dirty
)
768 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
772 TRACE("(%p)->(%p %d)\n", This
, stream
, clr_dirty
);
774 hr
= IXMLDOMDocument3_get_xml(&This
->IXMLDOMDocument3_iface
, &xmlString
);
777 DWORD len
= SysStringLen(xmlString
) * sizeof(WCHAR
);
779 hr
= IStream_Write( stream
, xmlString
, len
, NULL
);
780 SysFreeString(xmlString
);
783 TRACE("ret 0x%08x\n", hr
);
788 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetSizeMax(
789 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
791 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
792 TRACE("(%p)->(%p): stub!\n", This
, pcbSize
);
796 static HRESULT WINAPI
domdoc_IPersistStreamInit_InitNew(
797 IPersistStreamInit
*iface
)
799 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
800 TRACE("(%p)\n", This
);
804 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
806 domdoc_IPersistStreamInit_QueryInterface
,
807 domdoc_IPersistStreamInit_AddRef
,
808 domdoc_IPersistStreamInit_Release
,
809 domdoc_IPersistStreamInit_GetClassID
,
810 domdoc_IPersistStreamInit_IsDirty
,
811 domdoc_IPersistStreamInit_Load
,
812 domdoc_IPersistStreamInit_Save
,
813 domdoc_IPersistStreamInit_GetSizeMax
,
814 domdoc_IPersistStreamInit_InitNew
817 /* ISupportErrorInfo interface */
818 static HRESULT WINAPI
support_error_QueryInterface(
819 ISupportErrorInfo
*iface
,
820 REFIID riid
, void** ppvObj
)
822 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
823 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObj
);
826 static ULONG WINAPI
support_error_AddRef(
827 ISupportErrorInfo
*iface
)
829 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
830 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
833 static ULONG WINAPI
support_error_Release(
834 ISupportErrorInfo
*iface
)
836 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
837 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
840 static HRESULT WINAPI
support_error_InterfaceSupportsErrorInfo(
841 ISupportErrorInfo
*iface
,
844 FIXME("(%p)->(%s)\n", iface
, debugstr_guid(riid
));
848 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
850 support_error_QueryInterface
,
851 support_error_AddRef
,
852 support_error_Release
,
853 support_error_InterfaceSupportsErrorInfo
856 /* IXMLDOMDocument2 interface */
857 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument3
*iface
, REFIID riid
, void** ppvObject
)
859 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
861 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppvObject
);
865 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
866 IsEqualGUID( riid
, &IID_IDispatch
) ||
867 IsEqualGUID( riid
, &IID_IXMLDOMNode
) ||
868 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
869 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
)||
870 IsEqualGUID( riid
, &IID_IXMLDOMDocument3
))
874 else if (IsEqualGUID(&IID_IPersistStream
, riid
) ||
875 IsEqualGUID(&IID_IPersistStreamInit
, riid
))
877 *ppvObject
= &This
->IPersistStreamInit_iface
;
879 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
881 *ppvObject
= &This
->IObjectWithSite_iface
;
883 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
885 *ppvObject
= &This
->IObjectSafety_iface
;
887 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
889 *ppvObject
= &This
->ISupportErrorInfo_iface
;
891 else if(node_query_interface(&This
->node
, riid
, ppvObject
))
893 return *ppvObject
? S_OK
: E_NOINTERFACE
;
895 else if (IsEqualGUID( riid
, &IID_IConnectionPointContainer
))
897 *ppvObject
= &This
->IConnectionPointContainer_iface
;
901 TRACE("interface %s not implemented\n", debugstr_guid(riid
));
902 return E_NOINTERFACE
;
905 IUnknown_AddRef((IUnknown
*)*ppvObject
);
911 static ULONG WINAPI
domdoc_AddRef(
912 IXMLDOMDocument3
*iface
)
914 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
915 ULONG ref
= InterlockedIncrement( &This
->ref
);
916 TRACE("(%p)->(%d)\n", This
, ref
);
921 static ULONG WINAPI
domdoc_Release(
922 IXMLDOMDocument3
*iface
)
924 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
925 LONG ref
= InterlockedDecrement( &This
->ref
);
927 TRACE("(%p)->(%d)\n", This
, ref
);
934 detach_bsc(This
->bsc
);
937 IUnknown_Release( This
->site
);
938 destroy_xmlnode(&This
->node
);
940 IStream_Release(This
->stream
);
942 for (eid
= 0; eid
< EVENTID_LAST
; eid
++)
943 if (This
->events
[eid
]) IDispatch_Release(This
->events
[eid
]);
951 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument3
*iface
, UINT
* pctinfo
)
953 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
955 TRACE("(%p)->(%p)\n", This
, pctinfo
);
962 static HRESULT WINAPI
domdoc_GetTypeInfo(
963 IXMLDOMDocument3
*iface
,
964 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
966 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
969 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
971 hr
= get_typeinfo(IXMLDOMDocument2_tid
, ppTInfo
);
976 static HRESULT WINAPI
domdoc_GetIDsOfNames(
977 IXMLDOMDocument3
*iface
,
984 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
988 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
991 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
994 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
997 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
998 ITypeInfo_Release(typeinfo
);
1005 static HRESULT WINAPI
domdoc_Invoke(
1006 IXMLDOMDocument3
*iface
,
1007 DISPID dispIdMember
,
1011 DISPPARAMS
* pDispParams
,
1012 VARIANT
* pVarResult
,
1013 EXCEPINFO
* pExcepInfo
,
1016 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1017 ITypeInfo
*typeinfo
;
1020 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1021 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1023 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
1026 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IXMLDOMDocument3_iface
, dispIdMember
, wFlags
,
1027 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1028 ITypeInfo_Release(typeinfo
);
1035 static HRESULT WINAPI
domdoc_get_nodeName(
1036 IXMLDOMDocument3
*iface
,
1039 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1041 static const WCHAR documentW
[] = {'#','d','o','c','u','m','e','n','t',0};
1043 TRACE("(%p)->(%p)\n", This
, name
);
1045 return return_bstr(documentW
, name
);
1049 static HRESULT WINAPI
domdoc_get_nodeValue(
1050 IXMLDOMDocument3
*iface
,
1053 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1055 TRACE("(%p)->(%p)\n", This
, value
);
1058 return E_INVALIDARG
;
1060 V_VT(value
) = VT_NULL
;
1061 V_BSTR(value
) = NULL
; /* tests show that we should do this */
1066 static HRESULT WINAPI
domdoc_put_nodeValue(
1067 IXMLDOMDocument3
*iface
,
1070 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1071 TRACE("(%p)->(v%d)\n", This
, V_VT(&value
));
1076 static HRESULT WINAPI
domdoc_get_nodeType(
1077 IXMLDOMDocument3
*iface
,
1080 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1082 TRACE("(%p)->(%p)\n", This
, type
);
1084 *type
= NODE_DOCUMENT
;
1089 static HRESULT WINAPI
domdoc_get_parentNode(
1090 IXMLDOMDocument3
*iface
,
1091 IXMLDOMNode
** parent
)
1093 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1095 TRACE("(%p)->(%p)\n", This
, parent
);
1097 return node_get_parent(&This
->node
, parent
);
1101 static HRESULT WINAPI
domdoc_get_childNodes(
1102 IXMLDOMDocument3
*iface
,
1103 IXMLDOMNodeList
** childList
)
1105 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1107 TRACE("(%p)->(%p)\n", This
, childList
);
1109 return node_get_child_nodes(&This
->node
, childList
);
1113 static HRESULT WINAPI
domdoc_get_firstChild(
1114 IXMLDOMDocument3
*iface
,
1115 IXMLDOMNode
** firstChild
)
1117 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1119 TRACE("(%p)->(%p)\n", This
, firstChild
);
1121 return node_get_first_child(&This
->node
, firstChild
);
1125 static HRESULT WINAPI
domdoc_get_lastChild(
1126 IXMLDOMDocument3
*iface
,
1127 IXMLDOMNode
** lastChild
)
1129 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1131 TRACE("(%p)->(%p)\n", This
, lastChild
);
1133 return node_get_last_child(&This
->node
, lastChild
);
1137 static HRESULT WINAPI
domdoc_get_previousSibling(
1138 IXMLDOMDocument3
*iface
,
1139 IXMLDOMNode
** previousSibling
)
1141 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1143 TRACE("(%p)->(%p)\n", This
, previousSibling
);
1145 return return_null_node(previousSibling
);
1149 static HRESULT WINAPI
domdoc_get_nextSibling(
1150 IXMLDOMDocument3
*iface
,
1151 IXMLDOMNode
** nextSibling
)
1153 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1155 TRACE("(%p)->(%p)\n", This
, nextSibling
);
1157 return return_null_node(nextSibling
);
1161 static HRESULT WINAPI
domdoc_get_attributes(
1162 IXMLDOMDocument3
*iface
,
1163 IXMLDOMNamedNodeMap
** attributeMap
)
1165 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1167 TRACE("(%p)->(%p)\n", This
, attributeMap
);
1169 return return_null_ptr((void**)attributeMap
);
1173 static HRESULT WINAPI
domdoc_insertBefore(
1174 IXMLDOMDocument3
*iface
,
1175 IXMLDOMNode
* newChild
,
1177 IXMLDOMNode
** outNewChild
)
1179 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1181 TRACE("(%p)->(%p x%d %p)\n", This
, newChild
, V_VT(&refChild
), outNewChild
);
1183 return node_insert_before(&This
->node
, newChild
, &refChild
, outNewChild
);
1187 static HRESULT WINAPI
domdoc_replaceChild(
1188 IXMLDOMDocument3
*iface
,
1189 IXMLDOMNode
* newChild
,
1190 IXMLDOMNode
* oldChild
,
1191 IXMLDOMNode
** outOldChild
)
1193 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1195 TRACE("(%p)->(%p %p %p)\n", This
, newChild
, oldChild
, outOldChild
);
1197 return node_replace_child(&This
->node
, newChild
, oldChild
, outOldChild
);
1201 static HRESULT WINAPI
domdoc_removeChild(
1202 IXMLDOMDocument3
*iface
,
1204 IXMLDOMNode
**oldChild
)
1206 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1207 TRACE("(%p)->(%p %p)\n", This
, child
, oldChild
);
1208 return node_remove_child(&This
->node
, child
, oldChild
);
1212 static HRESULT WINAPI
domdoc_appendChild(
1213 IXMLDOMDocument3
*iface
,
1215 IXMLDOMNode
**outChild
)
1217 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1218 TRACE("(%p)->(%p %p)\n", This
, child
, outChild
);
1219 return node_append_child(&This
->node
, child
, outChild
);
1223 static HRESULT WINAPI
domdoc_hasChildNodes(
1224 IXMLDOMDocument3
*iface
,
1227 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1228 TRACE("(%p)->(%p)\n", This
, ret
);
1229 return node_has_childnodes(&This
->node
, ret
);
1233 static HRESULT WINAPI
domdoc_get_ownerDocument(
1234 IXMLDOMDocument3
*iface
,
1235 IXMLDOMDocument
**doc
)
1237 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1238 TRACE("(%p)->(%p)\n", This
, doc
);
1239 return node_get_owner_doc(&This
->node
, doc
);
1243 static HRESULT WINAPI
domdoc_cloneNode(
1244 IXMLDOMDocument3
*iface
,
1246 IXMLDOMNode
** outNode
)
1248 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1249 TRACE("(%p)->(%d %p)\n", This
, deep
, outNode
);
1250 return node_clone( &This
->node
, deep
, outNode
);
1254 static HRESULT WINAPI
domdoc_get_nodeTypeString(
1255 IXMLDOMDocument3
*iface
,
1258 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1259 static const WCHAR documentW
[] = {'d','o','c','u','m','e','n','t',0};
1261 TRACE("(%p)->(%p)\n", This
, p
);
1263 return return_bstr(documentW
, p
);
1267 static HRESULT WINAPI
domdoc_get_text(
1268 IXMLDOMDocument3
*iface
,
1271 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1272 TRACE("(%p)->(%p)\n", This
, p
);
1273 return node_get_text(&This
->node
, p
);
1277 static HRESULT WINAPI
domdoc_put_text(
1278 IXMLDOMDocument3
*iface
,
1281 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1282 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
1287 static HRESULT WINAPI
domdoc_get_specified(
1288 IXMLDOMDocument3
*iface
,
1289 VARIANT_BOOL
* isSpecified
)
1291 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1292 FIXME("(%p)->(%p) stub!\n", This
, isSpecified
);
1293 *isSpecified
= VARIANT_TRUE
;
1298 static HRESULT WINAPI
domdoc_get_definition(
1299 IXMLDOMDocument3
*iface
,
1300 IXMLDOMNode
** definitionNode
)
1302 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1303 FIXME("(%p)->(%p)\n", This
, definitionNode
);
1308 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
1309 IXMLDOMDocument3
*iface
,
1312 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1313 TRACE("(%p)->(%p)\n", This
, v
);
1314 return return_null_var(v
);
1317 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
1318 IXMLDOMDocument3
*iface
,
1319 VARIANT typedValue
)
1321 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1322 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&typedValue
));
1327 static HRESULT WINAPI
domdoc_get_dataType(
1328 IXMLDOMDocument3
*iface
,
1331 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1332 TRACE("(%p)->(%p)\n", This
, typename
);
1333 return return_null_var( typename
);
1337 static HRESULT WINAPI
domdoc_put_dataType(
1338 IXMLDOMDocument3
*iface
,
1341 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1343 FIXME("(%p)->(%s)\n", This
, debugstr_w(dataTypeName
));
1346 return E_INVALIDARG
;
1351 static int XMLCALL
domdoc_get_xml_writecallback(void *ctx
, const char *data
, int len
)
1353 return xmlBufferAdd((xmlBufferPtr
)ctx
, (xmlChar
*)data
, len
) == 0 ? len
: 0;
1356 static HRESULT WINAPI
domdoc_get_xml(
1357 IXMLDOMDocument3
*iface
,
1360 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1361 xmlSaveCtxtPtr ctxt
;
1366 TRACE("(%p)->(%p)\n", This
, p
);
1369 return E_INVALIDARG
;
1373 buf
= xmlBufferCreate();
1375 return E_OUTOFMEMORY
;
1377 options
= XML_SAVE_FORMAT
| XML_SAVE_NO_DECL
;
1378 ctxt
= xmlSaveToIO(domdoc_get_xml_writecallback
, NULL
, buf
, "UTF-8", options
);
1383 return E_OUTOFMEMORY
;
1386 ret
= xmlSaveDoc(ctxt
, get_doc(This
));
1387 /* flushes on close */
1390 TRACE("%ld, len=%d\n", ret
, xmlBufferLength(buf
));
1391 if(ret
!= -1 && xmlBufferLength(buf
) > 0)
1395 content
= bstr_from_xmlChar(xmlBufferContent(buf
));
1396 content
= EnsureCorrectEOL(content
);
1402 *p
= SysAllocStringLen(NULL
, 0);
1407 return *p
? S_OK
: E_OUTOFMEMORY
;
1411 static HRESULT WINAPI
domdoc_transformNode(
1412 IXMLDOMDocument3
*iface
,
1416 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1417 TRACE("(%p)->(%p %p)\n", This
, node
, p
);
1418 return node_transform_node(&This
->node
, node
, p
);
1422 static HRESULT WINAPI
domdoc_selectNodes(
1423 IXMLDOMDocument3
*iface
,
1425 IXMLDOMNodeList
**outList
)
1427 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1428 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outList
);
1429 return node_select_nodes(&This
->node
, p
, outList
);
1433 static HRESULT WINAPI
domdoc_selectSingleNode(
1434 IXMLDOMDocument3
*iface
,
1436 IXMLDOMNode
**outNode
)
1438 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1439 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outNode
);
1440 return node_select_singlenode(&This
->node
, p
, outNode
);
1444 static HRESULT WINAPI
domdoc_get_parsed(
1445 IXMLDOMDocument3
*iface
,
1446 VARIANT_BOOL
* isParsed
)
1448 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1449 FIXME("(%p)->(%p) stub!\n", This
, isParsed
);
1450 *isParsed
= VARIANT_TRUE
;
1455 static HRESULT WINAPI
domdoc_get_namespaceURI(
1456 IXMLDOMDocument3
*iface
,
1457 BSTR
* namespaceURI
)
1459 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1460 TRACE("(%p)->(%p)\n", This
, namespaceURI
);
1461 return node_get_namespaceURI(&This
->node
, namespaceURI
);
1465 static HRESULT WINAPI
domdoc_get_prefix(
1466 IXMLDOMDocument3
*iface
,
1469 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1470 TRACE("(%p)->(%p)\n", This
, prefix
);
1471 return return_null_bstr( prefix
);
1475 static HRESULT WINAPI
domdoc_get_baseName(
1476 IXMLDOMDocument3
*iface
,
1479 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1480 TRACE("(%p)->(%p)\n", This
, name
);
1481 return return_null_bstr( name
);
1485 static HRESULT WINAPI
domdoc_transformNodeToObject(
1486 IXMLDOMDocument3
*iface
,
1487 IXMLDOMNode
* stylesheet
,
1488 VARIANT outputObject
)
1490 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1491 FIXME("(%p)->(%p %s)\n", This
, stylesheet
, debugstr_variant(&outputObject
));
1496 static HRESULT WINAPI
domdoc_get_doctype(
1497 IXMLDOMDocument3
*iface
,
1498 IXMLDOMDocumentType
** doctype
)
1500 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1505 TRACE("(%p)->(%p)\n", This
, doctype
);
1507 if (!doctype
) return E_INVALIDARG
;
1511 dtd
= xmlGetIntSubset(get_doc(This
));
1512 if (!dtd
) return S_FALSE
;
1514 node
= create_node((xmlNodePtr
)dtd
);
1515 if (!node
) return S_FALSE
;
1517 hr
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentType
, (void**)doctype
);
1518 IXMLDOMNode_Release(node
);
1524 static HRESULT WINAPI
domdoc_get_implementation(
1525 IXMLDOMDocument3
*iface
,
1526 IXMLDOMImplementation
** impl
)
1528 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1530 TRACE("(%p)->(%p)\n", This
, impl
);
1533 return E_INVALIDARG
;
1535 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
1540 static HRESULT WINAPI
domdoc_get_documentElement(
1541 IXMLDOMDocument3
*iface
,
1542 IXMLDOMElement
** DOMElement
)
1544 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1545 IXMLDOMNode
*element_node
;
1549 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1552 return E_INVALIDARG
;
1556 root
= xmlDocGetRootElement( get_doc(This
) );
1560 element_node
= create_node( root
);
1561 if(!element_node
) return S_FALSE
;
1563 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (void**)DOMElement
);
1564 IXMLDOMNode_Release(element_node
);
1570 static HRESULT WINAPI
domdoc_put_documentElement(
1571 IXMLDOMDocument3
*iface
,
1572 IXMLDOMElement
* DOMElement
)
1574 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1575 IXMLDOMNode
*elementNode
;
1580 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1582 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1586 xmlNode
= get_node_obj( elementNode
);
1587 if(!xmlNode
) return E_FAIL
;
1589 if(!xmlNode
->node
->parent
)
1590 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1591 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1593 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1594 IXMLDOMNode_Release( elementNode
);
1597 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1603 static HRESULT WINAPI
domdoc_createElement(
1604 IXMLDOMDocument3
*iface
,
1606 IXMLDOMElement
** element
)
1608 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1613 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagname
), element
);
1615 if (!element
|| !tagname
) return E_INVALIDARG
;
1617 V_VT(&type
) = VT_I1
;
1618 V_I1(&type
) = NODE_ELEMENT
;
1620 hr
= IXMLDOMDocument3_createNode(iface
, type
, tagname
, NULL
, &node
);
1623 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMElement
, (void**)element
);
1624 IXMLDOMNode_Release(node
);
1631 static HRESULT WINAPI
domdoc_createDocumentFragment(
1632 IXMLDOMDocument3
*iface
,
1633 IXMLDOMDocumentFragment
** frag
)
1635 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1640 TRACE("(%p)->(%p)\n", This
, frag
);
1642 if (!frag
) return E_INVALIDARG
;
1646 V_VT(&type
) = VT_I1
;
1647 V_I1(&type
) = NODE_DOCUMENT_FRAGMENT
;
1649 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1652 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentFragment
, (void**)frag
);
1653 IXMLDOMNode_Release(node
);
1660 static HRESULT WINAPI
domdoc_createTextNode(
1661 IXMLDOMDocument3
*iface
,
1663 IXMLDOMText
** text
)
1665 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1670 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), text
);
1672 if (!text
) return E_INVALIDARG
;
1676 V_VT(&type
) = VT_I1
;
1677 V_I1(&type
) = NODE_TEXT
;
1679 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1682 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)text
);
1683 IXMLDOMNode_Release(node
);
1684 hr
= IXMLDOMText_put_data(*text
, data
);
1691 static HRESULT WINAPI
domdoc_createComment(
1692 IXMLDOMDocument3
*iface
,
1694 IXMLDOMComment
** comment
)
1696 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1701 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), comment
);
1703 if (!comment
) return E_INVALIDARG
;
1707 V_VT(&type
) = VT_I1
;
1708 V_I1(&type
) = NODE_COMMENT
;
1710 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1713 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)comment
);
1714 IXMLDOMNode_Release(node
);
1715 hr
= IXMLDOMComment_put_data(*comment
, data
);
1722 static HRESULT WINAPI
domdoc_createCDATASection(
1723 IXMLDOMDocument3
*iface
,
1725 IXMLDOMCDATASection
** cdata
)
1727 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1732 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), cdata
);
1734 if (!cdata
) return E_INVALIDARG
;
1738 V_VT(&type
) = VT_I1
;
1739 V_I1(&type
) = NODE_CDATA_SECTION
;
1741 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1744 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)cdata
);
1745 IXMLDOMNode_Release(node
);
1746 hr
= IXMLDOMCDATASection_put_data(*cdata
, data
);
1753 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1754 IXMLDOMDocument3
*iface
,
1757 IXMLDOMProcessingInstruction
** pi
)
1759 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1764 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(target
), debugstr_w(data
), pi
);
1766 if (!pi
) return E_INVALIDARG
;
1770 V_VT(&type
) = VT_I1
;
1771 V_I1(&type
) = NODE_PROCESSING_INSTRUCTION
;
1773 hr
= IXMLDOMDocument3_createNode(iface
, type
, target
, NULL
, &node
);
1778 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1779 node_obj
= get_node_obj(node
);
1780 hr
= node_set_content(node_obj
, data
);
1782 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMProcessingInstruction
, (void**)pi
);
1783 IXMLDOMNode_Release(node
);
1790 static HRESULT WINAPI
domdoc_createAttribute(
1791 IXMLDOMDocument3
*iface
,
1793 IXMLDOMAttribute
** attribute
)
1795 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1800 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), attribute
);
1802 if (!attribute
|| !name
) return E_INVALIDARG
;
1804 V_VT(&type
) = VT_I1
;
1805 V_I1(&type
) = NODE_ATTRIBUTE
;
1807 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1810 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMAttribute
, (void**)attribute
);
1811 IXMLDOMNode_Release(node
);
1818 static HRESULT WINAPI
domdoc_createEntityReference(
1819 IXMLDOMDocument3
*iface
,
1821 IXMLDOMEntityReference
** entityref
)
1823 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1828 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), entityref
);
1830 if (!entityref
) return E_INVALIDARG
;
1834 V_VT(&type
) = VT_I1
;
1835 V_I1(&type
) = NODE_ENTITY_REFERENCE
;
1837 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1840 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMEntityReference
, (void**)entityref
);
1841 IXMLDOMNode_Release(node
);
1847 xmlChar
* tagName_to_XPath(const BSTR tagName
)
1849 xmlChar
*query
, *tmp
;
1850 static const xmlChar mod_pre
[] = "*[local-name()='";
1851 static const xmlChar mod_post
[] = "']";
1852 static const xmlChar prefix
[] = "descendant::";
1853 const WCHAR
*tokBegin
, *tokEnd
;
1856 query
= xmlStrdup(prefix
);
1859 while (tokBegin
&& *tokBegin
)
1864 query
= xmlStrcat(query
, BAD_CAST
"/");
1868 query
= xmlStrcat(query
, BAD_CAST
"*");
1872 query
= xmlStrcat(query
, mod_pre
);
1874 while (*tokEnd
&& *tokEnd
!= '/')
1876 len
= WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, NULL
, 0, NULL
, NULL
);
1877 tmp
= xmlMalloc(len
);
1878 WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, (char*)tmp
, len
, NULL
, NULL
);
1879 query
= xmlStrncat(query
, tmp
, len
);
1882 query
= xmlStrcat(query
, mod_post
);
1889 static HRESULT WINAPI
domdoc_getElementsByTagName(
1890 IXMLDOMDocument3
*iface
,
1892 IXMLDOMNodeList
** resultList
)
1894 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1899 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(tagName
), resultList
);
1901 if (!tagName
|| !resultList
) return E_INVALIDARG
;
1903 XPath
= This
->properties
->XPath
;
1904 This
->properties
->XPath
= TRUE
;
1905 query
= tagName_to_XPath(tagName
);
1906 hr
= create_selection((xmlNodePtr
)get_doc(This
), query
, resultList
);
1908 This
->properties
->XPath
= XPath
;
1913 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1919 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1921 return E_INVALIDARG
;
1928 static HRESULT WINAPI
domdoc_createNode(
1929 IXMLDOMDocument3
*iface
,
1933 IXMLDOMNode
** node
)
1935 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1936 DOMNodeType node_type
;
1938 xmlChar
*xml_name
, *href
;
1941 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1943 if(!node
) return E_INVALIDARG
;
1945 hr
= get_node_type(Type
, &node_type
);
1946 if(FAILED(hr
)) return hr
;
1948 if(namespaceURI
&& namespaceURI
[0] && node_type
!= NODE_ELEMENT
)
1949 FIXME("nodes with namespaces currently not supported.\n");
1951 TRACE("node_type %d\n", node_type
);
1953 /* exit earlier for types that need name */
1957 case NODE_ATTRIBUTE
:
1958 case NODE_ENTITY_REFERENCE
:
1959 case NODE_PROCESSING_INSTRUCTION
:
1960 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 detach_bsc(This
->bsc
);
2084 static HRESULT WINAPI
domdoc_load(
2085 IXMLDOMDocument3
*iface
,
2087 VARIANT_BOOL
* isSuccessful
)
2089 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2090 LPWSTR filename
= NULL
;
2091 HRESULT hr
= S_FALSE
;
2092 IXMLDOMDocument3
*pNewDoc
= NULL
;
2093 IStream
*pStream
= NULL
;
2096 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&source
));
2100 *isSuccessful
= VARIANT_FALSE
;
2102 assert( &This
->node
);
2104 switch( V_VT(&source
) )
2107 filename
= V_BSTR(&source
);
2109 case VT_BSTR
|VT_BYREF
:
2110 if (!V_BSTRREF(&source
)) return E_INVALIDARG
;
2111 filename
= *V_BSTRREF(&source
);
2113 case VT_ARRAY
|VT_UI1
:
2115 SAFEARRAY
*psa
= V_ARRAY(&source
);
2118 UINT dim
= SafeArrayGetDim(psa
);
2123 ERR("SAFEARRAY == NULL\n");
2124 hr
= This
->error
= E_INVALIDARG
;
2127 /* Only takes UTF-8 strings.
2128 * NOT NULL-terminated. */
2129 SafeArrayAccessData(psa
, (void**)&str
);
2130 SafeArrayGetUBound(psa
, 1, &len
);
2132 if ((xmldoc
= doparse(This
, str
, ++len
, XML_CHAR_ENCODING_UTF8
)))
2134 hr
= This
->error
= S_OK
;
2135 *isSuccessful
= VARIANT_TRUE
;
2136 TRACE("parsed document %p\n", xmldoc
);
2140 This
->error
= E_FAIL
;
2141 TRACE("failed to parse document\n");
2144 SafeArrayUnaccessData(psa
);
2148 xmldoc
->_private
= create_priv();
2149 return attach_xmldoc(This
, xmldoc
);
2153 FIXME("unhandled SAFEARRAY dim: %d\n", dim
);
2154 hr
= This
->error
= E_NOTIMPL
;
2159 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IXMLDOMDocument3
, (void**)&pNewDoc
);
2164 domdoc
*newDoc
= impl_from_IXMLDOMDocument3( pNewDoc
);
2165 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
2166 hr
= attach_xmldoc(This
, xmldoc
);
2169 *isSuccessful
= VARIANT_TRUE
;
2174 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IStream
, (void**)&pStream
);
2177 IPersistStream
*pDocStream
;
2178 hr
= IUnknown_QueryInterface(iface
, &IID_IPersistStream
, (void**)&pDocStream
);
2181 hr
= IPersistStream_Load(pDocStream
, pStream
);
2182 IStream_Release(pStream
);
2185 *isSuccessful
= VARIANT_TRUE
;
2187 TRACE("Using IStream to load Document\n");
2192 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr
);
2197 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr
);
2202 /* ISequentialStream */
2203 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr
, pNewDoc
, V_UNKNOWN(&source
)->lpVtbl
);
2207 FIXME("VT type not supported (%d)\n", V_VT(&source
));
2212 hr
= doread( This
, filename
);
2215 This
->error
= E_FAIL
;
2218 hr
= This
->error
= S_OK
;
2219 *isSuccessful
= VARIANT_TRUE
;
2223 if(!filename
|| FAILED(hr
)) {
2224 xmldoc
= xmlNewDoc(NULL
);
2225 xmldoc
->_private
= create_priv();
2226 hr
= attach_xmldoc(This
, xmldoc
);
2231 TRACE("ret (%d)\n", hr
);
2237 static HRESULT WINAPI
domdoc_get_readyState(
2238 IXMLDOMDocument3
*iface
,
2241 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2242 FIXME("stub! (%p)->(%p)\n", This
, value
);
2245 return E_INVALIDARG
;
2247 *value
= READYSTATE_COMPLETE
;
2252 static HRESULT WINAPI
domdoc_get_parseError(
2253 IXMLDOMDocument3
*iface
,
2254 IXMLDOMParseError
** errorObj
)
2256 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2257 static const WCHAR err
[] = {'e','r','r','o','r',0};
2258 BSTR error_string
= NULL
;
2260 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
2263 error_string
= SysAllocString(err
);
2265 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
2266 if(!*errorObj
) return E_OUTOFMEMORY
;
2271 static HRESULT WINAPI
domdoc_get_url(
2272 IXMLDOMDocument3
*iface
,
2275 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2276 FIXME("(%p)->(%p)\n", This
, urlString
);
2281 static HRESULT WINAPI
domdoc_get_async(
2282 IXMLDOMDocument3
*iface
,
2283 VARIANT_BOOL
* isAsync
)
2285 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2287 TRACE("(%p)->(%p: %d)\n", This
, isAsync
, This
->async
);
2288 *isAsync
= This
->async
;
2293 static HRESULT WINAPI
domdoc_put_async(
2294 IXMLDOMDocument3
*iface
,
2295 VARIANT_BOOL isAsync
)
2297 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2299 TRACE("(%p)->(%d)\n", This
, isAsync
);
2300 This
->async
= isAsync
;
2305 static HRESULT WINAPI
domdoc_abort(
2306 IXMLDOMDocument3
*iface
)
2308 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2309 FIXME("%p\n", This
);
2314 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2315 static HRESULT WINAPI
domdoc_loadXML(
2316 IXMLDOMDocument3
*iface
,
2318 VARIANT_BOOL
* isSuccessful
)
2320 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2321 xmlDocPtr xmldoc
= NULL
;
2322 HRESULT hr
= S_FALSE
, hr2
;
2324 TRACE("(%p)->(%s %p)\n", This
, debugstr_w( bstrXML
), isSuccessful
);
2326 assert ( &This
->node
);
2330 *isSuccessful
= VARIANT_FALSE
;
2334 xmldoc
= doparse(This
, (LPCSTR
)bstrXML
, lstrlenW(bstrXML
) * sizeof(*bstrXML
), XML_CHAR_ENCODING_UTF16LE
);
2337 This
->error
= E_FAIL
;
2338 TRACE("failed to parse document\n");
2342 hr
= This
->error
= S_OK
;
2343 *isSuccessful
= VARIANT_TRUE
;
2344 TRACE("parsed document %p\n", xmldoc
);
2349 xmldoc
= xmlNewDoc(NULL
);
2351 xmldoc
->_private
= create_priv();
2353 hr2
= attach_xmldoc(This
, xmldoc
);
2360 static int XMLCALL
domdoc_save_writecallback(void *ctx
, const char *buffer
, int len
)
2364 if(!WriteFile(ctx
, buffer
, len
, &written
, NULL
))
2366 WARN("write error\n");
2373 static int XMLCALL
domdoc_save_closecallback(void *ctx
)
2375 return CloseHandle(ctx
) ? 0 : -1;
2378 static int XMLCALL
domdoc_stream_save_writecallback(void *ctx
, const char *buffer
, int len
)
2383 hr
= IStream_Write((IStream
*)ctx
, buffer
, len
, &written
);
2386 WARN("stream write error: 0x%08x\n", hr
);
2393 static int XMLCALL
domdoc_stream_save_closecallback(void *ctx
)
2395 IStream_Release((IStream
*)ctx
);
2399 static HRESULT WINAPI
domdoc_save(
2400 IXMLDOMDocument3
*iface
,
2401 VARIANT destination
)
2403 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2404 xmlSaveCtxtPtr ctx
= NULL
;
2408 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&destination
));
2410 switch (V_VT(&destination
))
2414 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
2415 IXMLDOMDocument2
*document
;
2418 ret
= IUnknown_QueryInterface(pUnk
, &IID_IXMLDOMDocument3
, (void**)&document
);
2421 VARIANT_BOOL success
;
2424 ret
= IXMLDOMDocument3_get_xml(iface
, &xml
);
2427 ret
= IXMLDOMDocument3_loadXML(document
, xml
, &success
);
2431 IXMLDOMDocument3_Release(document
);
2435 ret
= IUnknown_QueryInterface(pUnk
, &IID_IStream
, (void**)&stream
);
2438 ctx
= xmlSaveToIO(domdoc_stream_save_writecallback
,
2439 domdoc_stream_save_closecallback
, stream
, NULL
, XML_SAVE_NO_DECL
);
2443 IStream_Release(stream
);
2451 case VT_BSTR
| VT_BYREF
:
2453 /* save with file path */
2454 HANDLE handle
= CreateFileW( (V_VT(&destination
) & VT_BYREF
)? *V_BSTRREF(&destination
) : V_BSTR(&destination
),
2455 GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2456 if( handle
== INVALID_HANDLE_VALUE
)
2458 WARN("failed to create file\n");
2462 /* disable top XML declaration */
2463 ctx
= xmlSaveToIO(domdoc_save_writecallback
, domdoc_save_closecallback
,
2464 handle
, NULL
, XML_SAVE_NO_DECL
);
2467 CloseHandle(handle
);
2474 FIXME("Unhandled VARIANT: %s\n", debugstr_variant(&destination
));
2478 xmldecl
= xmldoc_unlink_xmldecl(get_doc(This
));
2479 if (xmlSaveDoc(ctx
, get_doc(This
)) == -1) ret
= S_FALSE
;
2480 xmldoc_link_xmldecl(get_doc(This
), xmldecl
);
2482 /* will release resources through close callback */
2488 static HRESULT WINAPI
domdoc_get_validateOnParse(
2489 IXMLDOMDocument3
*iface
,
2490 VARIANT_BOOL
* isValidating
)
2492 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2493 TRACE("(%p)->(%p: %d)\n", This
, isValidating
, This
->validating
);
2494 *isValidating
= This
->validating
;
2499 static HRESULT WINAPI
domdoc_put_validateOnParse(
2500 IXMLDOMDocument3
*iface
,
2501 VARIANT_BOOL isValidating
)
2503 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2504 TRACE("(%p)->(%d)\n", This
, isValidating
);
2505 This
->validating
= isValidating
;
2510 static HRESULT WINAPI
domdoc_get_resolveExternals(
2511 IXMLDOMDocument3
*iface
,
2512 VARIANT_BOOL
* isResolving
)
2514 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2515 TRACE("(%p)->(%p: %d)\n", This
, isResolving
, This
->resolving
);
2516 *isResolving
= This
->resolving
;
2521 static HRESULT WINAPI
domdoc_put_resolveExternals(
2522 IXMLDOMDocument3
*iface
,
2523 VARIANT_BOOL isResolving
)
2525 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2526 TRACE("(%p)->(%d)\n", This
, isResolving
);
2527 This
->resolving
= isResolving
;
2532 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
2533 IXMLDOMDocument3
*iface
,
2534 VARIANT_BOOL
* isPreserving
)
2536 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2537 TRACE("(%p)->(%p: %d)\n", This
, isPreserving
, This
->properties
->preserving
);
2538 *isPreserving
= This
->properties
->preserving
;
2543 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
2544 IXMLDOMDocument3
*iface
,
2545 VARIANT_BOOL isPreserving
)
2547 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2548 TRACE("(%p)->(%d)\n", This
, isPreserving
);
2549 This
->properties
->preserving
= isPreserving
;
2554 static HRESULT WINAPI
domdoc_put_onreadystatechange(
2555 IXMLDOMDocument3
*iface
,
2558 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2560 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&event
));
2561 return set_doc_event(This
, EVENTID_READYSTATECHANGE
, &event
);
2565 static HRESULT WINAPI
domdoc_put_onDataAvailable(
2566 IXMLDOMDocument3
*iface
,
2567 VARIANT onDataAvailableSink
)
2569 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2570 FIXME("%p\n", This
);
2574 static HRESULT WINAPI
domdoc_put_onTransformNode(
2575 IXMLDOMDocument3
*iface
,
2576 VARIANT onTransformNodeSink
)
2578 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2579 FIXME("%p\n", This
);
2583 static HRESULT WINAPI
domdoc_get_namespaces(
2584 IXMLDOMDocument3
* iface
,
2585 IXMLDOMSchemaCollection
** schemaCollection
)
2587 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2588 FIXME("(%p)->(%p)\n", This
, schemaCollection
);
2592 static HRESULT WINAPI
domdoc_get_schemas(
2593 IXMLDOMDocument3
* iface
,
2596 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2597 HRESULT hr
= S_FALSE
;
2598 IXMLDOMSchemaCollection2
* cur_schema
= This
->properties
->schemaCache
;
2600 TRACE("(%p)->(%p)\n", This
, var1
);
2602 VariantInit(var1
); /* Test shows we don't call VariantClear here */
2603 V_VT(var1
) = VT_NULL
;
2607 hr
= IXMLDOMSchemaCollection2_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(var1
));
2609 V_VT(var1
) = VT_DISPATCH
;
2614 static HRESULT WINAPI
domdoc_putref_schemas(
2615 IXMLDOMDocument3
* iface
,
2618 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2619 HRESULT hr
= E_FAIL
;
2620 IXMLDOMSchemaCollection2
* new_schema
= NULL
;
2622 FIXME("(%p): semi-stub\n", This
);
2626 hr
= IUnknown_QueryInterface(V_UNKNOWN(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2630 hr
= IDispatch_QueryInterface(V_DISPATCH(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2639 WARN("Can't get schema from vt %x\n", V_VT(&var1
));
2644 IXMLDOMSchemaCollection2
* old_schema
= InterlockedExchangePointer((void**)&This
->properties
->schemaCache
, new_schema
);
2645 if(old_schema
) IXMLDOMSchemaCollection2_Release(old_schema
);
2651 static inline BOOL
is_wellformed(xmlDocPtr doc
)
2653 #ifdef HAVE_XMLDOC_PROPERTIES
2654 return doc
->properties
& XML_DOC_WELLFORMED
;
2656 /* Not a full check, but catches the worst violations */
2660 for (child
= doc
->children
; child
!= NULL
; child
= child
->next
)
2662 switch (child
->type
)
2664 case XML_ELEMENT_NODE
:
2669 case XML_CDATA_SECTION_NODE
:
2681 static void LIBXML2_LOG_CALLBACK
validate_error(void* ctx
, char const* msg
, ...)
2685 LIBXML2_CALLBACK_ERR(domdoc_validateNode
, msg
, ap
);
2689 static void LIBXML2_LOG_CALLBACK
validate_warning(void* ctx
, char const* msg
, ...)
2693 LIBXML2_CALLBACK_WARN(domdoc_validateNode
, msg
, ap
);
2697 static HRESULT WINAPI
domdoc_validateNode(
2698 IXMLDOMDocument3
* iface
,
2700 IXMLDOMParseError
** err
)
2702 domdoc
* This
= impl_from_IXMLDOMDocument3(iface
);
2703 LONG state
, err_code
= 0;
2707 TRACE("(%p)->(%p, %p)\n", This
, node
, err
);
2708 domdoc_get_readyState(iface
, &state
);
2709 if (state
!= READYSTATE_COMPLETE
)
2712 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2719 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2723 if (!get_node_obj(node
)->node
|| get_node_obj(node
)->node
->doc
!= get_doc(This
))
2726 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2730 if (!is_wellformed(get_doc(This
)))
2732 ERR("doc not well-formed\n");
2734 *err
= create_parseError(E_XML_NOTWF
, NULL
, NULL
, NULL
, 0, 0, 0);
2738 /* DTD validation */
2739 if (get_doc(This
)->intSubset
|| get_doc(This
)->extSubset
)
2741 xmlValidCtxtPtr vctx
= xmlNewValidCtxt();
2742 vctx
->error
= validate_error
;
2743 vctx
->warning
= validate_warning
;
2746 if (!((node
== (IXMLDOMNode
*)iface
)?
2747 xmlValidateDocument(vctx
, get_doc(This
)) :
2748 xmlValidateElement(vctx
, get_doc(This
), get_node_obj(node
)->node
)))
2750 /* TODO: get a real error code here */
2751 TRACE("DTD validation failed\n");
2752 err_code
= E_XML_INVALID
;
2755 xmlFreeValidCtxt(vctx
);
2758 /* Schema validation */
2759 if (hr
== S_OK
&& This
->properties
->schemaCache
!= NULL
)
2762 hr
= SchemaCache_validate_tree(This
->properties
->schemaCache
, get_node_obj(node
)->node
);
2766 /* TODO: get a real error code here */
2769 TRACE("schema validation succeeded\n");
2773 ERR("schema validation failed\n");
2774 err_code
= E_XML_INVALID
;
2779 /* not really OK, just didn't find a schema for the ns */
2786 ERR("no DTD or schema found\n");
2787 err_code
= E_XML_NODTD
;
2792 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2797 static HRESULT WINAPI
domdoc_validate(
2798 IXMLDOMDocument3
* iface
,
2799 IXMLDOMParseError
** err
)
2801 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2802 TRACE("(%p)->(%p)\n", This
, err
);
2803 return domdoc_validateNode(iface
, (IXMLDOMNode
*)iface
, err
);
2806 static HRESULT WINAPI
domdoc_setProperty(
2807 IXMLDOMDocument3
* iface
,
2811 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2813 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
2815 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2821 V_VT(&varStr
) = VT_EMPTY
;
2822 if (V_VT(&var
) != VT_BSTR
)
2824 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2826 bstr
= V_BSTR(&varStr
);
2829 bstr
= V_BSTR(&var
);
2832 if (lstrcmpiW(bstr
, PropValueXPathW
) == 0)
2833 This
->properties
->XPath
= TRUE
;
2834 else if (lstrcmpiW(bstr
, PropValueXSLPatternW
) == 0)
2835 This
->properties
->XPath
= FALSE
;
2839 VariantClear(&varStr
);
2842 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2847 xmlChar
*pTokBegin
, *pTokEnd
, *pTokInner
;
2848 xmlChar
*nsStr
= (xmlChar
*)This
->properties
->selectNsStr
;
2849 xmlXPathContextPtr ctx
;
2850 struct list
*pNsList
;
2851 select_ns_entry
* pNsEntry
= NULL
;
2853 V_VT(&varStr
) = VT_EMPTY
;
2854 if (V_VT(&var
) != VT_BSTR
)
2856 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2858 bstr
= V_BSTR(&varStr
);
2861 bstr
= V_BSTR(&var
);
2865 pNsList
= &(This
->properties
->selectNsList
);
2866 clear_selectNsList(pNsList
);
2868 nsStr
= xmlchar_from_wchar(bstr
);
2870 TRACE("Setting SelectionNamespaces property to: %s\n", nsStr
);
2872 This
->properties
->selectNsStr
= nsStr
;
2873 This
->properties
->selectNsStr_len
= xmlStrlen(nsStr
);
2876 ctx
= xmlXPathNewContext(This
->node
.node
->doc
);
2878 for (; *pTokBegin
; pTokBegin
= pTokEnd
)
2880 if (pNsEntry
!= NULL
)
2881 memset(pNsEntry
, 0, sizeof(select_ns_entry
));
2883 pNsEntry
= heap_alloc_zero(sizeof(select_ns_entry
));
2885 while (*pTokBegin
== ' ')
2887 pTokEnd
= pTokBegin
;
2888 while (*pTokEnd
!= ' ' && *pTokEnd
!= 0)
2891 if (xmlStrncmp(pTokBegin
, (xmlChar
const*)"xmlns", 5) != 0)
2894 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2895 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2900 if (*pTokBegin
== '=')
2902 /*valid for XSLPattern?*/
2903 FIXME("Setting default xmlns not supported - skipping.\n");
2906 else if (*pTokBegin
== ':')
2908 pNsEntry
->prefix
= ++pTokBegin
;
2909 for (pTokInner
= pTokBegin
; pTokInner
!= pTokEnd
&& *pTokInner
!= '='; ++pTokInner
)
2912 if (pTokInner
== pTokEnd
)
2915 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2916 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2920 pNsEntry
->prefix_end
= *pTokInner
;
2924 if (pTokEnd
-pTokInner
> 1 &&
2925 ((*pTokInner
== '\'' && *(pTokEnd
-1) == '\'') ||
2926 (*pTokInner
== '"' && *(pTokEnd
-1) == '"')))
2928 pNsEntry
->href
= ++pTokInner
;
2929 pNsEntry
->href_end
= *(pTokEnd
-1);
2931 list_add_tail(pNsList
, &pNsEntry
->entry
);
2932 /*let libxml figure out if they're valid from here ;)*/
2933 if (xmlXPathRegisterNs(ctx
, pNsEntry
->prefix
, pNsEntry
->href
) != 0)
2942 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2943 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokInner
, pTokEnd
-pTokInner
));
2944 list_add_tail(pNsList
, &pNsEntry
->entry
);
2957 heap_free(pNsEntry
);
2958 xmlXPathFreeContext(ctx
);
2961 VariantClear(&varStr
);
2964 else if (lstrcmpiW(p
, PropertyProhibitDTDW
) == 0 ||
2965 lstrcmpiW(p
, PropertyNewParserW
) == 0 ||
2966 lstrcmpiW(p
, PropertyResolveExternalsW
) == 0)
2969 FIXME("Ignoring property %s, value %d\n", debugstr_w(p
), V_BOOL(&var
));
2973 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2977 static HRESULT WINAPI
domdoc_getProperty(
2978 IXMLDOMDocument3
* iface
,
2982 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2984 TRACE("(%p)->(%p)\n", This
, debugstr_w(p
));
2987 return E_INVALIDARG
;
2989 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2991 V_VT(var
) = VT_BSTR
;
2992 V_BSTR(var
) = This
->properties
->XPath
?
2993 SysAllocString(PropValueXPathW
) :
2994 SysAllocString(PropValueXSLPatternW
);
2995 return V_BSTR(var
) ? S_OK
: E_OUTOFMEMORY
;
2997 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
3000 BSTR rebuiltStr
, cur
;
3001 const xmlChar
*nsStr
;
3002 struct list
*pNsList
;
3003 select_ns_entry
* pNsEntry
;
3005 V_VT(var
) = VT_BSTR
;
3006 nsStr
= This
->properties
->selectNsStr
;
3007 pNsList
= &This
->properties
->selectNsList
;
3008 lenA
= This
->properties
->selectNsStr_len
;
3009 lenW
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, NULL
, 0);
3010 rebuiltStr
= heap_alloc(lenW
*sizeof(WCHAR
));
3011 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, rebuiltStr
, lenW
);
3013 /* this is fine because all of the chars that end tokens are ASCII*/
3014 LIST_FOR_EACH_ENTRY(pNsEntry
, pNsList
, select_ns_entry
, entry
)
3016 while (*cur
!= 0) ++cur
;
3017 if (pNsEntry
->prefix_end
)
3019 *cur
= pNsEntry
->prefix_end
;
3020 while (*cur
!= 0) ++cur
;
3023 if (pNsEntry
->href_end
)
3025 *cur
= pNsEntry
->href_end
;
3028 V_BSTR(var
) = SysAllocString(rebuiltStr
);
3029 heap_free(rebuiltStr
);
3033 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
3037 static HRESULT WINAPI
domdoc_importNode(
3038 IXMLDOMDocument3
* iface
,
3041 IXMLDOMNode
** clone
)
3043 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
3044 FIXME("(%p)->(%p %d %p): stub\n", This
, node
, deep
, clone
);
3048 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl
=
3050 domdoc_QueryInterface
,
3053 domdoc_GetTypeInfoCount
,
3055 domdoc_GetIDsOfNames
,
3057 domdoc_get_nodeName
,
3058 domdoc_get_nodeValue
,
3059 domdoc_put_nodeValue
,
3060 domdoc_get_nodeType
,
3061 domdoc_get_parentNode
,
3062 domdoc_get_childNodes
,
3063 domdoc_get_firstChild
,
3064 domdoc_get_lastChild
,
3065 domdoc_get_previousSibling
,
3066 domdoc_get_nextSibling
,
3067 domdoc_get_attributes
,
3068 domdoc_insertBefore
,
3069 domdoc_replaceChild
,
3072 domdoc_hasChildNodes
,
3073 domdoc_get_ownerDocument
,
3075 domdoc_get_nodeTypeString
,
3078 domdoc_get_specified
,
3079 domdoc_get_definition
,
3080 domdoc_get_nodeTypedValue
,
3081 domdoc_put_nodeTypedValue
,
3082 domdoc_get_dataType
,
3083 domdoc_put_dataType
,
3085 domdoc_transformNode
,
3087 domdoc_selectSingleNode
,
3089 domdoc_get_namespaceURI
,
3091 domdoc_get_baseName
,
3092 domdoc_transformNodeToObject
,
3094 domdoc_get_implementation
,
3095 domdoc_get_documentElement
,
3096 domdoc_put_documentElement
,
3097 domdoc_createElement
,
3098 domdoc_createDocumentFragment
,
3099 domdoc_createTextNode
,
3100 domdoc_createComment
,
3101 domdoc_createCDATASection
,
3102 domdoc_createProcessingInstruction
,
3103 domdoc_createAttribute
,
3104 domdoc_createEntityReference
,
3105 domdoc_getElementsByTagName
,
3109 domdoc_get_readyState
,
3110 domdoc_get_parseError
,
3117 domdoc_get_validateOnParse
,
3118 domdoc_put_validateOnParse
,
3119 domdoc_get_resolveExternals
,
3120 domdoc_put_resolveExternals
,
3121 domdoc_get_preserveWhiteSpace
,
3122 domdoc_put_preserveWhiteSpace
,
3123 domdoc_put_onreadystatechange
,
3124 domdoc_put_onDataAvailable
,
3125 domdoc_put_onTransformNode
,
3126 domdoc_get_namespaces
,
3128 domdoc_putref_schemas
,
3132 domdoc_validateNode
,
3136 /* IConnectionPointContainer */
3137 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
3138 REFIID riid
, void **ppv
)
3140 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3141 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3144 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
3146 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3147 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3150 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
3152 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3153 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3156 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
3157 IEnumConnectionPoints
**ppEnum
)
3159 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3160 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3164 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
3165 REFIID riid
, IConnectionPoint
**cp
)
3167 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3168 ConnectionPoint
*iter
;
3170 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), cp
);
3174 for(iter
= This
->cp_list
; iter
; iter
= iter
->next
)
3176 if (IsEqualGUID(iter
->iid
, riid
))
3177 *cp
= &iter
->IConnectionPoint_iface
;
3182 IConnectionPoint_AddRef(*cp
);
3186 FIXME("unsupported riid %s\n", debugstr_guid(riid
));
3187 return CONNECT_E_NOCONNECTION
;
3191 static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
3193 ConnectionPointContainer_QueryInterface
,
3194 ConnectionPointContainer_AddRef
,
3195 ConnectionPointContainer_Release
,
3196 ConnectionPointContainer_EnumConnectionPoints
,
3197 ConnectionPointContainer_FindConnectionPoint
3200 /* IConnectionPoint */
3201 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
3202 REFIID riid
, void **ppv
)
3204 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3206 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
3210 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
3211 IsEqualGUID(&IID_IConnectionPoint
, riid
))
3218 IConnectionPoint_AddRef(iface
);
3222 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
3223 return E_NOINTERFACE
;
3226 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
3228 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3229 return IConnectionPointContainer_AddRef(This
->container
);
3232 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
3234 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3235 return IConnectionPointContainer_Release(This
->container
);
3238 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*iid
)
3240 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3242 TRACE("(%p)->(%p)\n", This
, iid
);
3244 if (!iid
) return E_POINTER
;
3250 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
3251 IConnectionPointContainer
**container
)
3253 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3255 TRACE("(%p)->(%p)\n", This
, container
);
3257 if (!container
) return E_POINTER
;
3259 *container
= This
->container
;
3260 IConnectionPointContainer_AddRef(*container
);
3264 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
3267 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3268 FIXME("(%p)->(%p %p): stub\n", This
, pUnkSink
, pdwCookie
);
3272 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD cookie
)
3274 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3276 TRACE("(%p)->(%d)\n", This
, cookie
);
3278 if (cookie
== 0 || cookie
> This
->sinks_size
|| !This
->sinks
[cookie
-1].unk
)
3279 return CONNECT_E_NOCONNECTION
;
3281 IUnknown_Release(This
->sinks
[cookie
-1].unk
);
3282 This
->sinks
[cookie
-1].unk
= NULL
;
3287 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
3288 IEnumConnections
**ppEnum
)
3290 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3291 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3295 static const IConnectionPointVtbl ConnectionPointVtbl
=
3297 ConnectionPoint_QueryInterface
,
3298 ConnectionPoint_AddRef
,
3299 ConnectionPoint_Release
,
3300 ConnectionPoint_GetConnectionInterface
,
3301 ConnectionPoint_GetConnectionPointContainer
,
3302 ConnectionPoint_Advise
,
3303 ConnectionPoint_Unadvise
,
3304 ConnectionPoint_EnumConnections
3307 static void ConnectionPoint_Init(ConnectionPoint
*cp
, struct domdoc
*doc
, REFIID riid
)
3309 cp
->IConnectionPoint_iface
.lpVtbl
= &ConnectionPointVtbl
;
3315 cp
->next
= doc
->cp_list
;
3318 cp
->container
= &doc
->IConnectionPointContainer_iface
;
3321 /* domdoc implementation of IObjectWithSite */
3322 static HRESULT WINAPI
3323 domdoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
3325 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3326 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObject
);
3329 static ULONG WINAPI
domdoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
3331 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3332 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3335 static ULONG WINAPI
domdoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
3337 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3338 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3341 static HRESULT WINAPI
domdoc_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
3343 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3345 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
3350 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
3353 static HRESULT WINAPI
domdoc_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
3355 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3357 TRACE("(%p)->(%p)\n", iface
, punk
);
3363 IUnknown_Release( This
->site
);
3370 IUnknown_AddRef( punk
);
3373 IUnknown_Release( This
->site
);
3380 static const IObjectWithSiteVtbl domdocObjectSite
=
3382 domdoc_ObjectWithSite_QueryInterface
,
3383 domdoc_ObjectWithSite_AddRef
,
3384 domdoc_ObjectWithSite_Release
,
3385 domdoc_ObjectWithSite_SetSite
,
3386 domdoc_ObjectWithSite_GetSite
3389 static HRESULT WINAPI
domdoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
3391 domdoc
*This
= impl_from_IObjectSafety(iface
);
3392 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3395 static ULONG WINAPI
domdoc_Safety_AddRef(IObjectSafety
*iface
)
3397 domdoc
*This
= impl_from_IObjectSafety(iface
);
3398 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3401 static ULONG WINAPI
domdoc_Safety_Release(IObjectSafety
*iface
)
3403 domdoc
*This
= impl_from_IObjectSafety(iface
);
3404 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3407 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
3409 static HRESULT WINAPI
domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3410 DWORD
*supported
, DWORD
*enabled
)
3412 domdoc
*This
= impl_from_IObjectSafety(iface
);
3414 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
3416 if(!supported
|| !enabled
) return E_POINTER
;
3418 *supported
= SAFETY_SUPPORTED_OPTIONS
;
3419 *enabled
= This
->safeopt
;
3424 static HRESULT WINAPI
domdoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3425 DWORD mask
, DWORD enabled
)
3427 domdoc
*This
= impl_from_IObjectSafety(iface
);
3428 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
3430 if ((mask
& ~SAFETY_SUPPORTED_OPTIONS
) != 0)
3433 This
->safeopt
= (This
->safeopt
& ~mask
) | (mask
& enabled
);
3438 #undef SAFETY_SUPPORTED_OPTIONS
3440 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
3441 domdoc_Safety_QueryInterface
,
3442 domdoc_Safety_AddRef
,
3443 domdoc_Safety_Release
,
3444 domdoc_Safety_GetInterfaceSafetyOptions
,
3445 domdoc_Safety_SetInterfaceSafetyOptions
3448 static const tid_t domdoc_iface_tids
[] = {
3450 IXMLDOMDocument_tid
,
3451 IXMLDOMDocument2_tid
,
3454 static dispex_static_data_t domdoc_dispex
= {
3456 IXMLDOMDocument2_tid
,
3461 HRESULT
get_domdoc_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument3
**document
)
3465 doc
= heap_alloc( sizeof (*doc
) );
3467 return E_OUTOFMEMORY
;
3469 doc
->IXMLDOMDocument3_iface
.lpVtbl
= &domdoc_vtbl
;
3470 doc
->IPersistStreamInit_iface
.lpVtbl
= &xmldoc_IPersistStreamInit_VTable
;
3471 doc
->IObjectWithSite_iface
.lpVtbl
= &domdocObjectSite
;
3472 doc
->IObjectSafety_iface
.lpVtbl
= &domdocObjectSafetyVtbl
;
3473 doc
->ISupportErrorInfo_iface
.lpVtbl
= &support_error_vtbl
;
3474 doc
->IConnectionPointContainer_iface
.lpVtbl
= &ConnectionPointContainerVtbl
;
3476 doc
->async
= VARIANT_TRUE
;
3477 doc
->validating
= 0;
3479 doc
->properties
= properties_from_xmlDocPtr(xmldoc
);
3485 doc
->cp_list
= NULL
;
3486 memset(doc
->events
, 0, sizeof(doc
->events
));
3488 /* events connection points */
3489 ConnectionPoint_Init(&doc
->cp_dispatch
, doc
, &IID_IDispatch
);
3490 ConnectionPoint_Init(&doc
->cp_propnotif
, doc
, &IID_IPropertyNotifySink
);
3491 ConnectionPoint_Init(&doc
->cp_domdocevents
, doc
, &DIID_XMLDOMDocumentEvents
);
3493 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IXMLDOMNode
*)&doc
->IXMLDOMDocument3_iface
,
3496 *document
= &doc
->IXMLDOMDocument3_iface
;
3498 TRACE("returning iface %p\n", *document
);
3502 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3507 TRACE("(%d, %p, %p)\n", version
, pUnkOuter
, ppObj
);
3509 xmldoc
= xmlNewDoc(NULL
);
3511 return E_OUTOFMEMORY
;
3513 xmldoc
->_private
= create_priv();
3514 priv_from_xmlDocPtr(xmldoc
)->properties
= create_properties(version
);
3516 hr
= get_domdoc_from_xmldoc(xmldoc
, (IXMLDOMDocument3
**)ppObj
);
3519 free_properties(properties_from_xmlDocPtr(xmldoc
));
3520 heap_free(xmldoc
->_private
);
3528 IUnknown
* create_domdoc( xmlNodePtr document
)
3533 TRACE("(%p)\n", document
);
3535 hr
= get_domdoc_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument3
**)&pObj
);
3544 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3546 MESSAGE("This program tried to use a DOMDocument object, but\n"
3547 "libxml2 support was not present at compile time.\n");