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. */
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 IConnectionPointContainer IConnectionPointContainer_iface
;
129 VARIANT_BOOL validating
;
130 VARIANT_BOOL resolving
;
131 domdoc_properties
* properties
;
141 /* connection list */
142 ConnectionPoint
*cp_list
;
143 ConnectionPoint cp_domdocevents
;
144 ConnectionPoint cp_propnotif
;
145 ConnectionPoint cp_dispatch
;
148 IDispatch
*events
[EVENTID_LAST
];
150 IXMLDOMSchemaCollection2
*namespaces
;
153 static HRESULT
set_doc_event(domdoc
*doc
, eventid_t eid
, const VARIANT
*v
)
161 IUnknown_QueryInterface(V_UNKNOWN(v
), &IID_IDispatch
, (void**)&disp
);
166 disp
= V_DISPATCH(v
);
167 if (disp
) IDispatch_AddRef(disp
);
170 return DISP_E_TYPEMISMATCH
;
173 if (doc
->events
[eid
]) IDispatch_Release(doc
->events
[eid
]);
174 doc
->events
[eid
] = disp
;
179 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
181 return CONTAINING_RECORD(iface
, ConnectionPoint
, IConnectionPoint_iface
);
185 In native windows, the whole lifetime management of XMLDOMNodes is
186 managed automatically using reference counts. Wine emulates that by
187 maintaining a reference count to the document that is increased for
188 each IXMLDOMNode pointer passed out for this document. If all these
189 pointers are gone, the document is unreachable and gets freed, that
190 is, all nodes in the tree of the document get freed.
192 You are able to create nodes that are associated to a document (in
193 fact, in msxml's XMLDOM model, all nodes are associated to a document),
194 but not in the tree of that document, for example using the createFoo
195 functions from IXMLDOMDocument. These nodes do not get cleaned up
196 by libxml, so we have to do it ourselves.
198 To catch these nodes, a list of "orphan nodes" is introduced.
199 It contains pointers to all roots of node trees that are
200 associated with the document without being part of the document
201 tree. All nodes with parent==NULL (except for the document root nodes)
202 should be in the orphan node list of their document. All orphan nodes
203 get freed together with the document itself.
206 typedef struct _xmldoc_priv
{
209 domdoc_properties
* properties
;
212 typedef struct _orphan_entry
{
217 typedef struct _select_ns_entry
{
219 xmlChar
const* prefix
;
225 static inline xmldoc_priv
* priv_from_xmlDocPtr(const xmlDocPtr doc
)
227 return doc
->_private
;
230 static inline domdoc_properties
* properties_from_xmlDocPtr(xmlDocPtr doc
)
232 return priv_from_xmlDocPtr(doc
)->properties
;
235 BOOL
is_xpathmode(const xmlDocPtr doc
)
237 return properties_from_xmlDocPtr(doc
)->XPath
;
240 void set_xpathmode(xmlDocPtr doc
, BOOL xpath
)
242 properties_from_xmlDocPtr(doc
)->XPath
= xpath
;
245 int registerNamespaces(xmlXPathContextPtr ctxt
)
248 const select_ns_entry
* ns
= NULL
;
249 const struct list
* pNsList
= &properties_from_xmlDocPtr(ctxt
->doc
)->selectNsList
;
251 TRACE("(%p)\n", ctxt
);
253 LIST_FOR_EACH_ENTRY( ns
, pNsList
, select_ns_entry
, entry
)
255 xmlXPathRegisterNs(ctxt
, ns
->prefix
, ns
->href
);
262 static inline void clear_selectNsList(struct list
* pNsList
)
264 select_ns_entry
*ns
, *ns2
;
265 LIST_FOR_EACH_ENTRY_SAFE( ns
, ns2
, pNsList
, select_ns_entry
, entry
)
272 static xmldoc_priv
* create_priv(void)
275 priv
= heap_alloc( sizeof (*priv
) );
280 list_init( &priv
->orphans
);
281 priv
->properties
= NULL
;
287 static domdoc_properties
*create_properties(MSXML_VERSION version
)
289 domdoc_properties
*properties
= heap_alloc(sizeof(domdoc_properties
));
291 list_init(&properties
->selectNsList
);
292 properties
->preserving
= VARIANT_FALSE
;
293 properties
->schemaCache
= NULL
;
294 properties
->selectNsStr
= heap_alloc_zero(sizeof(xmlChar
));
295 properties
->selectNsStr_len
= 0;
297 /* properties that are dependent on object versions */
298 properties
->version
= version
;
299 properties
->XPath
= (version
== MSXML4
|| version
== MSXML6
);
304 static domdoc_properties
* copy_properties(domdoc_properties
const* properties
)
306 domdoc_properties
* pcopy
= heap_alloc(sizeof(domdoc_properties
));
307 select_ns_entry
const* ns
= NULL
;
308 select_ns_entry
* new_ns
= NULL
;
309 int len
= (properties
->selectNsStr_len
+1)*sizeof(xmlChar
);
314 pcopy
->version
= properties
->version
;
315 pcopy
->preserving
= properties
->preserving
;
316 pcopy
->schemaCache
= properties
->schemaCache
;
317 if (pcopy
->schemaCache
)
318 IXMLDOMSchemaCollection2_AddRef(pcopy
->schemaCache
);
319 pcopy
->XPath
= properties
->XPath
;
320 pcopy
->selectNsStr_len
= properties
->selectNsStr_len
;
321 list_init( &pcopy
->selectNsList
);
322 pcopy
->selectNsStr
= heap_alloc(len
);
323 memcpy((xmlChar
*)pcopy
->selectNsStr
, properties
->selectNsStr
, len
);
324 offset
= pcopy
->selectNsStr
- properties
->selectNsStr
;
326 LIST_FOR_EACH_ENTRY( ns
, (&properties
->selectNsList
), select_ns_entry
, entry
)
328 new_ns
= heap_alloc(sizeof(select_ns_entry
));
329 memcpy(new_ns
, ns
, sizeof(select_ns_entry
));
330 new_ns
->href
+= offset
;
331 new_ns
->prefix
+= offset
;
332 list_add_tail(&pcopy
->selectNsList
, &new_ns
->entry
);
340 static void free_properties(domdoc_properties
* properties
)
344 if (properties
->schemaCache
)
345 IXMLDOMSchemaCollection2_Release(properties
->schemaCache
);
346 clear_selectNsList(&properties
->selectNsList
);
347 heap_free((xmlChar
*)properties
->selectNsStr
);
348 heap_free(properties
);
352 static void release_namespaces(domdoc
*This
)
354 if (This
->namespaces
)
356 IXMLDOMSchemaCollection2_Release(This
->namespaces
);
357 This
->namespaces
= NULL
;
361 /* links a "<?xml" node as a first child */
362 void xmldoc_link_xmldecl(xmlDocPtr doc
, xmlNodePtr node
)
365 if (doc
->standalone
!= -1) xmlAddPrevSibling( doc
->children
, node
);
368 /* unlinks a first "<?xml" child if it was created */
369 xmlNodePtr
xmldoc_unlink_xmldecl(xmlDocPtr doc
)
371 static const xmlChar xmlA
[] = "xml";
372 xmlNodePtr node
, first_child
;
376 /* xml declaration node could be created automatically after parsing or added
378 first_child
= doc
->children
;
379 if (first_child
&& first_child
->type
== XML_PI_NODE
&& xmlStrEqual(first_child
->name
, xmlA
))
382 xmlUnlinkNode( node
);
390 BOOL
is_preserving_whitespace(xmlNodePtr node
)
392 domdoc_properties
* properties
= NULL
;
393 /* during parsing the xmlDoc._private stuff is not there */
394 if (priv_from_xmlDocPtr(node
->doc
))
395 properties
= properties_from_xmlDocPtr(node
->doc
);
396 return ((properties
&& properties
->preserving
== VARIANT_TRUE
) ||
397 xmlNodeGetSpacePreserve(node
) == 1);
400 static inline BOOL
strn_isspace(xmlChar
const* str
, int len
)
402 for (; str
&& len
> 0 && *str
; ++str
, --len
)
409 static void sax_characters(void *ctx
, const xmlChar
*ch
, int len
)
411 xmlParserCtxtPtr ctxt
;
414 ctxt
= (xmlParserCtxtPtr
) ctx
;
415 This
= (const domdoc
*) ctxt
->_private
;
419 /* during domdoc_loadXML() the xmlDocPtr->_private data is not available */
420 if (!This
->properties
->preserving
&&
421 !is_preserving_whitespace(ctxt
->node
) &&
422 strn_isspace(ch
, len
))
426 xmlSAX2Characters(ctxt
, ch
, len
);
429 static void LIBXML2_LOG_CALLBACK
sax_error(void* ctx
, char const* msg
, ...)
433 LIBXML2_CALLBACK_ERR(doparse
, msg
, ap
);
437 static void LIBXML2_LOG_CALLBACK
sax_warning(void* ctx
, char const* msg
, ...)
441 LIBXML2_CALLBACK_WARN(doparse
, msg
, ap
);
445 static void sax_serror(void* ctx
, xmlErrorPtr err
)
447 LIBXML2_CALLBACK_SERROR(doparse
, err
);
450 static xmlDocPtr
doparse(domdoc
* This
, char const* ptr
, int len
, xmlCharEncoding encoding
)
452 xmlDocPtr doc
= NULL
;
453 xmlParserCtxtPtr pctx
;
454 static xmlSAXHandler sax_handler
= {
455 xmlSAX2InternalSubset
, /* internalSubset */
456 xmlSAX2IsStandalone
, /* isStandalone */
457 xmlSAX2HasInternalSubset
, /* hasInternalSubset */
458 xmlSAX2HasExternalSubset
, /* hasExternalSubset */
459 xmlSAX2ResolveEntity
, /* resolveEntity */
460 xmlSAX2GetEntity
, /* getEntity */
461 xmlSAX2EntityDecl
, /* entityDecl */
462 xmlSAX2NotationDecl
, /* notationDecl */
463 xmlSAX2AttributeDecl
, /* attributeDecl */
464 xmlSAX2ElementDecl
, /* elementDecl */
465 xmlSAX2UnparsedEntityDecl
, /* unparsedEntityDecl */
466 xmlSAX2SetDocumentLocator
, /* setDocumentLocator */
467 xmlSAX2StartDocument
, /* startDocument */
468 xmlSAX2EndDocument
, /* endDocument */
469 xmlSAX2StartElement
, /* startElement */
470 xmlSAX2EndElement
, /* endElement */
471 xmlSAX2Reference
, /* reference */
472 sax_characters
, /* characters */
473 sax_characters
, /* ignorableWhitespace */
474 xmlSAX2ProcessingInstruction
, /* processingInstruction */
475 xmlSAX2Comment
, /* comment */
476 sax_warning
, /* warning */
477 sax_error
, /* error */
478 sax_error
, /* fatalError */
479 xmlSAX2GetParameterEntity
, /* getParameterEntity */
480 xmlSAX2CDataBlock
, /* cdataBlock */
481 xmlSAX2ExternalSubset
, /* externalSubset */
484 xmlSAX2StartElementNs
, /* startElementNs */
485 xmlSAX2EndElementNs
, /* endElementNs */
486 sax_serror
/* serror */
489 pctx
= xmlCreateMemoryParserCtxt(ptr
, len
);
492 ERR("Failed to create parser context\n");
496 if (pctx
->sax
) xmlFree(pctx
->sax
);
497 pctx
->sax
= &sax_handler
;
498 pctx
->_private
= This
;
501 if (encoding
!= XML_CHAR_ENCODING_NONE
)
502 xmlSwitchEncoding(pctx
, encoding
);
504 xmlParseDocument(pctx
);
506 if (pctx
->wellFormed
)
512 xmlFreeDoc(pctx
->myDoc
);
516 xmlFreeParserCtxt(pctx
);
518 /* TODO: put this in one of the SAX callbacks */
519 /* create first child as a <?xml...?> */
520 if (doc
&& doc
->standalone
!= -1)
524 xmlChar
*xmlbuff
= (xmlChar
*)buff
;
526 node
= xmlNewDocPI( doc
, (xmlChar
*)"xml", NULL
);
528 /* version attribute can't be omitted */
529 sprintf(buff
, "version=\"%s\"", doc
->version
? (char*)doc
->version
: "1.0");
530 xmlNodeAddContent( node
, xmlbuff
);
534 sprintf(buff
, " encoding=\"%s\"", doc
->encoding
);
535 xmlNodeAddContent( node
, xmlbuff
);
538 if (doc
->standalone
!= -2)
540 sprintf(buff
, " standalone=\"%s\"", doc
->standalone
== 0 ? "no" : "yes");
541 xmlNodeAddContent( node
, xmlbuff
);
544 xmldoc_link_xmldecl( doc
, node
);
550 void xmldoc_init(xmlDocPtr doc
, MSXML_VERSION version
)
552 doc
->_private
= create_priv();
553 priv_from_xmlDocPtr(doc
)->properties
= create_properties(version
);
556 LONG
xmldoc_add_ref(xmlDocPtr doc
)
558 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
559 TRACE("(%p)->(%d)\n", doc
, ref
);
563 LONG
xmldoc_release(xmlDocPtr doc
)
565 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
566 LONG ref
= InterlockedDecrement(&priv
->refs
);
567 TRACE("(%p)->(%d)\n", doc
, ref
);
570 orphan_entry
*orphan
, *orphan2
;
571 TRACE("freeing docptr %p\n", doc
);
573 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
575 xmlFreeNode( orphan
->node
);
578 free_properties(priv
->properties
);
579 heap_free(doc
->_private
);
587 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
589 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
592 entry
= heap_alloc( sizeof (*entry
) );
594 return E_OUTOFMEMORY
;
597 list_add_head( &priv
->orphans
, &entry
->entry
);
601 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
603 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
604 orphan_entry
*entry
, *entry2
;
606 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
608 if( entry
->node
== node
)
610 list_remove( &entry
->entry
);
619 static inline xmlDocPtr
get_doc( domdoc
*This
)
621 return (xmlDocPtr
)This
->node
.node
;
624 static HRESULT
attach_xmldoc(domdoc
*This
, xmlDocPtr xml
)
626 release_namespaces(This
);
630 priv_from_xmlDocPtr(get_doc(This
))->properties
= NULL
;
631 if (xmldoc_release(get_doc(This
)) != 0)
632 priv_from_xmlDocPtr(get_doc(This
))->properties
=
633 copy_properties(This
->properties
);
636 This
->node
.node
= (xmlNodePtr
) xml
;
640 xmldoc_add_ref(get_doc(This
));
641 priv_from_xmlDocPtr(get_doc(This
))->properties
= This
->properties
;
647 static inline domdoc
*impl_from_IXMLDOMDocument3( IXMLDOMDocument3
*iface
)
649 return CONTAINING_RECORD(iface
, domdoc
, IXMLDOMDocument3_iface
);
652 static inline domdoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
654 return CONTAINING_RECORD(iface
, domdoc
, IPersistStreamInit_iface
);
657 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
659 return CONTAINING_RECORD(iface
, domdoc
, IObjectWithSite_iface
);
662 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
664 return CONTAINING_RECORD(iface
, domdoc
, IObjectSafety_iface
);
667 static inline domdoc
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
669 return CONTAINING_RECORD(iface
, domdoc
, IConnectionPointContainer_iface
);
672 /************************************************************************
673 * domdoc implementation of IPersistStream.
675 static HRESULT WINAPI
PersistStreamInit_QueryInterface(
676 IPersistStreamInit
*iface
, REFIID riid
, void **ppvObj
)
678 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
679 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObj
);
682 static ULONG WINAPI
PersistStreamInit_AddRef(
683 IPersistStreamInit
*iface
)
685 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
686 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
689 static ULONG WINAPI
PersistStreamInit_Release(
690 IPersistStreamInit
*iface
)
692 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
693 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
696 static HRESULT WINAPI
PersistStreamInit_GetClassID(
697 IPersistStreamInit
*iface
, CLSID
*classid
)
699 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
700 TRACE("(%p)->(%p)\n", This
, classid
);
705 *classid
= *DOMDocument_version(This
->properties
->version
);
710 static HRESULT WINAPI
PersistStreamInit_IsDirty(
711 IPersistStreamInit
*iface
)
713 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
714 FIXME("(%p): stub!\n", This
);
718 static HRESULT
domdoc_load_from_stream(domdoc
*doc
, ISequentialStream
*stream
)
720 DWORD read
, written
, len
;
721 xmlDocPtr xmldoc
= NULL
;
729 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &hstream
);
735 ISequentialStream_Read(stream
, buf
, sizeof(buf
), &read
);
736 hr
= IStream_Write(hstream
, buf
, read
, &written
);
737 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
741 ERR("failed to copy stream 0x%08x\n", hr
);
742 IStream_Release(hstream
);
746 hr
= GetHGlobalFromStream(hstream
, &hglobal
);
750 len
= GlobalSize(hglobal
);
751 ptr
= GlobalLock(hglobal
);
753 xmldoc
= doparse(doc
, ptr
, len
, XML_CHAR_ENCODING_NONE
);
754 GlobalUnlock(hglobal
);
758 ERR("Failed to parse xml\n");
762 xmldoc
->_private
= create_priv();
764 return attach_xmldoc(doc
, xmldoc
);
767 static HRESULT WINAPI
PersistStreamInit_Load(IPersistStreamInit
*iface
, IStream
*stream
)
769 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
771 TRACE("(%p)->(%p)\n", This
, stream
);
776 return domdoc_load_from_stream(This
, (ISequentialStream
*)stream
);
779 static HRESULT WINAPI
PersistStreamInit_Save(
780 IPersistStreamInit
*iface
, IStream
*stream
, BOOL clr_dirty
)
782 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
786 TRACE("(%p)->(%p %d)\n", This
, stream
, clr_dirty
);
788 hr
= IXMLDOMDocument3_get_xml(&This
->IXMLDOMDocument3_iface
, &xmlString
);
791 DWORD len
= SysStringLen(xmlString
) * sizeof(WCHAR
);
793 hr
= IStream_Write( stream
, xmlString
, len
, NULL
);
794 SysFreeString(xmlString
);
797 TRACE("ret 0x%08x\n", hr
);
802 static HRESULT WINAPI
PersistStreamInit_GetSizeMax(
803 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
805 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
806 TRACE("(%p)->(%p)\n", This
, pcbSize
);
810 static HRESULT WINAPI
PersistStreamInit_InitNew(
811 IPersistStreamInit
*iface
)
813 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
814 TRACE("(%p)\n", This
);
818 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
820 PersistStreamInit_QueryInterface
,
821 PersistStreamInit_AddRef
,
822 PersistStreamInit_Release
,
823 PersistStreamInit_GetClassID
,
824 PersistStreamInit_IsDirty
,
825 PersistStreamInit_Load
,
826 PersistStreamInit_Save
,
827 PersistStreamInit_GetSizeMax
,
828 PersistStreamInit_InitNew
831 /* IXMLDOMDocument3 interface */
833 static const tid_t domdoc_se_tids
[] = {
836 IXMLDOMDocument2_tid
,
837 IXMLDOMDocument3_tid
,
841 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument3
*iface
, REFIID riid
, void** ppvObject
)
843 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
845 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppvObject
);
849 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
850 IsEqualGUID( riid
, &IID_IDispatch
) ||
851 IsEqualGUID( riid
, &IID_IXMLDOMNode
) ||
852 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
853 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
)||
854 IsEqualGUID( riid
, &IID_IXMLDOMDocument3
))
858 else if (IsEqualGUID(&IID_IPersistStream
, riid
) ||
859 IsEqualGUID(&IID_IPersistStreamInit
, riid
))
861 *ppvObject
= &This
->IPersistStreamInit_iface
;
863 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
865 *ppvObject
= &This
->IObjectWithSite_iface
;
867 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
869 *ppvObject
= &This
->IObjectSafety_iface
;
871 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
873 return node_create_supporterrorinfo(domdoc_se_tids
, ppvObject
);
875 else if(node_query_interface(&This
->node
, riid
, ppvObject
))
877 return *ppvObject
? S_OK
: E_NOINTERFACE
;
879 else if (IsEqualGUID( riid
, &IID_IConnectionPointContainer
))
881 *ppvObject
= &This
->IConnectionPointContainer_iface
;
885 TRACE("interface %s not implemented\n", debugstr_guid(riid
));
886 return E_NOINTERFACE
;
889 IUnknown_AddRef((IUnknown
*)*ppvObject
);
894 static ULONG WINAPI
domdoc_AddRef( IXMLDOMDocument3
*iface
)
896 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
897 ULONG ref
= InterlockedIncrement( &This
->ref
);
898 TRACE("(%p)->(%d)\n", This
, ref
);
902 static ULONG WINAPI
domdoc_Release( IXMLDOMDocument3
*iface
)
904 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
905 LONG ref
= InterlockedDecrement( &This
->ref
);
907 TRACE("(%p)->(%d)\n", This
, ref
);
914 detach_bsc(This
->bsc
);
917 IUnknown_Release( This
->site
);
918 destroy_xmlnode(&This
->node
);
920 for (eid
= 0; eid
< EVENTID_LAST
; eid
++)
921 if (This
->events
[eid
]) IDispatch_Release(This
->events
[eid
]);
923 release_namespaces(This
);
930 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument3
*iface
, UINT
* pctinfo
)
932 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
933 return IDispatchEx_GetTypeInfoCount(&This
->node
.dispex
.IDispatchEx_iface
, pctinfo
);
936 static HRESULT WINAPI
domdoc_GetTypeInfo(
937 IXMLDOMDocument3
*iface
,
938 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
940 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
941 return IDispatchEx_GetTypeInfo(&This
->node
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
944 static HRESULT WINAPI
domdoc_GetIDsOfNames(
945 IXMLDOMDocument3
*iface
,
952 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
953 return IDispatchEx_GetIDsOfNames(&This
->node
.dispex
.IDispatchEx_iface
,
954 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
957 static HRESULT WINAPI
domdoc_Invoke(
958 IXMLDOMDocument3
*iface
,
963 DISPPARAMS
* pDispParams
,
965 EXCEPINFO
* pExcepInfo
,
968 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
969 return IDispatchEx_Invoke(&This
->node
.dispex
.IDispatchEx_iface
,
970 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
973 static HRESULT WINAPI
domdoc_get_nodeName(
974 IXMLDOMDocument3
*iface
,
977 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
979 static const WCHAR documentW
[] = {'#','d','o','c','u','m','e','n','t',0};
981 TRACE("(%p)->(%p)\n", This
, name
);
983 return return_bstr(documentW
, name
);
987 static HRESULT WINAPI
domdoc_get_nodeValue(
988 IXMLDOMDocument3
*iface
,
991 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
993 TRACE("(%p)->(%p)\n", This
, value
);
998 V_VT(value
) = VT_NULL
;
999 V_BSTR(value
) = NULL
; /* tests show that we should do this */
1004 static HRESULT WINAPI
domdoc_put_nodeValue(
1005 IXMLDOMDocument3
*iface
,
1008 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1009 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&value
));
1014 static HRESULT WINAPI
domdoc_get_nodeType(
1015 IXMLDOMDocument3
*iface
,
1018 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1020 TRACE("(%p)->(%p)\n", This
, type
);
1022 *type
= NODE_DOCUMENT
;
1027 static HRESULT WINAPI
domdoc_get_parentNode(
1028 IXMLDOMDocument3
*iface
,
1029 IXMLDOMNode
** parent
)
1031 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1033 TRACE("(%p)->(%p)\n", This
, parent
);
1035 return node_get_parent(&This
->node
, parent
);
1039 static HRESULT WINAPI
domdoc_get_childNodes(
1040 IXMLDOMDocument3
*iface
,
1041 IXMLDOMNodeList
** childList
)
1043 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1045 TRACE("(%p)->(%p)\n", This
, childList
);
1047 return node_get_child_nodes(&This
->node
, childList
);
1051 static HRESULT WINAPI
domdoc_get_firstChild(
1052 IXMLDOMDocument3
*iface
,
1053 IXMLDOMNode
** firstChild
)
1055 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1057 TRACE("(%p)->(%p)\n", This
, firstChild
);
1059 return node_get_first_child(&This
->node
, firstChild
);
1063 static HRESULT WINAPI
domdoc_get_lastChild(
1064 IXMLDOMDocument3
*iface
,
1065 IXMLDOMNode
** lastChild
)
1067 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1069 TRACE("(%p)->(%p)\n", This
, lastChild
);
1071 return node_get_last_child(&This
->node
, lastChild
);
1075 static HRESULT WINAPI
domdoc_get_previousSibling(
1076 IXMLDOMDocument3
*iface
,
1077 IXMLDOMNode
** previousSibling
)
1079 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1081 TRACE("(%p)->(%p)\n", This
, previousSibling
);
1083 return return_null_node(previousSibling
);
1087 static HRESULT WINAPI
domdoc_get_nextSibling(
1088 IXMLDOMDocument3
*iface
,
1089 IXMLDOMNode
** nextSibling
)
1091 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1093 TRACE("(%p)->(%p)\n", This
, nextSibling
);
1095 return return_null_node(nextSibling
);
1099 static HRESULT WINAPI
domdoc_get_attributes(
1100 IXMLDOMDocument3
*iface
,
1101 IXMLDOMNamedNodeMap
** attributeMap
)
1103 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1105 TRACE("(%p)->(%p)\n", This
, attributeMap
);
1107 return return_null_ptr((void**)attributeMap
);
1111 static HRESULT WINAPI
domdoc_insertBefore(
1112 IXMLDOMDocument3
*iface
,
1113 IXMLDOMNode
* newChild
,
1115 IXMLDOMNode
** outNewChild
)
1117 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1119 TRACE("(%p)->(%p %s %p)\n", This
, newChild
, debugstr_variant(&refChild
), outNewChild
);
1121 return node_insert_before(&This
->node
, newChild
, &refChild
, outNewChild
);
1125 static HRESULT WINAPI
domdoc_replaceChild(
1126 IXMLDOMDocument3
*iface
,
1127 IXMLDOMNode
* newChild
,
1128 IXMLDOMNode
* oldChild
,
1129 IXMLDOMNode
** outOldChild
)
1131 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1133 TRACE("(%p)->(%p %p %p)\n", This
, newChild
, oldChild
, outOldChild
);
1135 return node_replace_child(&This
->node
, newChild
, oldChild
, outOldChild
);
1139 static HRESULT WINAPI
domdoc_removeChild(
1140 IXMLDOMDocument3
*iface
,
1142 IXMLDOMNode
**oldChild
)
1144 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1145 TRACE("(%p)->(%p %p)\n", This
, child
, oldChild
);
1146 return node_remove_child(&This
->node
, child
, oldChild
);
1150 static HRESULT WINAPI
domdoc_appendChild(
1151 IXMLDOMDocument3
*iface
,
1153 IXMLDOMNode
**outChild
)
1155 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1156 TRACE("(%p)->(%p %p)\n", This
, child
, outChild
);
1157 return node_append_child(&This
->node
, child
, outChild
);
1161 static HRESULT WINAPI
domdoc_hasChildNodes(
1162 IXMLDOMDocument3
*iface
,
1165 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1166 TRACE("(%p)->(%p)\n", This
, ret
);
1167 return node_has_childnodes(&This
->node
, ret
);
1171 static HRESULT WINAPI
domdoc_get_ownerDocument(
1172 IXMLDOMDocument3
*iface
,
1173 IXMLDOMDocument
**doc
)
1175 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1176 TRACE("(%p)->(%p)\n", This
, doc
);
1177 return node_get_owner_doc(&This
->node
, doc
);
1181 static HRESULT WINAPI
domdoc_cloneNode(
1182 IXMLDOMDocument3
*iface
,
1184 IXMLDOMNode
** outNode
)
1186 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1187 TRACE("(%p)->(%d %p)\n", This
, deep
, outNode
);
1188 return node_clone( &This
->node
, deep
, outNode
);
1192 static HRESULT WINAPI
domdoc_get_nodeTypeString(
1193 IXMLDOMDocument3
*iface
,
1196 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1197 static const WCHAR documentW
[] = {'d','o','c','u','m','e','n','t',0};
1199 TRACE("(%p)->(%p)\n", This
, p
);
1201 return return_bstr(documentW
, p
);
1205 static HRESULT WINAPI
domdoc_get_text(
1206 IXMLDOMDocument3
*iface
,
1209 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1210 TRACE("(%p)->(%p)\n", This
, p
);
1211 return node_get_text(&This
->node
, p
);
1215 static HRESULT WINAPI
domdoc_put_text(
1216 IXMLDOMDocument3
*iface
,
1219 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1220 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
1225 static HRESULT WINAPI
domdoc_get_specified(
1226 IXMLDOMDocument3
*iface
,
1227 VARIANT_BOOL
* isSpecified
)
1229 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1230 FIXME("(%p)->(%p) stub!\n", This
, isSpecified
);
1231 *isSpecified
= VARIANT_TRUE
;
1236 static HRESULT WINAPI
domdoc_get_definition(
1237 IXMLDOMDocument3
*iface
,
1238 IXMLDOMNode
** definitionNode
)
1240 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1241 FIXME("(%p)->(%p)\n", This
, definitionNode
);
1246 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
1247 IXMLDOMDocument3
*iface
,
1250 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1251 TRACE("(%p)->(%p)\n", This
, v
);
1252 return return_null_var(v
);
1255 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
1256 IXMLDOMDocument3
*iface
,
1257 VARIANT typedValue
)
1259 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1260 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&typedValue
));
1265 static HRESULT WINAPI
domdoc_get_dataType(
1266 IXMLDOMDocument3
*iface
,
1269 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1270 TRACE("(%p)->(%p)\n", This
, typename
);
1271 return return_null_var( typename
);
1275 static HRESULT WINAPI
domdoc_put_dataType(
1276 IXMLDOMDocument3
*iface
,
1279 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1281 FIXME("(%p)->(%s)\n", This
, debugstr_w(dataTypeName
));
1284 return E_INVALIDARG
;
1289 static int XMLCALL
domdoc_get_xml_writecallback(void *ctx
, const char *data
, int len
)
1291 return xmlBufferAdd((xmlBufferPtr
)ctx
, (xmlChar
*)data
, len
) == 0 ? len
: 0;
1294 static HRESULT WINAPI
domdoc_get_xml(
1295 IXMLDOMDocument3
*iface
,
1298 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1299 xmlSaveCtxtPtr ctxt
;
1304 TRACE("(%p)->(%p)\n", This
, p
);
1307 return E_INVALIDARG
;
1311 buf
= xmlBufferCreate();
1313 return E_OUTOFMEMORY
;
1315 options
= XML_SAVE_FORMAT
| XML_SAVE_NO_DECL
;
1316 ctxt
= xmlSaveToIO(domdoc_get_xml_writecallback
, NULL
, buf
, "UTF-8", options
);
1321 return E_OUTOFMEMORY
;
1324 ret
= xmlSaveDoc(ctxt
, get_doc(This
));
1325 /* flushes on close */
1328 TRACE("%ld, len=%d\n", ret
, xmlBufferLength(buf
));
1329 if(ret
!= -1 && xmlBufferLength(buf
) > 0)
1333 content
= bstr_from_xmlChar(xmlBufferContent(buf
));
1334 content
= EnsureCorrectEOL(content
);
1340 *p
= SysAllocStringLen(NULL
, 0);
1345 return *p
? S_OK
: E_OUTOFMEMORY
;
1349 static HRESULT WINAPI
domdoc_transformNode(
1350 IXMLDOMDocument3
*iface
,
1354 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1355 TRACE("(%p)->(%p %p)\n", This
, node
, p
);
1356 return node_transform_node(&This
->node
, node
, p
);
1360 static HRESULT WINAPI
domdoc_selectNodes(
1361 IXMLDOMDocument3
*iface
,
1363 IXMLDOMNodeList
**outList
)
1365 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1366 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outList
);
1367 return node_select_nodes(&This
->node
, p
, outList
);
1371 static HRESULT WINAPI
domdoc_selectSingleNode(
1372 IXMLDOMDocument3
*iface
,
1374 IXMLDOMNode
**outNode
)
1376 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1377 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outNode
);
1378 return node_select_singlenode(&This
->node
, p
, outNode
);
1382 static HRESULT WINAPI
domdoc_get_parsed(
1383 IXMLDOMDocument3
*iface
,
1384 VARIANT_BOOL
* isParsed
)
1386 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1387 FIXME("(%p)->(%p) stub!\n", This
, isParsed
);
1388 *isParsed
= VARIANT_TRUE
;
1392 static HRESULT WINAPI
domdoc_get_namespaceURI(
1393 IXMLDOMDocument3
*iface
,
1394 BSTR
* namespaceURI
)
1396 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1397 TRACE("(%p)->(%p)\n", This
, namespaceURI
);
1398 return return_null_bstr( namespaceURI
);
1401 static HRESULT WINAPI
domdoc_get_prefix(
1402 IXMLDOMDocument3
*iface
,
1405 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1406 TRACE("(%p)->(%p)\n", This
, prefix
);
1407 return return_null_bstr( prefix
);
1411 static HRESULT WINAPI
domdoc_get_baseName(
1412 IXMLDOMDocument3
*iface
,
1415 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1416 TRACE("(%p)->(%p)\n", This
, name
);
1417 return return_null_bstr( name
);
1421 static HRESULT WINAPI
domdoc_transformNodeToObject(
1422 IXMLDOMDocument3
*iface
,
1423 IXMLDOMNode
* stylesheet
,
1424 VARIANT outputObject
)
1426 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1427 FIXME("(%p)->(%p %s)\n", This
, stylesheet
, debugstr_variant(&outputObject
));
1432 static HRESULT WINAPI
domdoc_get_doctype(
1433 IXMLDOMDocument3
*iface
,
1434 IXMLDOMDocumentType
** doctype
)
1436 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1441 TRACE("(%p)->(%p)\n", This
, doctype
);
1443 if (!doctype
) return E_INVALIDARG
;
1447 dtd
= xmlGetIntSubset(get_doc(This
));
1448 if (!dtd
) return S_FALSE
;
1450 node
= create_node((xmlNodePtr
)dtd
);
1451 if (!node
) return S_FALSE
;
1453 hr
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentType
, (void**)doctype
);
1454 IXMLDOMNode_Release(node
);
1460 static HRESULT WINAPI
domdoc_get_implementation(
1461 IXMLDOMDocument3
*iface
,
1462 IXMLDOMImplementation
** impl
)
1464 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1466 TRACE("(%p)->(%p)\n", This
, impl
);
1469 return E_INVALIDARG
;
1471 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
1476 static HRESULT WINAPI
domdoc_get_documentElement(
1477 IXMLDOMDocument3
*iface
,
1478 IXMLDOMElement
** DOMElement
)
1480 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1481 IXMLDOMNode
*element_node
;
1485 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1488 return E_INVALIDARG
;
1492 root
= xmlDocGetRootElement( get_doc(This
) );
1496 element_node
= create_node( root
);
1497 if(!element_node
) return S_FALSE
;
1499 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (void**)DOMElement
);
1500 IXMLDOMNode_Release(element_node
);
1506 static HRESULT WINAPI
domdoc_put_documentElement(
1507 IXMLDOMDocument3
*iface
,
1508 IXMLDOMElement
* DOMElement
)
1510 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1511 IXMLDOMNode
*elementNode
;
1516 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1518 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1522 xmlNode
= get_node_obj( elementNode
);
1523 if(!xmlNode
) return E_FAIL
;
1525 if(!xmlNode
->node
->parent
)
1526 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1527 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1529 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1530 IXMLDOMNode_Release( elementNode
);
1533 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1539 static HRESULT WINAPI
domdoc_createElement(
1540 IXMLDOMDocument3
*iface
,
1542 IXMLDOMElement
** element
)
1544 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1549 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagname
), element
);
1551 if (!element
|| !tagname
) return E_INVALIDARG
;
1553 V_VT(&type
) = VT_I1
;
1554 V_I1(&type
) = NODE_ELEMENT
;
1556 hr
= IXMLDOMDocument3_createNode(iface
, type
, tagname
, NULL
, &node
);
1559 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMElement
, (void**)element
);
1560 IXMLDOMNode_Release(node
);
1567 static HRESULT WINAPI
domdoc_createDocumentFragment(
1568 IXMLDOMDocument3
*iface
,
1569 IXMLDOMDocumentFragment
** frag
)
1571 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1576 TRACE("(%p)->(%p)\n", This
, frag
);
1578 if (!frag
) return E_INVALIDARG
;
1582 V_VT(&type
) = VT_I1
;
1583 V_I1(&type
) = NODE_DOCUMENT_FRAGMENT
;
1585 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1588 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentFragment
, (void**)frag
);
1589 IXMLDOMNode_Release(node
);
1596 static HRESULT WINAPI
domdoc_createTextNode(
1597 IXMLDOMDocument3
*iface
,
1599 IXMLDOMText
** text
)
1601 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1606 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), text
);
1608 if (!text
) return E_INVALIDARG
;
1612 V_VT(&type
) = VT_I1
;
1613 V_I1(&type
) = NODE_TEXT
;
1615 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1618 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)text
);
1619 IXMLDOMNode_Release(node
);
1620 hr
= IXMLDOMText_put_data(*text
, data
);
1627 static HRESULT WINAPI
domdoc_createComment(
1628 IXMLDOMDocument3
*iface
,
1630 IXMLDOMComment
** comment
)
1632 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1637 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), comment
);
1639 if (!comment
) return E_INVALIDARG
;
1643 V_VT(&type
) = VT_I1
;
1644 V_I1(&type
) = NODE_COMMENT
;
1646 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1649 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)comment
);
1650 IXMLDOMNode_Release(node
);
1651 hr
= IXMLDOMComment_put_data(*comment
, data
);
1658 static HRESULT WINAPI
domdoc_createCDATASection(
1659 IXMLDOMDocument3
*iface
,
1661 IXMLDOMCDATASection
** cdata
)
1663 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1668 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), cdata
);
1670 if (!cdata
) return E_INVALIDARG
;
1674 V_VT(&type
) = VT_I1
;
1675 V_I1(&type
) = NODE_CDATA_SECTION
;
1677 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1680 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)cdata
);
1681 IXMLDOMNode_Release(node
);
1682 hr
= IXMLDOMCDATASection_put_data(*cdata
, data
);
1689 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1690 IXMLDOMDocument3
*iface
,
1693 IXMLDOMProcessingInstruction
** pi
)
1695 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1700 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(target
), debugstr_w(data
), pi
);
1702 if (!pi
) return E_INVALIDARG
;
1706 V_VT(&type
) = VT_I1
;
1707 V_I1(&type
) = NODE_PROCESSING_INSTRUCTION
;
1709 hr
= IXMLDOMDocument3_createNode(iface
, type
, target
, NULL
, &node
);
1714 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1715 node_obj
= get_node_obj(node
);
1716 hr
= node_set_content(node_obj
, data
);
1718 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMProcessingInstruction
, (void**)pi
);
1719 IXMLDOMNode_Release(node
);
1726 static HRESULT WINAPI
domdoc_createAttribute(
1727 IXMLDOMDocument3
*iface
,
1729 IXMLDOMAttribute
** attribute
)
1731 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1736 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), attribute
);
1738 if (!attribute
|| !name
) return E_INVALIDARG
;
1740 V_VT(&type
) = VT_I1
;
1741 V_I1(&type
) = NODE_ATTRIBUTE
;
1743 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1746 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMAttribute
, (void**)attribute
);
1747 IXMLDOMNode_Release(node
);
1754 static HRESULT WINAPI
domdoc_createEntityReference(
1755 IXMLDOMDocument3
*iface
,
1757 IXMLDOMEntityReference
** entityref
)
1759 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1764 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), entityref
);
1766 if (!entityref
) return E_INVALIDARG
;
1770 V_VT(&type
) = VT_I1
;
1771 V_I1(&type
) = NODE_ENTITY_REFERENCE
;
1773 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1776 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMEntityReference
, (void**)entityref
);
1777 IXMLDOMNode_Release(node
);
1783 xmlChar
* tagName_to_XPath(const BSTR tagName
)
1785 xmlChar
*query
, *tmp
;
1786 static const xmlChar mod_pre
[] = "*[local-name()='";
1787 static const xmlChar mod_post
[] = "']";
1788 static const xmlChar prefix
[] = "descendant::";
1789 const WCHAR
*tokBegin
, *tokEnd
;
1792 query
= xmlStrdup(prefix
);
1795 while (tokBegin
&& *tokBegin
)
1800 query
= xmlStrcat(query
, BAD_CAST
"/");
1804 query
= xmlStrcat(query
, BAD_CAST
"*");
1808 query
= xmlStrcat(query
, mod_pre
);
1810 while (*tokEnd
&& *tokEnd
!= '/')
1812 len
= WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, NULL
, 0, NULL
, NULL
);
1813 tmp
= xmlMalloc(len
);
1814 WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, (char*)tmp
, len
, NULL
, NULL
);
1815 query
= xmlStrncat(query
, tmp
, len
);
1818 query
= xmlStrcat(query
, mod_post
);
1825 static HRESULT WINAPI
domdoc_getElementsByTagName(
1826 IXMLDOMDocument3
*iface
,
1828 IXMLDOMNodeList
** resultList
)
1830 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1835 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(tagName
), resultList
);
1837 if (!tagName
|| !resultList
) return E_INVALIDARG
;
1839 XPath
= This
->properties
->XPath
;
1840 This
->properties
->XPath
= TRUE
;
1841 query
= tagName_to_XPath(tagName
);
1842 hr
= create_selection((xmlNodePtr
)get_doc(This
), query
, resultList
);
1844 This
->properties
->XPath
= XPath
;
1849 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1855 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1857 return E_INVALIDARG
;
1864 static HRESULT WINAPI
domdoc_createNode(
1865 IXMLDOMDocument3
*iface
,
1869 IXMLDOMNode
** node
)
1871 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1872 DOMNodeType node_type
;
1874 xmlChar
*xml_name
, *href
;
1877 TRACE("(%p)->(%s %s %s %p)\n", This
, debugstr_variant(&Type
), debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1879 if(!node
) return E_INVALIDARG
;
1881 hr
= get_node_type(Type
, &node_type
);
1882 if(FAILED(hr
)) return hr
;
1884 if(namespaceURI
&& namespaceURI
[0] && node_type
!= NODE_ELEMENT
)
1885 FIXME("nodes with namespaces currently not supported.\n");
1887 TRACE("node_type %d\n", node_type
);
1889 /* exit earlier for types that need name */
1893 case NODE_ATTRIBUTE
:
1894 case NODE_ENTITY_REFERENCE
:
1895 case NODE_PROCESSING_INSTRUCTION
:
1896 if (!name
|| *name
== 0) return E_FAIL
;
1902 xml_name
= xmlchar_from_wchar(name
);
1903 /* prevent empty href to be allocated */
1904 href
= namespaceURI
? xmlchar_from_wchar(namespaceURI
) : NULL
;
1910 xmlChar
*local
, *prefix
;
1912 local
= xmlSplitQName2(xml_name
, &prefix
);
1914 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, local
? local
: xml_name
, NULL
);
1916 /* allow to create default namespace xmlns= */
1917 if (local
|| (href
&& *href
))
1919 xmlNsPtr ns
= xmlNewNs(xmlnode
, href
, prefix
);
1920 xmlSetNs(xmlnode
, ns
);
1928 case NODE_ATTRIBUTE
:
1929 xmlnode
= (xmlNodePtr
)xmlNewDocProp(get_doc(This
), xml_name
, NULL
);
1932 xmlnode
= (xmlNodePtr
)xmlNewDocText(get_doc(This
), NULL
);
1934 case NODE_CDATA_SECTION
:
1935 xmlnode
= xmlNewCDataBlock(get_doc(This
), NULL
, 0);
1937 case NODE_ENTITY_REFERENCE
:
1938 xmlnode
= xmlNewReference(get_doc(This
), xml_name
);
1940 case NODE_PROCESSING_INSTRUCTION
:
1941 #ifdef HAVE_XMLNEWDOCPI
1942 xmlnode
= xmlNewDocPI(get_doc(This
), xml_name
, NULL
);
1944 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1949 xmlnode
= xmlNewDocComment(get_doc(This
), NULL
);
1951 case NODE_DOCUMENT_FRAGMENT
:
1952 xmlnode
= xmlNewDocFragment(get_doc(This
));
1954 /* unsupported types */
1956 case NODE_DOCUMENT_TYPE
:
1959 heap_free(xml_name
);
1960 return E_INVALIDARG
;
1962 FIXME("unhandled node type %d\n", node_type
);
1967 *node
= create_node(xmlnode
);
1968 heap_free(xml_name
);
1973 TRACE("created node (%d, %p, %p)\n", node_type
, *node
, xmlnode
);
1974 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1981 static HRESULT WINAPI
domdoc_nodeFromID(
1982 IXMLDOMDocument3
*iface
,
1984 IXMLDOMNode
** node
)
1986 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1987 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(idString
), node
);
1991 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
1996 xmldoc
= doparse(This
, ptr
, len
, XML_CHAR_ENCODING_NONE
);
1998 xmldoc
->_private
= create_priv();
1999 return attach_xmldoc(This
, xmldoc
);
2005 static HRESULT
domdoc_load_moniker(domdoc
*This
, IMoniker
*mon
)
2010 hr
= bind_url(mon
, domdoc_onDataAvailable
, This
, &bsc
);
2015 hr
= detach_bsc(This
->bsc
);
2024 static HRESULT WINAPI
domdoc_load(
2025 IXMLDOMDocument3
*iface
,
2027 VARIANT_BOOL
* isSuccessful
)
2029 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2030 LPWSTR filename
= NULL
;
2031 HRESULT hr
= S_FALSE
;
2034 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&source
));
2038 *isSuccessful
= VARIANT_FALSE
;
2040 assert( &This
->node
);
2042 switch( V_VT(&source
) )
2045 filename
= V_BSTR(&source
);
2047 case VT_BSTR
|VT_BYREF
:
2048 if (!V_BSTRREF(&source
)) return E_INVALIDARG
;
2049 filename
= *V_BSTRREF(&source
);
2051 case VT_ARRAY
|VT_UI1
:
2053 SAFEARRAY
*psa
= V_ARRAY(&source
);
2056 UINT dim
= SafeArrayGetDim(psa
);
2061 ERR("SAFEARRAY == NULL\n");
2062 hr
= This
->error
= E_INVALIDARG
;
2065 /* Only takes UTF-8 strings.
2066 * NOT NULL-terminated. */
2067 SafeArrayAccessData(psa
, (void**)&str
);
2068 SafeArrayGetUBound(psa
, 1, &len
);
2070 if ((xmldoc
= doparse(This
, str
, ++len
, XML_CHAR_ENCODING_UTF8
)))
2072 hr
= This
->error
= S_OK
;
2073 *isSuccessful
= VARIANT_TRUE
;
2074 TRACE("parsed document %p\n", xmldoc
);
2078 This
->error
= E_FAIL
;
2079 TRACE("failed to parse document\n");
2082 SafeArrayUnaccessData(psa
);
2086 xmldoc
->_private
= create_priv();
2087 return attach_xmldoc(This
, xmldoc
);
2091 FIXME("unhandled SAFEARRAY dim: %d\n", dim
);
2092 hr
= This
->error
= E_NOTIMPL
;
2098 ISequentialStream
*stream
= NULL
;
2099 IXMLDOMDocument3
*newdoc
= NULL
;
2101 if (!V_UNKNOWN(&source
)) return E_INVALIDARG
;
2103 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IXMLDOMDocument3
, (void**)&newdoc
);
2108 domdoc
*newDoc
= impl_from_IXMLDOMDocument3( newdoc
);
2110 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
2111 xmldoc
->_private
= create_priv();
2112 hr
= attach_xmldoc(This
, xmldoc
);
2115 *isSuccessful
= VARIANT_TRUE
;
2121 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IStream
, (void**)&stream
);
2123 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_ISequentialStream
, (void**)&stream
);
2127 hr
= domdoc_load_from_stream(This
, stream
);
2129 *isSuccessful
= VARIANT_TRUE
;
2130 ISequentialStream_Release(stream
);
2134 FIXME("unsupported IUnknown type (0x%08x) (%p)\n", hr
, V_UNKNOWN(&source
)->lpVtbl
);
2138 FIXME("VT type not supported (%d)\n", V_VT(&source
));
2145 hr
= create_moniker_from_url( filename
, &mon
);
2146 if ( SUCCEEDED(hr
) )
2148 hr
= domdoc_load_moniker( This
, mon
);
2149 IMoniker_Release(mon
);
2153 This
->error
= E_FAIL
;
2156 hr
= This
->error
= S_OK
;
2157 *isSuccessful
= VARIANT_TRUE
;
2161 if(!filename
|| FAILED(hr
)) {
2162 xmldoc
= xmlNewDoc(NULL
);
2163 xmldoc
->_private
= create_priv();
2164 hr
= attach_xmldoc(This
, xmldoc
);
2169 TRACE("ret (%d)\n", hr
);
2175 static HRESULT WINAPI
domdoc_get_readyState(
2176 IXMLDOMDocument3
*iface
,
2179 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2180 FIXME("stub! (%p)->(%p)\n", This
, value
);
2183 return E_INVALIDARG
;
2185 *value
= READYSTATE_COMPLETE
;
2190 static HRESULT WINAPI
domdoc_get_parseError(
2191 IXMLDOMDocument3
*iface
,
2192 IXMLDOMParseError
** errorObj
)
2194 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2195 static const WCHAR err
[] = {'e','r','r','o','r',0};
2196 BSTR error_string
= NULL
;
2198 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
2201 error_string
= SysAllocString(err
);
2203 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
2204 if(!*errorObj
) return E_OUTOFMEMORY
;
2209 static HRESULT WINAPI
domdoc_get_url(
2210 IXMLDOMDocument3
*iface
,
2213 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2214 FIXME("(%p)->(%p)\n", This
, urlString
);
2219 static HRESULT WINAPI
domdoc_get_async(
2220 IXMLDOMDocument3
*iface
,
2221 VARIANT_BOOL
* isAsync
)
2223 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2225 TRACE("(%p)->(%p: %d)\n", This
, isAsync
, This
->async
);
2226 *isAsync
= This
->async
;
2231 static HRESULT WINAPI
domdoc_put_async(
2232 IXMLDOMDocument3
*iface
,
2233 VARIANT_BOOL isAsync
)
2235 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2237 TRACE("(%p)->(%d)\n", This
, isAsync
);
2238 This
->async
= isAsync
;
2243 static HRESULT WINAPI
domdoc_abort(
2244 IXMLDOMDocument3
*iface
)
2246 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2247 FIXME("%p\n", This
);
2251 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2252 static HRESULT WINAPI
domdoc_loadXML(
2253 IXMLDOMDocument3
*iface
,
2255 VARIANT_BOOL
* isSuccessful
)
2257 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2258 xmlDocPtr xmldoc
= NULL
;
2259 HRESULT hr
= S_FALSE
, hr2
;
2261 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), isSuccessful
);
2263 assert ( &This
->node
);
2267 *isSuccessful
= VARIANT_FALSE
;
2273 /* skip leading spaces if needed */
2274 if (This
->properties
->version
== MSXML_DEFAULT
|| This
->properties
->version
== MSXML26
)
2275 while (*ptr
&& isspaceW(*ptr
)) ptr
++;
2277 xmldoc
= doparse(This
, (char*)ptr
, strlenW(ptr
)*sizeof(WCHAR
), XML_CHAR_ENCODING_UTF16LE
);
2280 This
->error
= E_FAIL
;
2281 TRACE("failed to parse document\n");
2285 hr
= This
->error
= S_OK
;
2286 *isSuccessful
= VARIANT_TRUE
;
2287 TRACE("parsed document %p\n", xmldoc
);
2293 xmldoc
= xmlNewDoc(NULL
);
2294 xmldoc
->_private
= create_priv();
2295 hr2
= attach_xmldoc(This
, xmldoc
);
2302 static int XMLCALL
domdoc_save_writecallback(void *ctx
, const char *buffer
, int len
)
2306 if(!WriteFile(ctx
, buffer
, len
, &written
, NULL
))
2308 WARN("write error\n");
2315 static int XMLCALL
domdoc_save_closecallback(void *ctx
)
2317 return CloseHandle(ctx
) ? 0 : -1;
2320 static int XMLCALL
domdoc_stream_save_writecallback(void *ctx
, const char *buffer
, int len
)
2325 hr
= IStream_Write((IStream
*)ctx
, buffer
, len
, &written
);
2326 TRACE("0x%08x %p %d %u\n", hr
, buffer
, len
, written
);
2329 WARN("stream write error: 0x%08x\n", hr
);
2336 static int XMLCALL
domdoc_stream_save_closecallback(void *ctx
)
2338 IStream_Release((IStream
*)ctx
);
2342 static HRESULT WINAPI
domdoc_save(
2343 IXMLDOMDocument3
*iface
,
2344 VARIANT destination
)
2346 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2347 xmlSaveCtxtPtr ctx
= NULL
;
2351 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&destination
));
2353 switch (V_VT(&destination
))
2357 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
2358 IXMLDOMDocument3
*document
;
2361 ret
= IUnknown_QueryInterface(pUnk
, &IID_IXMLDOMDocument3
, (void**)&document
);
2364 VARIANT_BOOL success
;
2367 ret
= IXMLDOMDocument3_get_xml(iface
, &xml
);
2370 ret
= IXMLDOMDocument3_loadXML(document
, xml
, &success
);
2374 IXMLDOMDocument3_Release(document
);
2378 ret
= IUnknown_QueryInterface(pUnk
, &IID_IStream
, (void**)&stream
);
2381 int options
= get_doc(This
)->standalone
== -1 ? XML_SAVE_NO_DECL
: 0;
2382 ctx
= xmlSaveToIO(domdoc_stream_save_writecallback
,
2383 domdoc_stream_save_closecallback
, stream
, NULL
, options
);
2387 IStream_Release(stream
);
2395 case VT_BSTR
| VT_BYREF
:
2397 int options
= get_doc(This
)->standalone
== -1 ? XML_SAVE_NO_DECL
: 0;
2399 /* save with file path */
2400 HANDLE handle
= CreateFileW( (V_VT(&destination
) & VT_BYREF
)? *V_BSTRREF(&destination
) : V_BSTR(&destination
),
2401 GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2402 if( handle
== INVALID_HANDLE_VALUE
)
2404 WARN("failed to create file\n");
2408 /* disable top XML declaration */
2409 ctx
= xmlSaveToIO(domdoc_save_writecallback
, domdoc_save_closecallback
,
2410 handle
, NULL
, options
);
2413 CloseHandle(handle
);
2420 FIXME("Unhandled VARIANT: %s\n", debugstr_variant(&destination
));
2424 xmldecl
= xmldoc_unlink_xmldecl(get_doc(This
));
2425 if (xmlSaveDoc(ctx
, get_doc(This
)) == -1) ret
= S_FALSE
;
2426 xmldoc_link_xmldecl(get_doc(This
), xmldecl
);
2428 /* will release resources through close callback */
2434 static HRESULT WINAPI
domdoc_get_validateOnParse(
2435 IXMLDOMDocument3
*iface
,
2436 VARIANT_BOOL
* isValidating
)
2438 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2439 TRACE("(%p)->(%p: %d)\n", This
, isValidating
, This
->validating
);
2440 *isValidating
= This
->validating
;
2445 static HRESULT WINAPI
domdoc_put_validateOnParse(
2446 IXMLDOMDocument3
*iface
,
2447 VARIANT_BOOL isValidating
)
2449 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2450 TRACE("(%p)->(%d)\n", This
, isValidating
);
2451 This
->validating
= isValidating
;
2456 static HRESULT WINAPI
domdoc_get_resolveExternals(
2457 IXMLDOMDocument3
*iface
,
2458 VARIANT_BOOL
* isResolving
)
2460 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2461 TRACE("(%p)->(%p: %d)\n", This
, isResolving
, This
->resolving
);
2462 *isResolving
= This
->resolving
;
2467 static HRESULT WINAPI
domdoc_put_resolveExternals(
2468 IXMLDOMDocument3
*iface
,
2469 VARIANT_BOOL isResolving
)
2471 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2472 TRACE("(%p)->(%d)\n", This
, isResolving
);
2473 This
->resolving
= isResolving
;
2478 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
2479 IXMLDOMDocument3
*iface
,
2480 VARIANT_BOOL
* isPreserving
)
2482 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2483 TRACE("(%p)->(%p: %d)\n", This
, isPreserving
, This
->properties
->preserving
);
2484 *isPreserving
= This
->properties
->preserving
;
2489 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
2490 IXMLDOMDocument3
*iface
,
2491 VARIANT_BOOL isPreserving
)
2493 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2494 TRACE("(%p)->(%d)\n", This
, isPreserving
);
2495 This
->properties
->preserving
= isPreserving
;
2500 static HRESULT WINAPI
domdoc_put_onreadystatechange(
2501 IXMLDOMDocument3
*iface
,
2504 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2506 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&event
));
2507 return set_doc_event(This
, EVENTID_READYSTATECHANGE
, &event
);
2511 static HRESULT WINAPI
domdoc_put_onDataAvailable(IXMLDOMDocument3
*iface
, VARIANT sink
)
2513 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2514 FIXME("(%p)->(%s): stub\n", This
, debugstr_variant(&sink
));
2518 static HRESULT WINAPI
domdoc_put_onTransformNode(IXMLDOMDocument3
*iface
, VARIANT sink
)
2520 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2521 FIXME("(%p)->(%s): stub\n", This
, debugstr_variant(&sink
));
2525 static HRESULT WINAPI
domdoc_get_namespaces(
2526 IXMLDOMDocument3
* iface
,
2527 IXMLDOMSchemaCollection
** collection
)
2529 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2532 FIXME("(%p)->(%p): semi-stub\n", This
, collection
);
2534 if (!collection
) return E_POINTER
;
2536 if (!This
->namespaces
)
2538 hr
= SchemaCache_create(This
->properties
->version
, NULL
, (void**)&This
->namespaces
);
2539 if (hr
!= S_OK
) return hr
;
2541 hr
= cache_from_doc_ns(This
->namespaces
, &This
->node
);
2543 release_namespaces(This
);
2546 if (This
->namespaces
)
2547 return IXMLDOMSchemaCollection2_QueryInterface(This
->namespaces
,
2548 &IID_IXMLDOMSchemaCollection
, (void**)collection
);
2553 static HRESULT WINAPI
domdoc_get_schemas(
2554 IXMLDOMDocument3
* iface
,
2557 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2558 IXMLDOMSchemaCollection2
* cur_schema
= This
->properties
->schemaCache
;
2559 HRESULT hr
= S_FALSE
;
2561 TRACE("(%p)->(%p)\n", This
, schema
);
2563 V_VT(schema
) = VT_NULL
;
2564 /* just to reset pointer part, cause that's what application is expected to use */
2565 V_DISPATCH(schema
) = NULL
;
2569 hr
= IXMLDOMSchemaCollection2_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(schema
));
2571 V_VT(schema
) = VT_DISPATCH
;
2576 static HRESULT WINAPI
domdoc_putref_schemas(
2577 IXMLDOMDocument3
* iface
,
2580 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2581 HRESULT hr
= E_FAIL
;
2582 IXMLDOMSchemaCollection2
* new_schema
= NULL
;
2584 FIXME("(%p)->(%s): semi-stub\n", This
, debugstr_variant(&schema
));
2585 switch(V_VT(&schema
))
2588 if (V_UNKNOWN(&schema
))
2590 hr
= IUnknown_QueryInterface(V_UNKNOWN(&schema
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2595 if (V_DISPATCH(&schema
))
2597 hr
= IDispatch_QueryInterface(V_DISPATCH(&schema
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2607 WARN("Can't get schema from vt %x\n", V_VT(&schema
));
2612 IXMLDOMSchemaCollection2
* old_schema
= InterlockedExchangePointer((void**)&This
->properties
->schemaCache
, new_schema
);
2613 if(old_schema
) IXMLDOMSchemaCollection2_Release(old_schema
);
2619 static inline BOOL
is_wellformed(xmlDocPtr doc
)
2621 #ifdef HAVE_XMLDOC_PROPERTIES
2622 return doc
->properties
& XML_DOC_WELLFORMED
;
2624 /* Not a full check, but catches the worst violations */
2628 for (child
= doc
->children
; child
!= NULL
; child
= child
->next
)
2630 switch (child
->type
)
2632 case XML_ELEMENT_NODE
:
2637 case XML_CDATA_SECTION_NODE
:
2649 static void LIBXML2_LOG_CALLBACK
validate_error(void* ctx
, char const* msg
, ...)
2653 LIBXML2_CALLBACK_ERR(domdoc_validateNode
, msg
, ap
);
2657 static void LIBXML2_LOG_CALLBACK
validate_warning(void* ctx
, char const* msg
, ...)
2661 LIBXML2_CALLBACK_WARN(domdoc_validateNode
, msg
, ap
);
2665 static HRESULT WINAPI
domdoc_validateNode(
2666 IXMLDOMDocument3
* iface
,
2668 IXMLDOMParseError
** err
)
2670 domdoc
* This
= impl_from_IXMLDOMDocument3(iface
);
2671 LONG state
, err_code
= 0;
2675 TRACE("(%p)->(%p, %p)\n", This
, node
, err
);
2676 IXMLDOMDocument3_get_readyState(iface
, &state
);
2677 if (state
!= READYSTATE_COMPLETE
)
2680 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2687 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2691 if (!get_node_obj(node
)->node
|| get_node_obj(node
)->node
->doc
!= get_doc(This
))
2694 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2698 if (!is_wellformed(get_doc(This
)))
2700 ERR("doc not well-formed\n");
2702 *err
= create_parseError(E_XML_NOTWF
, NULL
, NULL
, NULL
, 0, 0, 0);
2706 /* DTD validation */
2707 if (get_doc(This
)->intSubset
|| get_doc(This
)->extSubset
)
2709 xmlValidCtxtPtr vctx
= xmlNewValidCtxt();
2710 vctx
->error
= validate_error
;
2711 vctx
->warning
= validate_warning
;
2714 if (!((node
== (IXMLDOMNode
*)iface
)?
2715 xmlValidateDocument(vctx
, get_doc(This
)) :
2716 xmlValidateElement(vctx
, get_doc(This
), get_node_obj(node
)->node
)))
2718 /* TODO: get a real error code here */
2719 TRACE("DTD validation failed\n");
2720 err_code
= E_XML_INVALID
;
2723 xmlFreeValidCtxt(vctx
);
2726 /* Schema validation */
2727 if (hr
== S_OK
&& This
->properties
->schemaCache
!= NULL
)
2730 hr
= SchemaCache_validate_tree(This
->properties
->schemaCache
, get_node_obj(node
)->node
);
2734 /* TODO: get a real error code here */
2737 TRACE("schema validation succeeded\n");
2741 ERR("schema validation failed\n");
2742 err_code
= E_XML_INVALID
;
2747 /* not really OK, just didn't find a schema for the ns */
2754 ERR("no DTD or schema found\n");
2755 err_code
= E_XML_NODTD
;
2760 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2765 static HRESULT WINAPI
domdoc_validate(
2766 IXMLDOMDocument3
* iface
,
2767 IXMLDOMParseError
** err
)
2769 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2770 TRACE("(%p)->(%p)\n", This
, err
);
2771 return IXMLDOMDocument3_validateNode(iface
, (IXMLDOMNode
*)iface
, err
);
2774 static HRESULT WINAPI
domdoc_setProperty(
2775 IXMLDOMDocument3
* iface
,
2779 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2781 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(p
), debugstr_variant(&value
));
2783 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2789 V_VT(&varStr
) = VT_EMPTY
;
2790 if (V_VT(&value
) != VT_BSTR
)
2792 if (FAILED(hr
= VariantChangeType(&varStr
, &value
, 0, VT_BSTR
)))
2794 bstr
= V_BSTR(&varStr
);
2797 bstr
= V_BSTR(&value
);
2800 if (lstrcmpiW(bstr
, PropValueXPathW
) == 0)
2801 This
->properties
->XPath
= TRUE
;
2802 else if (lstrcmpiW(bstr
, PropValueXSLPatternW
) == 0)
2803 This
->properties
->XPath
= FALSE
;
2807 VariantClear(&varStr
);
2810 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2812 xmlChar
*nsStr
= (xmlChar
*)This
->properties
->selectNsStr
;
2813 struct list
*pNsList
;
2818 V_VT(&varStr
) = VT_EMPTY
;
2819 if (V_VT(&value
) != VT_BSTR
)
2821 if (FAILED(hr
= VariantChangeType(&varStr
, &value
, 0, VT_BSTR
)))
2823 bstr
= V_BSTR(&varStr
);
2826 bstr
= V_BSTR(&value
);
2830 pNsList
= &(This
->properties
->selectNsList
);
2831 clear_selectNsList(pNsList
);
2833 nsStr
= xmlchar_from_wchar(bstr
);
2835 TRACE("property value: \"%s\"\n", debugstr_w(bstr
));
2837 This
->properties
->selectNsStr
= nsStr
;
2838 This
->properties
->selectNsStr_len
= xmlStrlen(nsStr
);
2841 xmlChar
*pTokBegin
, *pTokEnd
, *pTokInner
;
2842 select_ns_entry
* ns_entry
= NULL
;
2843 xmlXPathContextPtr ctx
;
2845 ctx
= xmlXPathNewContext(This
->node
.node
->doc
);
2848 /* skip leading spaces */
2849 while (*pTokBegin
== ' ' || *pTokBegin
== '\n' ||
2850 *pTokBegin
== '\t' || *pTokBegin
== '\r')
2853 for (; *pTokBegin
; pTokBegin
= pTokEnd
)
2856 memset(ns_entry
, 0, sizeof(select_ns_entry
));
2858 ns_entry
= heap_alloc_zero(sizeof(select_ns_entry
));
2860 while (*pTokBegin
== ' ')
2862 pTokEnd
= pTokBegin
;
2863 while (*pTokEnd
!= ' ' && *pTokEnd
!= 0)
2866 /* so it failed to advance which means we've got some trailing spaces */
2867 if (pTokEnd
== pTokBegin
) break;
2869 if (xmlStrncmp(pTokBegin
, (xmlChar
const*)"xmlns", 5) != 0)
2872 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2873 debugstr_w(bstr
), debugstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2878 if (*pTokBegin
== '=')
2880 /*valid for XSLPattern?*/
2881 FIXME("Setting default xmlns not supported - skipping.\n");
2884 else if (*pTokBegin
== ':')
2886 ns_entry
->prefix
= ++pTokBegin
;
2887 for (pTokInner
= pTokBegin
; pTokInner
!= pTokEnd
&& *pTokInner
!= '='; ++pTokInner
)
2890 if (pTokInner
== pTokEnd
)
2893 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2894 debugstr_w(bstr
), debugstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2898 ns_entry
->prefix_end
= *pTokInner
;
2902 if (pTokEnd
-pTokInner
> 1 &&
2903 ((*pTokInner
== '\'' && *(pTokEnd
-1) == '\'') ||
2904 (*pTokInner
== '"' && *(pTokEnd
-1) == '"')))
2906 ns_entry
->href
= ++pTokInner
;
2907 ns_entry
->href_end
= *(pTokEnd
-1);
2909 list_add_tail(pNsList
, &ns_entry
->entry
);
2910 /*let libxml figure out if they're valid from here ;)*/
2911 if (xmlXPathRegisterNs(ctx
, ns_entry
->prefix
, ns_entry
->href
) != 0)
2920 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2921 debugstr_w(bstr
), debugstr_an((const char*)pTokInner
, pTokEnd
-pTokInner
));
2922 list_add_tail(pNsList
, &ns_entry
->entry
);
2935 heap_free(ns_entry
);
2936 xmlXPathFreeContext(ctx
);
2939 VariantClear(&varStr
);
2942 else if (lstrcmpiW(p
, PropertyProhibitDTDW
) == 0 ||
2943 lstrcmpiW(p
, PropertyNewParserW
) == 0 ||
2944 lstrcmpiW(p
, PropertyResolveExternalsW
) == 0)
2947 FIXME("Ignoring property %s, value %d\n", debugstr_w(p
), V_BOOL(&value
));
2951 FIXME("Unknown property %s\n", debugstr_w(p
));
2955 static HRESULT WINAPI
domdoc_getProperty(
2956 IXMLDOMDocument3
* iface
,
2960 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2962 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
2965 return E_INVALIDARG
;
2967 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2969 V_VT(var
) = VT_BSTR
;
2970 V_BSTR(var
) = This
->properties
->XPath
?
2971 SysAllocString(PropValueXPathW
) :
2972 SysAllocString(PropValueXSLPatternW
);
2973 return V_BSTR(var
) ? S_OK
: E_OUTOFMEMORY
;
2975 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2978 BSTR rebuiltStr
, cur
;
2979 const xmlChar
*nsStr
;
2980 struct list
*pNsList
;
2981 select_ns_entry
* pNsEntry
;
2983 V_VT(var
) = VT_BSTR
;
2984 nsStr
= This
->properties
->selectNsStr
;
2985 pNsList
= &This
->properties
->selectNsList
;
2986 lenA
= This
->properties
->selectNsStr_len
;
2987 lenW
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, NULL
, 0);
2988 rebuiltStr
= heap_alloc(lenW
*sizeof(WCHAR
));
2989 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, rebuiltStr
, lenW
);
2991 /* this is fine because all of the chars that end tokens are ASCII*/
2992 LIST_FOR_EACH_ENTRY(pNsEntry
, pNsList
, select_ns_entry
, entry
)
2994 while (*cur
!= 0) ++cur
;
2995 if (pNsEntry
->prefix_end
)
2997 *cur
= pNsEntry
->prefix_end
;
2998 while (*cur
!= 0) ++cur
;
3001 if (pNsEntry
->href_end
)
3003 *cur
= pNsEntry
->href_end
;
3006 V_BSTR(var
) = SysAllocString(rebuiltStr
);
3007 heap_free(rebuiltStr
);
3011 FIXME("Unknown property %s\n", debugstr_w(p
));
3015 static HRESULT WINAPI
domdoc_importNode(
3016 IXMLDOMDocument3
* iface
,
3019 IXMLDOMNode
** clone
)
3021 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
3022 FIXME("(%p)->(%p %d %p): stub\n", This
, node
, deep
, clone
);
3026 static const struct IXMLDOMDocument3Vtbl XMLDOMDocument3Vtbl
=
3028 domdoc_QueryInterface
,
3031 domdoc_GetTypeInfoCount
,
3033 domdoc_GetIDsOfNames
,
3035 domdoc_get_nodeName
,
3036 domdoc_get_nodeValue
,
3037 domdoc_put_nodeValue
,
3038 domdoc_get_nodeType
,
3039 domdoc_get_parentNode
,
3040 domdoc_get_childNodes
,
3041 domdoc_get_firstChild
,
3042 domdoc_get_lastChild
,
3043 domdoc_get_previousSibling
,
3044 domdoc_get_nextSibling
,
3045 domdoc_get_attributes
,
3046 domdoc_insertBefore
,
3047 domdoc_replaceChild
,
3050 domdoc_hasChildNodes
,
3051 domdoc_get_ownerDocument
,
3053 domdoc_get_nodeTypeString
,
3056 domdoc_get_specified
,
3057 domdoc_get_definition
,
3058 domdoc_get_nodeTypedValue
,
3059 domdoc_put_nodeTypedValue
,
3060 domdoc_get_dataType
,
3061 domdoc_put_dataType
,
3063 domdoc_transformNode
,
3065 domdoc_selectSingleNode
,
3067 domdoc_get_namespaceURI
,
3069 domdoc_get_baseName
,
3070 domdoc_transformNodeToObject
,
3072 domdoc_get_implementation
,
3073 domdoc_get_documentElement
,
3074 domdoc_put_documentElement
,
3075 domdoc_createElement
,
3076 domdoc_createDocumentFragment
,
3077 domdoc_createTextNode
,
3078 domdoc_createComment
,
3079 domdoc_createCDATASection
,
3080 domdoc_createProcessingInstruction
,
3081 domdoc_createAttribute
,
3082 domdoc_createEntityReference
,
3083 domdoc_getElementsByTagName
,
3087 domdoc_get_readyState
,
3088 domdoc_get_parseError
,
3095 domdoc_get_validateOnParse
,
3096 domdoc_put_validateOnParse
,
3097 domdoc_get_resolveExternals
,
3098 domdoc_put_resolveExternals
,
3099 domdoc_get_preserveWhiteSpace
,
3100 domdoc_put_preserveWhiteSpace
,
3101 domdoc_put_onreadystatechange
,
3102 domdoc_put_onDataAvailable
,
3103 domdoc_put_onTransformNode
,
3104 domdoc_get_namespaces
,
3106 domdoc_putref_schemas
,
3110 domdoc_validateNode
,
3114 /* IConnectionPointContainer */
3115 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
3116 REFIID riid
, void **ppv
)
3118 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3119 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3122 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
3124 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3125 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3128 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
3130 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3131 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3134 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
3135 IEnumConnectionPoints
**ppEnum
)
3137 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3138 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3142 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
3143 REFIID riid
, IConnectionPoint
**cp
)
3145 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3146 ConnectionPoint
*iter
;
3148 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), cp
);
3152 for(iter
= This
->cp_list
; iter
; iter
= iter
->next
)
3154 if (IsEqualGUID(iter
->iid
, riid
))
3155 *cp
= &iter
->IConnectionPoint_iface
;
3160 IConnectionPoint_AddRef(*cp
);
3164 FIXME("unsupported riid %s\n", debugstr_guid(riid
));
3165 return CONNECT_E_NOCONNECTION
;
3169 static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
3171 ConnectionPointContainer_QueryInterface
,
3172 ConnectionPointContainer_AddRef
,
3173 ConnectionPointContainer_Release
,
3174 ConnectionPointContainer_EnumConnectionPoints
,
3175 ConnectionPointContainer_FindConnectionPoint
3178 /* IConnectionPoint */
3179 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
3180 REFIID riid
, void **ppv
)
3182 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3184 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
3188 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
3189 IsEqualGUID(&IID_IConnectionPoint
, riid
))
3196 IConnectionPoint_AddRef(iface
);
3200 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
3201 return E_NOINTERFACE
;
3204 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
3206 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3207 return IConnectionPointContainer_AddRef(This
->container
);
3210 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
3212 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3213 return IConnectionPointContainer_Release(This
->container
);
3216 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*iid
)
3218 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3220 TRACE("(%p)->(%p)\n", This
, iid
);
3222 if (!iid
) return E_POINTER
;
3228 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
3229 IConnectionPointContainer
**container
)
3231 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3233 TRACE("(%p)->(%p)\n", This
, container
);
3235 if (!container
) return E_POINTER
;
3237 *container
= This
->container
;
3238 IConnectionPointContainer_AddRef(*container
);
3242 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*unk_sink
,
3245 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3250 TRACE("(%p)->(%p %p)\n", This
, unk_sink
, cookie
);
3252 hr
= IUnknown_QueryInterface(unk_sink
, This
->iid
, (void**)&sink
);
3253 if(FAILED(hr
) && !IsEqualGUID(&IID_IPropertyNotifySink
, This
->iid
))
3254 hr
= IUnknown_QueryInterface(unk_sink
, &IID_IDispatch
, (void**)&sink
);
3256 return CONNECT_E_CANNOTCONNECT
;
3260 for (i
= 0; i
< This
->sinks_size
; i
++)
3261 if (!This
->sinks
[i
].unk
)
3264 if (i
== This
->sinks_size
)
3265 This
->sinks
= heap_realloc(This
->sinks
,(++This
->sinks_size
)*sizeof(*This
->sinks
));
3269 This
->sinks
= heap_alloc(sizeof(*This
->sinks
));
3270 This
->sinks_size
= 1;
3274 This
->sinks
[i
].unk
= sink
;
3281 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD cookie
)
3283 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3285 TRACE("(%p)->(%d)\n", This
, cookie
);
3287 if (cookie
== 0 || cookie
> This
->sinks_size
|| !This
->sinks
[cookie
-1].unk
)
3288 return CONNECT_E_NOCONNECTION
;
3290 IUnknown_Release(This
->sinks
[cookie
-1].unk
);
3291 This
->sinks
[cookie
-1].unk
= NULL
;
3296 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
3297 IEnumConnections
**ppEnum
)
3299 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3300 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3304 static const IConnectionPointVtbl ConnectionPointVtbl
=
3306 ConnectionPoint_QueryInterface
,
3307 ConnectionPoint_AddRef
,
3308 ConnectionPoint_Release
,
3309 ConnectionPoint_GetConnectionInterface
,
3310 ConnectionPoint_GetConnectionPointContainer
,
3311 ConnectionPoint_Advise
,
3312 ConnectionPoint_Unadvise
,
3313 ConnectionPoint_EnumConnections
3316 static void ConnectionPoint_Init(ConnectionPoint
*cp
, struct domdoc
*doc
, REFIID riid
)
3318 cp
->IConnectionPoint_iface
.lpVtbl
= &ConnectionPointVtbl
;
3324 cp
->next
= doc
->cp_list
;
3327 cp
->container
= &doc
->IConnectionPointContainer_iface
;
3330 /* domdoc implementation of IObjectWithSite */
3331 static HRESULT WINAPI
3332 domdoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
3334 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3335 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObject
);
3338 static ULONG WINAPI
domdoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
3340 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3341 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3344 static ULONG WINAPI
domdoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
3346 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3347 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3350 static HRESULT WINAPI
domdoc_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
3352 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3354 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
3359 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
3362 static HRESULT WINAPI
domdoc_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
3364 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3366 TRACE("(%p)->(%p)\n", iface
, punk
);
3372 IUnknown_Release( This
->site
);
3379 IUnknown_AddRef( punk
);
3382 IUnknown_Release( This
->site
);
3389 static const IObjectWithSiteVtbl domdocObjectSite
=
3391 domdoc_ObjectWithSite_QueryInterface
,
3392 domdoc_ObjectWithSite_AddRef
,
3393 domdoc_ObjectWithSite_Release
,
3394 domdoc_ObjectWithSite_SetSite
,
3395 domdoc_ObjectWithSite_GetSite
3398 static HRESULT WINAPI
domdoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
3400 domdoc
*This
= impl_from_IObjectSafety(iface
);
3401 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3404 static ULONG WINAPI
domdoc_Safety_AddRef(IObjectSafety
*iface
)
3406 domdoc
*This
= impl_from_IObjectSafety(iface
);
3407 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3410 static ULONG WINAPI
domdoc_Safety_Release(IObjectSafety
*iface
)
3412 domdoc
*This
= impl_from_IObjectSafety(iface
);
3413 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3416 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
3418 static HRESULT WINAPI
domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3419 DWORD
*supported
, DWORD
*enabled
)
3421 domdoc
*This
= impl_from_IObjectSafety(iface
);
3423 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
3425 if(!supported
|| !enabled
) return E_POINTER
;
3427 *supported
= SAFETY_SUPPORTED_OPTIONS
;
3428 *enabled
= This
->safeopt
;
3433 static HRESULT WINAPI
domdoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3434 DWORD mask
, DWORD enabled
)
3436 domdoc
*This
= impl_from_IObjectSafety(iface
);
3437 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
3439 if ((mask
& ~SAFETY_SUPPORTED_OPTIONS
) != 0)
3442 This
->safeopt
= (This
->safeopt
& ~mask
) | (mask
& enabled
);
3447 #undef SAFETY_SUPPORTED_OPTIONS
3449 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
3450 domdoc_Safety_QueryInterface
,
3451 domdoc_Safety_AddRef
,
3452 domdoc_Safety_Release
,
3453 domdoc_Safety_GetInterfaceSafetyOptions
,
3454 domdoc_Safety_SetInterfaceSafetyOptions
3457 static const tid_t domdoc_iface_tids
[] = {
3458 IXMLDOMDocument3_tid
,
3462 static dispex_static_data_t domdoc_dispex
= {
3464 IXMLDOMDocument3_tid
,
3469 HRESULT
get_domdoc_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument3
**document
)
3473 doc
= heap_alloc( sizeof (*doc
) );
3475 return E_OUTOFMEMORY
;
3477 doc
->IXMLDOMDocument3_iface
.lpVtbl
= &XMLDOMDocument3Vtbl
;
3478 doc
->IPersistStreamInit_iface
.lpVtbl
= &xmldoc_IPersistStreamInit_VTable
;
3479 doc
->IObjectWithSite_iface
.lpVtbl
= &domdocObjectSite
;
3480 doc
->IObjectSafety_iface
.lpVtbl
= &domdocObjectSafetyVtbl
;
3481 doc
->IConnectionPointContainer_iface
.lpVtbl
= &ConnectionPointContainerVtbl
;
3483 doc
->async
= VARIANT_TRUE
;
3484 doc
->validating
= 0;
3486 doc
->properties
= properties_from_xmlDocPtr(xmldoc
);
3491 doc
->cp_list
= NULL
;
3492 doc
->namespaces
= NULL
;
3493 memset(doc
->events
, 0, sizeof(doc
->events
));
3495 /* events connection points */
3496 ConnectionPoint_Init(&doc
->cp_dispatch
, doc
, &IID_IDispatch
);
3497 ConnectionPoint_Init(&doc
->cp_propnotif
, doc
, &IID_IPropertyNotifySink
);
3498 ConnectionPoint_Init(&doc
->cp_domdocevents
, doc
, &DIID_XMLDOMDocumentEvents
);
3500 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IXMLDOMNode
*)&doc
->IXMLDOMDocument3_iface
,
3503 *document
= &doc
->IXMLDOMDocument3_iface
;
3505 TRACE("returning iface %p\n", *document
);
3509 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3514 TRACE("(%d, %p, %p)\n", version
, pUnkOuter
, ppObj
);
3516 xmldoc
= xmlNewDoc(NULL
);
3518 return E_OUTOFMEMORY
;
3520 xmldoc_init(xmldoc
, version
);
3522 hr
= get_domdoc_from_xmldoc(xmldoc
, (IXMLDOMDocument3
**)ppObj
);
3525 free_properties(properties_from_xmlDocPtr(xmldoc
));
3526 heap_free(xmldoc
->_private
);
3534 IUnknown
* create_domdoc( xmlNodePtr document
)
3539 TRACE("(%p)\n", document
);
3541 hr
= get_domdoc_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument3
**)&pObj
);
3550 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3552 MESSAGE("This program tried to use a DOMDocument object, but\n"
3553 "libxml2 support was not present at compile time.\n");