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_refs(xmlDocPtr doc
, LONG refs
)
558 LONG ref
= InterlockedExchangeAdd(&priv_from_xmlDocPtr(doc
)->refs
, refs
) + refs
;
559 TRACE("(%p)->(%d)\n", doc
, ref
);
563 LONG
xmldoc_add_ref(xmlDocPtr doc
)
565 return xmldoc_add_refs(doc
, 1);
568 LONG
xmldoc_release_refs(xmlDocPtr doc
, LONG refs
)
570 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
571 LONG ref
= InterlockedExchangeAdd(&priv
->refs
, -refs
) - refs
;
572 TRACE("(%p)->(%d)\n", doc
, ref
);
575 WARN("negative refcount, expect troubles\n");
579 orphan_entry
*orphan
, *orphan2
;
580 TRACE("freeing docptr %p\n", doc
);
582 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
584 xmlFreeNode( orphan
->node
);
587 free_properties(priv
->properties
);
588 heap_free(doc
->_private
);
596 LONG
xmldoc_release(xmlDocPtr doc
)
598 return xmldoc_release_refs(doc
, 1);
601 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
603 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
606 entry
= heap_alloc( sizeof (*entry
) );
608 return E_OUTOFMEMORY
;
611 list_add_head( &priv
->orphans
, &entry
->entry
);
615 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
617 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
618 orphan_entry
*entry
, *entry2
;
620 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
622 if( entry
->node
== node
)
624 list_remove( &entry
->entry
);
633 static inline xmlDocPtr
get_doc( domdoc
*This
)
635 return This
->node
.node
->doc
;
638 static HRESULT
attach_xmldoc(domdoc
*This
, xmlDocPtr xml
)
640 release_namespaces(This
);
644 priv_from_xmlDocPtr(get_doc(This
))->properties
= NULL
;
645 if (xmldoc_release(get_doc(This
)) != 0)
646 priv_from_xmlDocPtr(get_doc(This
))->properties
=
647 copy_properties(This
->properties
);
650 This
->node
.node
= (xmlNodePtr
) xml
;
654 xmldoc_add_ref(get_doc(This
));
655 priv_from_xmlDocPtr(get_doc(This
))->properties
= This
->properties
;
661 static inline domdoc
*impl_from_IXMLDOMDocument3( IXMLDOMDocument3
*iface
)
663 return CONTAINING_RECORD(iface
, domdoc
, IXMLDOMDocument3_iface
);
666 static inline domdoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
668 return CONTAINING_RECORD(iface
, domdoc
, IPersistStreamInit_iface
);
671 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
673 return CONTAINING_RECORD(iface
, domdoc
, IObjectWithSite_iface
);
676 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
678 return CONTAINING_RECORD(iface
, domdoc
, IObjectSafety_iface
);
681 static inline domdoc
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
683 return CONTAINING_RECORD(iface
, domdoc
, IConnectionPointContainer_iface
);
686 /************************************************************************
687 * domdoc implementation of IPersistStream.
689 static HRESULT WINAPI
PersistStreamInit_QueryInterface(
690 IPersistStreamInit
*iface
, REFIID riid
, void **ppvObj
)
692 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
693 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObj
);
696 static ULONG WINAPI
PersistStreamInit_AddRef(
697 IPersistStreamInit
*iface
)
699 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
700 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
703 static ULONG WINAPI
PersistStreamInit_Release(
704 IPersistStreamInit
*iface
)
706 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
707 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
710 static HRESULT WINAPI
PersistStreamInit_GetClassID(
711 IPersistStreamInit
*iface
, CLSID
*classid
)
713 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
714 TRACE("(%p)->(%p)\n", This
, classid
);
719 *classid
= *DOMDocument_version(This
->properties
->version
);
724 static HRESULT WINAPI
PersistStreamInit_IsDirty(
725 IPersistStreamInit
*iface
)
727 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
728 FIXME("(%p): stub!\n", This
);
732 static HRESULT
domdoc_load_from_stream(domdoc
*doc
, ISequentialStream
*stream
)
734 DWORD read
, written
, len
;
735 xmlDocPtr xmldoc
= NULL
;
743 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &hstream
);
749 ISequentialStream_Read(stream
, buf
, sizeof(buf
), &read
);
750 hr
= IStream_Write(hstream
, buf
, read
, &written
);
751 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
755 ERR("failed to copy stream 0x%08x\n", hr
);
756 IStream_Release(hstream
);
760 hr
= GetHGlobalFromStream(hstream
, &hglobal
);
764 len
= GlobalSize(hglobal
);
765 ptr
= GlobalLock(hglobal
);
767 xmldoc
= doparse(doc
, ptr
, len
, XML_CHAR_ENCODING_NONE
);
768 GlobalUnlock(hglobal
);
772 ERR("Failed to parse xml\n");
776 xmldoc
->_private
= create_priv();
778 return attach_xmldoc(doc
, xmldoc
);
781 static HRESULT WINAPI
PersistStreamInit_Load(IPersistStreamInit
*iface
, IStream
*stream
)
783 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
785 TRACE("(%p)->(%p)\n", This
, stream
);
790 return domdoc_load_from_stream(This
, (ISequentialStream
*)stream
);
793 static HRESULT WINAPI
PersistStreamInit_Save(
794 IPersistStreamInit
*iface
, IStream
*stream
, BOOL clr_dirty
)
796 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
800 TRACE("(%p)->(%p %d)\n", This
, stream
, clr_dirty
);
802 hr
= IXMLDOMDocument3_get_xml(&This
->IXMLDOMDocument3_iface
, &xmlString
);
805 DWORD len
= SysStringLen(xmlString
) * sizeof(WCHAR
);
807 hr
= IStream_Write( stream
, xmlString
, len
, NULL
);
808 SysFreeString(xmlString
);
811 TRACE("ret 0x%08x\n", hr
);
816 static HRESULT WINAPI
PersistStreamInit_GetSizeMax(
817 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
819 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
820 TRACE("(%p)->(%p)\n", This
, pcbSize
);
824 static HRESULT WINAPI
PersistStreamInit_InitNew(
825 IPersistStreamInit
*iface
)
827 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
828 TRACE("(%p)\n", This
);
832 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
834 PersistStreamInit_QueryInterface
,
835 PersistStreamInit_AddRef
,
836 PersistStreamInit_Release
,
837 PersistStreamInit_GetClassID
,
838 PersistStreamInit_IsDirty
,
839 PersistStreamInit_Load
,
840 PersistStreamInit_Save
,
841 PersistStreamInit_GetSizeMax
,
842 PersistStreamInit_InitNew
845 /* IXMLDOMDocument3 interface */
847 static const tid_t domdoc_se_tids
[] = {
850 IXMLDOMDocument2_tid
,
851 IXMLDOMDocument3_tid
,
855 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument3
*iface
, REFIID riid
, void** ppvObject
)
857 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
859 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppvObject
);
863 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
864 IsEqualGUID( riid
, &IID_IDispatch
) ||
865 IsEqualGUID( riid
, &IID_IXMLDOMNode
) ||
866 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
867 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
)||
868 IsEqualGUID( riid
, &IID_IXMLDOMDocument3
))
872 else if (IsEqualGUID(&IID_IPersistStream
, riid
) ||
873 IsEqualGUID(&IID_IPersistStreamInit
, riid
))
875 *ppvObject
= &This
->IPersistStreamInit_iface
;
877 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
879 *ppvObject
= &This
->IObjectWithSite_iface
;
881 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
883 *ppvObject
= &This
->IObjectSafety_iface
;
885 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
887 return node_create_supporterrorinfo(domdoc_se_tids
, ppvObject
);
889 else if(node_query_interface(&This
->node
, riid
, ppvObject
))
891 return *ppvObject
? S_OK
: E_NOINTERFACE
;
893 else if (IsEqualGUID( riid
, &IID_IConnectionPointContainer
))
895 *ppvObject
= &This
->IConnectionPointContainer_iface
;
899 TRACE("interface %s not implemented\n", debugstr_guid(riid
));
900 return E_NOINTERFACE
;
903 IUnknown_AddRef((IUnknown
*)*ppvObject
);
908 static ULONG WINAPI
domdoc_AddRef( IXMLDOMDocument3
*iface
)
910 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
911 ULONG ref
= InterlockedIncrement( &This
->ref
);
912 TRACE("(%p)->(%d)\n", This
, ref
);
916 static ULONG WINAPI
domdoc_Release( IXMLDOMDocument3
*iface
)
918 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
919 LONG ref
= InterlockedDecrement( &This
->ref
);
921 TRACE("(%p)->(%d)\n", This
, ref
);
928 detach_bsc(This
->bsc
);
931 IUnknown_Release( This
->site
);
932 destroy_xmlnode(&This
->node
);
934 for (eid
= 0; eid
< EVENTID_LAST
; eid
++)
935 if (This
->events
[eid
]) IDispatch_Release(This
->events
[eid
]);
937 release_namespaces(This
);
944 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument3
*iface
, UINT
* pctinfo
)
946 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
947 return IDispatchEx_GetTypeInfoCount(&This
->node
.dispex
.IDispatchEx_iface
, pctinfo
);
950 static HRESULT WINAPI
domdoc_GetTypeInfo(
951 IXMLDOMDocument3
*iface
,
952 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
954 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
955 return IDispatchEx_GetTypeInfo(&This
->node
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
958 static HRESULT WINAPI
domdoc_GetIDsOfNames(
959 IXMLDOMDocument3
*iface
,
966 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
967 return IDispatchEx_GetIDsOfNames(&This
->node
.dispex
.IDispatchEx_iface
,
968 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
971 static HRESULT WINAPI
domdoc_Invoke(
972 IXMLDOMDocument3
*iface
,
977 DISPPARAMS
* pDispParams
,
979 EXCEPINFO
* pExcepInfo
,
982 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
983 return IDispatchEx_Invoke(&This
->node
.dispex
.IDispatchEx_iface
,
984 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
987 static HRESULT WINAPI
domdoc_get_nodeName(
988 IXMLDOMDocument3
*iface
,
991 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
993 static const WCHAR documentW
[] = {'#','d','o','c','u','m','e','n','t',0};
995 TRACE("(%p)->(%p)\n", This
, name
);
997 return return_bstr(documentW
, name
);
1001 static HRESULT WINAPI
domdoc_get_nodeValue(
1002 IXMLDOMDocument3
*iface
,
1005 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1007 TRACE("(%p)->(%p)\n", This
, value
);
1010 return E_INVALIDARG
;
1012 V_VT(value
) = VT_NULL
;
1013 V_BSTR(value
) = NULL
; /* tests show that we should do this */
1018 static HRESULT WINAPI
domdoc_put_nodeValue(
1019 IXMLDOMDocument3
*iface
,
1022 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1023 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&value
));
1028 static HRESULT WINAPI
domdoc_get_nodeType(
1029 IXMLDOMDocument3
*iface
,
1032 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1034 TRACE("(%p)->(%p)\n", This
, type
);
1036 *type
= NODE_DOCUMENT
;
1041 static HRESULT WINAPI
domdoc_get_parentNode(
1042 IXMLDOMDocument3
*iface
,
1043 IXMLDOMNode
** parent
)
1045 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1047 TRACE("(%p)->(%p)\n", This
, parent
);
1049 return node_get_parent(&This
->node
, parent
);
1053 static HRESULT WINAPI
domdoc_get_childNodes(
1054 IXMLDOMDocument3
*iface
,
1055 IXMLDOMNodeList
** childList
)
1057 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1059 TRACE("(%p)->(%p)\n", This
, childList
);
1061 return node_get_child_nodes(&This
->node
, childList
);
1065 static HRESULT WINAPI
domdoc_get_firstChild(
1066 IXMLDOMDocument3
*iface
,
1067 IXMLDOMNode
** firstChild
)
1069 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1071 TRACE("(%p)->(%p)\n", This
, firstChild
);
1073 return node_get_first_child(&This
->node
, firstChild
);
1077 static HRESULT WINAPI
domdoc_get_lastChild(
1078 IXMLDOMDocument3
*iface
,
1079 IXMLDOMNode
** lastChild
)
1081 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1083 TRACE("(%p)->(%p)\n", This
, lastChild
);
1085 return node_get_last_child(&This
->node
, lastChild
);
1089 static HRESULT WINAPI
domdoc_get_previousSibling(
1090 IXMLDOMDocument3
*iface
,
1091 IXMLDOMNode
** previousSibling
)
1093 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1095 TRACE("(%p)->(%p)\n", This
, previousSibling
);
1097 return return_null_node(previousSibling
);
1101 static HRESULT WINAPI
domdoc_get_nextSibling(
1102 IXMLDOMDocument3
*iface
,
1103 IXMLDOMNode
** nextSibling
)
1105 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1107 TRACE("(%p)->(%p)\n", This
, nextSibling
);
1109 return return_null_node(nextSibling
);
1113 static HRESULT WINAPI
domdoc_get_attributes(
1114 IXMLDOMDocument3
*iface
,
1115 IXMLDOMNamedNodeMap
** attributeMap
)
1117 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1119 TRACE("(%p)->(%p)\n", This
, attributeMap
);
1121 return return_null_ptr((void**)attributeMap
);
1125 static HRESULT WINAPI
domdoc_insertBefore(
1126 IXMLDOMDocument3
*iface
,
1127 IXMLDOMNode
* newChild
,
1129 IXMLDOMNode
** outNewChild
)
1131 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1135 TRACE("(%p)->(%p %s %p)\n", This
, newChild
, debugstr_variant(&refChild
), outNewChild
);
1137 hr
= IXMLDOMNode_get_nodeType(newChild
, &type
);
1138 if (hr
!= S_OK
) return hr
;
1140 TRACE("new node type %d\n", type
);
1143 case NODE_ATTRIBUTE
:
1145 case NODE_CDATA_SECTION
:
1146 if (outNewChild
) *outNewChild
= NULL
;
1149 return node_insert_before(&This
->node
, newChild
, &refChild
, outNewChild
);
1153 static HRESULT WINAPI
domdoc_replaceChild(
1154 IXMLDOMDocument3
*iface
,
1155 IXMLDOMNode
* newChild
,
1156 IXMLDOMNode
* oldChild
,
1157 IXMLDOMNode
** outOldChild
)
1159 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1161 TRACE("(%p)->(%p %p %p)\n", This
, newChild
, oldChild
, outOldChild
);
1163 return node_replace_child(&This
->node
, newChild
, oldChild
, outOldChild
);
1167 static HRESULT WINAPI
domdoc_removeChild(
1168 IXMLDOMDocument3
*iface
,
1170 IXMLDOMNode
**oldChild
)
1172 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1173 TRACE("(%p)->(%p %p)\n", This
, child
, oldChild
);
1174 return node_remove_child(&This
->node
, child
, oldChild
);
1178 static HRESULT WINAPI
domdoc_appendChild(
1179 IXMLDOMDocument3
*iface
,
1181 IXMLDOMNode
**outChild
)
1183 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1184 TRACE("(%p)->(%p %p)\n", This
, child
, outChild
);
1185 return node_append_child(&This
->node
, child
, outChild
);
1189 static HRESULT WINAPI
domdoc_hasChildNodes(
1190 IXMLDOMDocument3
*iface
,
1193 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1194 TRACE("(%p)->(%p)\n", This
, ret
);
1195 return node_has_childnodes(&This
->node
, ret
);
1199 static HRESULT WINAPI
domdoc_get_ownerDocument(
1200 IXMLDOMDocument3
*iface
,
1201 IXMLDOMDocument
**doc
)
1203 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1204 TRACE("(%p)->(%p)\n", This
, doc
);
1205 return node_get_owner_doc(&This
->node
, doc
);
1209 static HRESULT WINAPI
domdoc_cloneNode(
1210 IXMLDOMDocument3
*iface
,
1212 IXMLDOMNode
** outNode
)
1214 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1215 TRACE("(%p)->(%d %p)\n", This
, deep
, outNode
);
1216 return node_clone( &This
->node
, deep
, outNode
);
1220 static HRESULT WINAPI
domdoc_get_nodeTypeString(
1221 IXMLDOMDocument3
*iface
,
1224 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1225 static const WCHAR documentW
[] = {'d','o','c','u','m','e','n','t',0};
1227 TRACE("(%p)->(%p)\n", This
, p
);
1229 return return_bstr(documentW
, p
);
1233 static HRESULT WINAPI
domdoc_get_text(
1234 IXMLDOMDocument3
*iface
,
1237 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1238 TRACE("(%p)->(%p)\n", This
, p
);
1239 return node_get_text(&This
->node
, p
);
1243 static HRESULT WINAPI
domdoc_put_text(
1244 IXMLDOMDocument3
*iface
,
1247 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1248 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
1253 static HRESULT WINAPI
domdoc_get_specified(
1254 IXMLDOMDocument3
*iface
,
1255 VARIANT_BOOL
* isSpecified
)
1257 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1258 FIXME("(%p)->(%p) stub!\n", This
, isSpecified
);
1259 *isSpecified
= VARIANT_TRUE
;
1264 static HRESULT WINAPI
domdoc_get_definition(
1265 IXMLDOMDocument3
*iface
,
1266 IXMLDOMNode
** definitionNode
)
1268 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1269 FIXME("(%p)->(%p)\n", This
, definitionNode
);
1274 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
1275 IXMLDOMDocument3
*iface
,
1278 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1279 TRACE("(%p)->(%p)\n", This
, v
);
1280 return return_null_var(v
);
1283 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
1284 IXMLDOMDocument3
*iface
,
1285 VARIANT typedValue
)
1287 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1288 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&typedValue
));
1293 static HRESULT WINAPI
domdoc_get_dataType(
1294 IXMLDOMDocument3
*iface
,
1297 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1298 TRACE("(%p)->(%p)\n", This
, typename
);
1299 return return_null_var( typename
);
1303 static HRESULT WINAPI
domdoc_put_dataType(
1304 IXMLDOMDocument3
*iface
,
1307 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1309 FIXME("(%p)->(%s)\n", This
, debugstr_w(dataTypeName
));
1312 return E_INVALIDARG
;
1317 static int XMLCALL
domdoc_get_xml_writecallback(void *ctx
, const char *data
, int len
)
1319 return xmlBufferAdd((xmlBufferPtr
)ctx
, (xmlChar
*)data
, len
) == 0 ? len
: 0;
1322 static HRESULT WINAPI
domdoc_get_xml(
1323 IXMLDOMDocument3
*iface
,
1326 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1327 xmlSaveCtxtPtr ctxt
;
1332 TRACE("(%p)->(%p)\n", This
, p
);
1335 return E_INVALIDARG
;
1339 buf
= xmlBufferCreate();
1341 return E_OUTOFMEMORY
;
1343 options
= XML_SAVE_FORMAT
| XML_SAVE_NO_DECL
;
1344 ctxt
= xmlSaveToIO(domdoc_get_xml_writecallback
, NULL
, buf
, "UTF-8", options
);
1349 return E_OUTOFMEMORY
;
1352 ret
= xmlSaveDoc(ctxt
, get_doc(This
));
1353 /* flushes on close */
1356 TRACE("%ld, len=%d\n", ret
, xmlBufferLength(buf
));
1357 if(ret
!= -1 && xmlBufferLength(buf
) > 0)
1361 content
= bstr_from_xmlChar(xmlBufferContent(buf
));
1362 content
= EnsureCorrectEOL(content
);
1368 *p
= SysAllocStringLen(NULL
, 0);
1373 return *p
? S_OK
: E_OUTOFMEMORY
;
1377 static HRESULT WINAPI
domdoc_transformNode(
1378 IXMLDOMDocument3
*iface
,
1382 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1383 TRACE("(%p)->(%p %p)\n", This
, node
, p
);
1384 return node_transform_node(&This
->node
, node
, p
);
1388 static HRESULT WINAPI
domdoc_selectNodes(
1389 IXMLDOMDocument3
*iface
,
1391 IXMLDOMNodeList
**outList
)
1393 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1394 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outList
);
1395 return node_select_nodes(&This
->node
, p
, outList
);
1399 static HRESULT WINAPI
domdoc_selectSingleNode(
1400 IXMLDOMDocument3
*iface
,
1402 IXMLDOMNode
**outNode
)
1404 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1405 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outNode
);
1406 return node_select_singlenode(&This
->node
, p
, outNode
);
1410 static HRESULT WINAPI
domdoc_get_parsed(
1411 IXMLDOMDocument3
*iface
,
1412 VARIANT_BOOL
* isParsed
)
1414 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1415 FIXME("(%p)->(%p) stub!\n", This
, isParsed
);
1416 *isParsed
= VARIANT_TRUE
;
1420 static HRESULT WINAPI
domdoc_get_namespaceURI(
1421 IXMLDOMDocument3
*iface
,
1422 BSTR
* namespaceURI
)
1424 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1425 TRACE("(%p)->(%p)\n", This
, namespaceURI
);
1426 return return_null_bstr( namespaceURI
);
1429 static HRESULT WINAPI
domdoc_get_prefix(
1430 IXMLDOMDocument3
*iface
,
1433 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1434 TRACE("(%p)->(%p)\n", This
, prefix
);
1435 return return_null_bstr( prefix
);
1439 static HRESULT WINAPI
domdoc_get_baseName(
1440 IXMLDOMDocument3
*iface
,
1443 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1444 TRACE("(%p)->(%p)\n", This
, name
);
1445 return return_null_bstr( name
);
1449 static HRESULT WINAPI
domdoc_transformNodeToObject(
1450 IXMLDOMDocument3
*iface
,
1451 IXMLDOMNode
* stylesheet
,
1452 VARIANT outputObject
)
1454 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1455 FIXME("(%p)->(%p %s)\n", This
, stylesheet
, debugstr_variant(&outputObject
));
1460 static HRESULT WINAPI
domdoc_get_doctype(
1461 IXMLDOMDocument3
*iface
,
1462 IXMLDOMDocumentType
** doctype
)
1464 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1469 TRACE("(%p)->(%p)\n", This
, doctype
);
1471 if (!doctype
) return E_INVALIDARG
;
1475 dtd
= xmlGetIntSubset(get_doc(This
));
1476 if (!dtd
) return S_FALSE
;
1478 node
= create_node((xmlNodePtr
)dtd
);
1479 if (!node
) return S_FALSE
;
1481 hr
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentType
, (void**)doctype
);
1482 IXMLDOMNode_Release(node
);
1488 static HRESULT WINAPI
domdoc_get_implementation(
1489 IXMLDOMDocument3
*iface
,
1490 IXMLDOMImplementation
** impl
)
1492 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1494 TRACE("(%p)->(%p)\n", This
, impl
);
1497 return E_INVALIDARG
;
1499 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
1504 static HRESULT WINAPI
domdoc_get_documentElement(
1505 IXMLDOMDocument3
*iface
,
1506 IXMLDOMElement
** DOMElement
)
1508 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1509 IXMLDOMNode
*element_node
;
1513 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1516 return E_INVALIDARG
;
1520 root
= xmlDocGetRootElement( get_doc(This
) );
1524 element_node
= create_node( root
);
1525 if(!element_node
) return S_FALSE
;
1527 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (void**)DOMElement
);
1528 IXMLDOMNode_Release(element_node
);
1534 static HRESULT WINAPI
domdoc_put_documentElement(
1535 IXMLDOMDocument3
*iface
,
1536 IXMLDOMElement
* DOMElement
)
1538 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1539 IXMLDOMNode
*elementNode
;
1546 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1548 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1552 xmlNode
= get_node_obj( elementNode
);
1553 if(!xmlNode
) return E_FAIL
;
1555 if(!xmlNode
->node
->parent
)
1556 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1557 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1559 old_doc
= xmlNode
->node
->doc
;
1560 if (old_doc
!= get_doc(This
))
1561 refcount
= xmlnode_get_inst_cnt(xmlNode
);
1563 /* old root is still orphaned by its document, update refcount from new root */
1564 if (refcount
) xmldoc_add_refs(get_doc(This
), refcount
);
1565 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1566 if (refcount
) xmldoc_release_refs(old_doc
, refcount
);
1567 IXMLDOMNode_Release( elementNode
);
1570 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1576 static HRESULT WINAPI
domdoc_createElement(
1577 IXMLDOMDocument3
*iface
,
1579 IXMLDOMElement
** element
)
1581 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1586 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagname
), element
);
1588 if (!element
|| !tagname
) return E_INVALIDARG
;
1590 V_VT(&type
) = VT_I1
;
1591 V_I1(&type
) = NODE_ELEMENT
;
1593 hr
= IXMLDOMDocument3_createNode(iface
, type
, tagname
, NULL
, &node
);
1596 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMElement
, (void**)element
);
1597 IXMLDOMNode_Release(node
);
1604 static HRESULT WINAPI
domdoc_createDocumentFragment(
1605 IXMLDOMDocument3
*iface
,
1606 IXMLDOMDocumentFragment
** frag
)
1608 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1613 TRACE("(%p)->(%p)\n", This
, frag
);
1615 if (!frag
) return E_INVALIDARG
;
1619 V_VT(&type
) = VT_I1
;
1620 V_I1(&type
) = NODE_DOCUMENT_FRAGMENT
;
1622 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1625 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentFragment
, (void**)frag
);
1626 IXMLDOMNode_Release(node
);
1633 static HRESULT WINAPI
domdoc_createTextNode(
1634 IXMLDOMDocument3
*iface
,
1636 IXMLDOMText
** text
)
1638 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1643 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), text
);
1645 if (!text
) return E_INVALIDARG
;
1649 V_VT(&type
) = VT_I1
;
1650 V_I1(&type
) = NODE_TEXT
;
1652 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1655 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)text
);
1656 IXMLDOMNode_Release(node
);
1657 hr
= IXMLDOMText_put_data(*text
, data
);
1664 static HRESULT WINAPI
domdoc_createComment(
1665 IXMLDOMDocument3
*iface
,
1667 IXMLDOMComment
** comment
)
1669 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1674 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), comment
);
1676 if (!comment
) return E_INVALIDARG
;
1680 V_VT(&type
) = VT_I1
;
1681 V_I1(&type
) = NODE_COMMENT
;
1683 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1686 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)comment
);
1687 IXMLDOMNode_Release(node
);
1688 hr
= IXMLDOMComment_put_data(*comment
, data
);
1695 static HRESULT WINAPI
domdoc_createCDATASection(
1696 IXMLDOMDocument3
*iface
,
1698 IXMLDOMCDATASection
** cdata
)
1700 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1705 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), cdata
);
1707 if (!cdata
) return E_INVALIDARG
;
1711 V_VT(&type
) = VT_I1
;
1712 V_I1(&type
) = NODE_CDATA_SECTION
;
1714 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1717 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)cdata
);
1718 IXMLDOMNode_Release(node
);
1719 hr
= IXMLDOMCDATASection_put_data(*cdata
, data
);
1726 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1727 IXMLDOMDocument3
*iface
,
1730 IXMLDOMProcessingInstruction
** pi
)
1732 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1737 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(target
), debugstr_w(data
), pi
);
1739 if (!pi
) return E_INVALIDARG
;
1743 V_VT(&type
) = VT_I1
;
1744 V_I1(&type
) = NODE_PROCESSING_INSTRUCTION
;
1746 hr
= IXMLDOMDocument3_createNode(iface
, type
, target
, NULL
, &node
);
1751 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1752 node_obj
= get_node_obj(node
);
1753 hr
= node_set_content(node_obj
, data
);
1755 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMProcessingInstruction
, (void**)pi
);
1756 IXMLDOMNode_Release(node
);
1763 static HRESULT WINAPI
domdoc_createAttribute(
1764 IXMLDOMDocument3
*iface
,
1766 IXMLDOMAttribute
** attribute
)
1768 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1773 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), attribute
);
1775 if (!attribute
|| !name
) return E_INVALIDARG
;
1777 V_VT(&type
) = VT_I1
;
1778 V_I1(&type
) = NODE_ATTRIBUTE
;
1780 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1783 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMAttribute
, (void**)attribute
);
1784 IXMLDOMNode_Release(node
);
1791 static HRESULT WINAPI
domdoc_createEntityReference(
1792 IXMLDOMDocument3
*iface
,
1794 IXMLDOMEntityReference
** entityref
)
1796 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1801 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), entityref
);
1803 if (!entityref
) return E_INVALIDARG
;
1807 V_VT(&type
) = VT_I1
;
1808 V_I1(&type
) = NODE_ENTITY_REFERENCE
;
1810 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1813 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMEntityReference
, (void**)entityref
);
1814 IXMLDOMNode_Release(node
);
1820 xmlChar
* tagName_to_XPath(const BSTR tagName
)
1822 xmlChar
*query
, *tmp
;
1823 static const xmlChar mod_pre
[] = "*[local-name()='";
1824 static const xmlChar mod_post
[] = "']";
1825 static const xmlChar prefix
[] = "descendant::";
1826 const WCHAR
*tokBegin
, *tokEnd
;
1829 query
= xmlStrdup(prefix
);
1832 while (tokBegin
&& *tokBegin
)
1837 query
= xmlStrcat(query
, BAD_CAST
"/");
1841 query
= xmlStrcat(query
, BAD_CAST
"*");
1845 query
= xmlStrcat(query
, mod_pre
);
1847 while (*tokEnd
&& *tokEnd
!= '/')
1849 len
= WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, NULL
, 0, NULL
, NULL
);
1850 tmp
= xmlMalloc(len
);
1851 WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, (char*)tmp
, len
, NULL
, NULL
);
1852 query
= xmlStrncat(query
, tmp
, len
);
1855 query
= xmlStrcat(query
, mod_post
);
1862 static HRESULT WINAPI
domdoc_getElementsByTagName(
1863 IXMLDOMDocument3
*iface
,
1865 IXMLDOMNodeList
** resultList
)
1867 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1872 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(tagName
), resultList
);
1874 if (!tagName
|| !resultList
) return E_INVALIDARG
;
1876 XPath
= This
->properties
->XPath
;
1877 This
->properties
->XPath
= TRUE
;
1878 query
= tagName_to_XPath(tagName
);
1879 hr
= create_selection((xmlNodePtr
)get_doc(This
), query
, resultList
);
1881 This
->properties
->XPath
= XPath
;
1886 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1892 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1894 return E_INVALIDARG
;
1901 static HRESULT WINAPI
domdoc_createNode(
1902 IXMLDOMDocument3
*iface
,
1906 IXMLDOMNode
** node
)
1908 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1909 DOMNodeType node_type
;
1911 xmlChar
*xml_name
, *href
;
1914 TRACE("(%p)->(%s %s %s %p)\n", This
, debugstr_variant(&Type
), debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1916 if(!node
) return E_INVALIDARG
;
1918 hr
= get_node_type(Type
, &node_type
);
1919 if(FAILED(hr
)) return hr
;
1921 if(namespaceURI
&& namespaceURI
[0] && node_type
!= NODE_ELEMENT
)
1922 FIXME("nodes with namespaces currently not supported.\n");
1924 TRACE("node_type %d\n", node_type
);
1926 /* exit earlier for types that need name */
1930 case NODE_ATTRIBUTE
:
1931 case NODE_ENTITY_REFERENCE
:
1932 case NODE_PROCESSING_INSTRUCTION
:
1933 if (!name
|| *name
== 0) return E_FAIL
;
1939 xml_name
= xmlchar_from_wchar(name
);
1940 /* prevent empty href to be allocated */
1941 href
= namespaceURI
? xmlchar_from_wchar(namespaceURI
) : NULL
;
1947 xmlChar
*local
, *prefix
;
1949 local
= xmlSplitQName2(xml_name
, &prefix
);
1951 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, local
? local
: xml_name
, NULL
);
1953 /* allow to create default namespace xmlns= */
1954 if (local
|| (href
&& *href
))
1956 xmlNsPtr ns
= xmlNewNs(xmlnode
, href
, prefix
);
1957 xmlSetNs(xmlnode
, ns
);
1965 case NODE_ATTRIBUTE
:
1966 xmlnode
= (xmlNodePtr
)xmlNewDocProp(get_doc(This
), xml_name
, NULL
);
1969 xmlnode
= (xmlNodePtr
)xmlNewDocText(get_doc(This
), NULL
);
1971 case NODE_CDATA_SECTION
:
1972 xmlnode
= xmlNewCDataBlock(get_doc(This
), NULL
, 0);
1974 case NODE_ENTITY_REFERENCE
:
1975 xmlnode
= xmlNewReference(get_doc(This
), xml_name
);
1977 case NODE_PROCESSING_INSTRUCTION
:
1978 #ifdef HAVE_XMLNEWDOCPI
1979 xmlnode
= xmlNewDocPI(get_doc(This
), xml_name
, NULL
);
1981 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1986 xmlnode
= xmlNewDocComment(get_doc(This
), NULL
);
1988 case NODE_DOCUMENT_FRAGMENT
:
1989 xmlnode
= xmlNewDocFragment(get_doc(This
));
1991 /* unsupported types */
1993 case NODE_DOCUMENT_TYPE
:
1996 heap_free(xml_name
);
1997 return E_INVALIDARG
;
1999 FIXME("unhandled node type %d\n", node_type
);
2004 *node
= create_node(xmlnode
);
2005 heap_free(xml_name
);
2010 TRACE("created node (%d, %p, %p)\n", node_type
, *node
, xmlnode
);
2011 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
2018 static HRESULT WINAPI
domdoc_nodeFromID(
2019 IXMLDOMDocument3
*iface
,
2021 IXMLDOMNode
** node
)
2023 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2024 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(idString
), node
);
2028 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
2033 xmldoc
= doparse(This
, ptr
, len
, XML_CHAR_ENCODING_NONE
);
2035 xmldoc
->_private
= create_priv();
2036 return attach_xmldoc(This
, xmldoc
);
2042 static HRESULT
domdoc_load_moniker(domdoc
*This
, IMoniker
*mon
)
2047 hr
= bind_url(mon
, domdoc_onDataAvailable
, This
, &bsc
);
2052 hr
= detach_bsc(This
->bsc
);
2061 static HRESULT WINAPI
domdoc_load(
2062 IXMLDOMDocument3
*iface
,
2064 VARIANT_BOOL
* isSuccessful
)
2066 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2067 LPWSTR filename
= NULL
;
2068 HRESULT hr
= S_FALSE
;
2071 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&source
));
2075 *isSuccessful
= VARIANT_FALSE
;
2077 assert( &This
->node
);
2079 switch( V_VT(&source
) )
2082 filename
= V_BSTR(&source
);
2084 case VT_BSTR
|VT_BYREF
:
2085 if (!V_BSTRREF(&source
)) return E_INVALIDARG
;
2086 filename
= *V_BSTRREF(&source
);
2088 case VT_ARRAY
|VT_UI1
:
2090 SAFEARRAY
*psa
= V_ARRAY(&source
);
2093 UINT dim
= SafeArrayGetDim(psa
);
2098 ERR("SAFEARRAY == NULL\n");
2099 hr
= This
->error
= E_INVALIDARG
;
2102 /* Only takes UTF-8 strings.
2103 * NOT NULL-terminated. */
2104 SafeArrayAccessData(psa
, (void**)&str
);
2105 SafeArrayGetUBound(psa
, 1, &len
);
2107 if ((xmldoc
= doparse(This
, str
, ++len
, XML_CHAR_ENCODING_UTF8
)))
2109 hr
= This
->error
= S_OK
;
2110 *isSuccessful
= VARIANT_TRUE
;
2111 TRACE("parsed document %p\n", xmldoc
);
2115 This
->error
= E_FAIL
;
2116 TRACE("failed to parse document\n");
2119 SafeArrayUnaccessData(psa
);
2123 xmldoc
->_private
= create_priv();
2124 return attach_xmldoc(This
, xmldoc
);
2128 FIXME("unhandled SAFEARRAY dim: %d\n", dim
);
2129 hr
= This
->error
= E_NOTIMPL
;
2135 ISequentialStream
*stream
= NULL
;
2136 IXMLDOMDocument3
*newdoc
= NULL
;
2138 if (!V_UNKNOWN(&source
)) return E_INVALIDARG
;
2140 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IXMLDOMDocument3
, (void**)&newdoc
);
2145 domdoc
*newDoc
= impl_from_IXMLDOMDocument3( newdoc
);
2147 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
2148 xmldoc
->_private
= create_priv();
2149 hr
= attach_xmldoc(This
, xmldoc
);
2152 *isSuccessful
= VARIANT_TRUE
;
2158 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IStream
, (void**)&stream
);
2160 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_ISequentialStream
, (void**)&stream
);
2164 hr
= domdoc_load_from_stream(This
, stream
);
2166 *isSuccessful
= VARIANT_TRUE
;
2167 ISequentialStream_Release(stream
);
2171 FIXME("unsupported IUnknown type (0x%08x) (%p)\n", hr
, V_UNKNOWN(&source
)->lpVtbl
);
2175 FIXME("VT type not supported (%d)\n", V_VT(&source
));
2182 hr
= create_moniker_from_url( filename
, &mon
);
2183 if ( SUCCEEDED(hr
) )
2185 hr
= domdoc_load_moniker( This
, mon
);
2186 IMoniker_Release(mon
);
2190 This
->error
= E_FAIL
;
2193 hr
= This
->error
= S_OK
;
2194 *isSuccessful
= VARIANT_TRUE
;
2198 if(!filename
|| FAILED(hr
)) {
2199 xmldoc
= xmlNewDoc(NULL
);
2200 xmldoc
->_private
= create_priv();
2201 hr
= attach_xmldoc(This
, xmldoc
);
2206 TRACE("ret (%d)\n", hr
);
2212 static HRESULT WINAPI
domdoc_get_readyState(
2213 IXMLDOMDocument3
*iface
,
2216 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2217 FIXME("stub! (%p)->(%p)\n", This
, value
);
2220 return E_INVALIDARG
;
2222 *value
= READYSTATE_COMPLETE
;
2227 static HRESULT WINAPI
domdoc_get_parseError(
2228 IXMLDOMDocument3
*iface
,
2229 IXMLDOMParseError
** errorObj
)
2231 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2232 static const WCHAR err
[] = {'e','r','r','o','r',0};
2233 BSTR error_string
= NULL
;
2235 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
2238 error_string
= SysAllocString(err
);
2240 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
2241 if(!*errorObj
) return E_OUTOFMEMORY
;
2246 static HRESULT WINAPI
domdoc_get_url(
2247 IXMLDOMDocument3
*iface
,
2250 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2251 FIXME("(%p)->(%p)\n", This
, urlString
);
2256 static HRESULT WINAPI
domdoc_get_async(
2257 IXMLDOMDocument3
*iface
,
2258 VARIANT_BOOL
* isAsync
)
2260 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2262 TRACE("(%p)->(%p: %d)\n", This
, isAsync
, This
->async
);
2263 *isAsync
= This
->async
;
2268 static HRESULT WINAPI
domdoc_put_async(
2269 IXMLDOMDocument3
*iface
,
2270 VARIANT_BOOL isAsync
)
2272 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2274 TRACE("(%p)->(%d)\n", This
, isAsync
);
2275 This
->async
= isAsync
;
2280 static HRESULT WINAPI
domdoc_abort(
2281 IXMLDOMDocument3
*iface
)
2283 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2284 FIXME("%p\n", This
);
2288 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2289 static HRESULT WINAPI
domdoc_loadXML(
2290 IXMLDOMDocument3
*iface
,
2292 VARIANT_BOOL
* isSuccessful
)
2294 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2295 xmlDocPtr xmldoc
= NULL
;
2296 HRESULT hr
= S_FALSE
, hr2
;
2298 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), isSuccessful
);
2300 assert ( &This
->node
);
2304 *isSuccessful
= VARIANT_FALSE
;
2310 /* skip leading spaces if needed */
2311 if (This
->properties
->version
== MSXML_DEFAULT
|| This
->properties
->version
== MSXML26
)
2312 while (*ptr
&& isspaceW(*ptr
)) ptr
++;
2314 xmldoc
= doparse(This
, (char*)ptr
, strlenW(ptr
)*sizeof(WCHAR
), XML_CHAR_ENCODING_UTF16LE
);
2317 This
->error
= E_FAIL
;
2318 TRACE("failed to parse document\n");
2322 hr
= This
->error
= S_OK
;
2323 *isSuccessful
= VARIANT_TRUE
;
2324 TRACE("parsed document %p\n", xmldoc
);
2330 xmldoc
= xmlNewDoc(NULL
);
2331 xmldoc
->_private
= create_priv();
2332 hr2
= attach_xmldoc(This
, xmldoc
);
2339 static int XMLCALL
domdoc_save_writecallback(void *ctx
, const char *buffer
, int len
)
2343 if(!WriteFile(ctx
, buffer
, len
, &written
, NULL
))
2345 WARN("write error\n");
2352 static int XMLCALL
domdoc_save_closecallback(void *ctx
)
2354 return CloseHandle(ctx
) ? 0 : -1;
2357 static int XMLCALL
domdoc_stream_save_writecallback(void *ctx
, const char *buffer
, int len
)
2362 hr
= IStream_Write((IStream
*)ctx
, buffer
, len
, &written
);
2363 TRACE("0x%08x %p %d %u\n", hr
, buffer
, len
, written
);
2366 WARN("stream write error: 0x%08x\n", hr
);
2373 static int XMLCALL
domdoc_stream_save_closecallback(void *ctx
)
2375 IStream_Release((IStream
*)ctx
);
2379 static HRESULT WINAPI
domdoc_save(
2380 IXMLDOMDocument3
*iface
,
2381 VARIANT destination
)
2383 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2384 xmlSaveCtxtPtr ctx
= NULL
;
2388 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&destination
));
2390 switch (V_VT(&destination
))
2394 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
2395 IXMLDOMDocument3
*document
;
2398 ret
= IUnknown_QueryInterface(pUnk
, &IID_IXMLDOMDocument3
, (void**)&document
);
2401 VARIANT_BOOL success
;
2404 ret
= IXMLDOMDocument3_get_xml(iface
, &xml
);
2407 ret
= IXMLDOMDocument3_loadXML(document
, xml
, &success
);
2411 IXMLDOMDocument3_Release(document
);
2415 ret
= IUnknown_QueryInterface(pUnk
, &IID_IStream
, (void**)&stream
);
2418 int options
= get_doc(This
)->standalone
== -1 ? XML_SAVE_NO_DECL
: 0;
2419 ctx
= xmlSaveToIO(domdoc_stream_save_writecallback
,
2420 domdoc_stream_save_closecallback
, stream
, NULL
, options
);
2424 IStream_Release(stream
);
2432 case VT_BSTR
| VT_BYREF
:
2434 int options
= get_doc(This
)->standalone
== -1 ? XML_SAVE_NO_DECL
: 0;
2436 /* save with file path */
2437 HANDLE handle
= CreateFileW( (V_VT(&destination
) & VT_BYREF
)? *V_BSTRREF(&destination
) : V_BSTR(&destination
),
2438 GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2439 if( handle
== INVALID_HANDLE_VALUE
)
2441 WARN("failed to create file\n");
2445 /* disable top XML declaration */
2446 ctx
= xmlSaveToIO(domdoc_save_writecallback
, domdoc_save_closecallback
,
2447 handle
, NULL
, options
);
2450 CloseHandle(handle
);
2457 FIXME("Unhandled VARIANT: %s\n", debugstr_variant(&destination
));
2461 xmldecl
= xmldoc_unlink_xmldecl(get_doc(This
));
2462 if (xmlSaveDoc(ctx
, get_doc(This
)) == -1) ret
= S_FALSE
;
2463 xmldoc_link_xmldecl(get_doc(This
), xmldecl
);
2465 /* will release resources through close callback */
2471 static HRESULT WINAPI
domdoc_get_validateOnParse(
2472 IXMLDOMDocument3
*iface
,
2473 VARIANT_BOOL
* isValidating
)
2475 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2476 TRACE("(%p)->(%p: %d)\n", This
, isValidating
, This
->validating
);
2477 *isValidating
= This
->validating
;
2482 static HRESULT WINAPI
domdoc_put_validateOnParse(
2483 IXMLDOMDocument3
*iface
,
2484 VARIANT_BOOL isValidating
)
2486 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2487 TRACE("(%p)->(%d)\n", This
, isValidating
);
2488 This
->validating
= isValidating
;
2493 static HRESULT WINAPI
domdoc_get_resolveExternals(
2494 IXMLDOMDocument3
*iface
,
2495 VARIANT_BOOL
* isResolving
)
2497 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2498 TRACE("(%p)->(%p: %d)\n", This
, isResolving
, This
->resolving
);
2499 *isResolving
= This
->resolving
;
2504 static HRESULT WINAPI
domdoc_put_resolveExternals(
2505 IXMLDOMDocument3
*iface
,
2506 VARIANT_BOOL isResolving
)
2508 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2509 TRACE("(%p)->(%d)\n", This
, isResolving
);
2510 This
->resolving
= isResolving
;
2515 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
2516 IXMLDOMDocument3
*iface
,
2517 VARIANT_BOOL
* isPreserving
)
2519 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2520 TRACE("(%p)->(%p: %d)\n", This
, isPreserving
, This
->properties
->preserving
);
2521 *isPreserving
= This
->properties
->preserving
;
2526 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
2527 IXMLDOMDocument3
*iface
,
2528 VARIANT_BOOL isPreserving
)
2530 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2531 TRACE("(%p)->(%d)\n", This
, isPreserving
);
2532 This
->properties
->preserving
= isPreserving
;
2537 static HRESULT WINAPI
domdoc_put_onreadystatechange(
2538 IXMLDOMDocument3
*iface
,
2541 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2543 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&event
));
2544 return set_doc_event(This
, EVENTID_READYSTATECHANGE
, &event
);
2548 static HRESULT WINAPI
domdoc_put_onDataAvailable(IXMLDOMDocument3
*iface
, VARIANT sink
)
2550 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2551 FIXME("(%p)->(%s): stub\n", This
, debugstr_variant(&sink
));
2555 static HRESULT WINAPI
domdoc_put_onTransformNode(IXMLDOMDocument3
*iface
, VARIANT sink
)
2557 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2558 FIXME("(%p)->(%s): stub\n", This
, debugstr_variant(&sink
));
2562 static HRESULT WINAPI
domdoc_get_namespaces(
2563 IXMLDOMDocument3
* iface
,
2564 IXMLDOMSchemaCollection
** collection
)
2566 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2569 FIXME("(%p)->(%p): semi-stub\n", This
, collection
);
2571 if (!collection
) return E_POINTER
;
2573 if (!This
->namespaces
)
2575 hr
= SchemaCache_create(This
->properties
->version
, NULL
, (void**)&This
->namespaces
);
2576 if (hr
!= S_OK
) return hr
;
2578 hr
= cache_from_doc_ns(This
->namespaces
, &This
->node
);
2580 release_namespaces(This
);
2583 if (This
->namespaces
)
2584 return IXMLDOMSchemaCollection2_QueryInterface(This
->namespaces
,
2585 &IID_IXMLDOMSchemaCollection
, (void**)collection
);
2590 static HRESULT WINAPI
domdoc_get_schemas(
2591 IXMLDOMDocument3
* iface
,
2594 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2595 IXMLDOMSchemaCollection2
* cur_schema
= This
->properties
->schemaCache
;
2596 HRESULT hr
= S_FALSE
;
2598 TRACE("(%p)->(%p)\n", This
, schema
);
2600 V_VT(schema
) = VT_NULL
;
2601 /* just to reset pointer part, cause that's what application is expected to use */
2602 V_DISPATCH(schema
) = NULL
;
2606 hr
= IXMLDOMSchemaCollection2_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(schema
));
2608 V_VT(schema
) = VT_DISPATCH
;
2613 static HRESULT WINAPI
domdoc_putref_schemas(
2614 IXMLDOMDocument3
* iface
,
2617 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2618 HRESULT hr
= E_FAIL
;
2619 IXMLDOMSchemaCollection2
* new_schema
= NULL
;
2621 FIXME("(%p)->(%s): semi-stub\n", This
, debugstr_variant(&schema
));
2622 switch(V_VT(&schema
))
2625 if (V_UNKNOWN(&schema
))
2627 hr
= IUnknown_QueryInterface(V_UNKNOWN(&schema
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2632 if (V_DISPATCH(&schema
))
2634 hr
= IDispatch_QueryInterface(V_DISPATCH(&schema
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2644 WARN("Can't get schema from vt %x\n", V_VT(&schema
));
2649 IXMLDOMSchemaCollection2
* old_schema
= InterlockedExchangePointer((void**)&This
->properties
->schemaCache
, new_schema
);
2650 if(old_schema
) IXMLDOMSchemaCollection2_Release(old_schema
);
2656 static inline BOOL
is_wellformed(xmlDocPtr doc
)
2658 #ifdef HAVE_XMLDOC_PROPERTIES
2659 return doc
->properties
& XML_DOC_WELLFORMED
;
2661 /* Not a full check, but catches the worst violations */
2665 for (child
= doc
->children
; child
!= NULL
; child
= child
->next
)
2667 switch (child
->type
)
2669 case XML_ELEMENT_NODE
:
2674 case XML_CDATA_SECTION_NODE
:
2686 static void LIBXML2_LOG_CALLBACK
validate_error(void* ctx
, char const* msg
, ...)
2690 LIBXML2_CALLBACK_ERR(domdoc_validateNode
, msg
, ap
);
2694 static void LIBXML2_LOG_CALLBACK
validate_warning(void* ctx
, char const* msg
, ...)
2698 LIBXML2_CALLBACK_WARN(domdoc_validateNode
, msg
, ap
);
2702 static HRESULT WINAPI
domdoc_validateNode(
2703 IXMLDOMDocument3
* iface
,
2705 IXMLDOMParseError
** err
)
2707 domdoc
* This
= impl_from_IXMLDOMDocument3(iface
);
2708 LONG state
, err_code
= 0;
2712 TRACE("(%p)->(%p, %p)\n", This
, node
, err
);
2713 IXMLDOMDocument3_get_readyState(iface
, &state
);
2714 if (state
!= READYSTATE_COMPLETE
)
2717 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2724 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2728 if (!get_node_obj(node
)->node
|| get_node_obj(node
)->node
->doc
!= get_doc(This
))
2731 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2735 if (!is_wellformed(get_doc(This
)))
2737 ERR("doc not well-formed\n");
2739 *err
= create_parseError(E_XML_NOTWF
, NULL
, NULL
, NULL
, 0, 0, 0);
2743 /* DTD validation */
2744 if (get_doc(This
)->intSubset
|| get_doc(This
)->extSubset
)
2746 xmlValidCtxtPtr vctx
= xmlNewValidCtxt();
2747 vctx
->error
= validate_error
;
2748 vctx
->warning
= validate_warning
;
2751 if (!((node
== (IXMLDOMNode
*)iface
)?
2752 xmlValidateDocument(vctx
, get_doc(This
)) :
2753 xmlValidateElement(vctx
, get_doc(This
), get_node_obj(node
)->node
)))
2755 /* TODO: get a real error code here */
2756 TRACE("DTD validation failed\n");
2757 err_code
= E_XML_INVALID
;
2760 xmlFreeValidCtxt(vctx
);
2763 /* Schema validation */
2764 if (hr
== S_OK
&& This
->properties
->schemaCache
!= NULL
)
2767 hr
= SchemaCache_validate_tree(This
->properties
->schemaCache
, get_node_obj(node
)->node
);
2771 /* TODO: get a real error code here */
2774 TRACE("schema validation succeeded\n");
2778 ERR("schema validation failed\n");
2779 err_code
= E_XML_INVALID
;
2784 /* not really OK, just didn't find a schema for the ns */
2791 ERR("no DTD or schema found\n");
2792 err_code
= E_XML_NODTD
;
2797 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2802 static HRESULT WINAPI
domdoc_validate(
2803 IXMLDOMDocument3
* iface
,
2804 IXMLDOMParseError
** err
)
2806 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2807 TRACE("(%p)->(%p)\n", This
, err
);
2808 return IXMLDOMDocument3_validateNode(iface
, (IXMLDOMNode
*)iface
, err
);
2811 static HRESULT WINAPI
domdoc_setProperty(
2812 IXMLDOMDocument3
* iface
,
2816 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2818 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(p
), debugstr_variant(&value
));
2820 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2826 V_VT(&varStr
) = VT_EMPTY
;
2827 if (V_VT(&value
) != VT_BSTR
)
2829 if (FAILED(hr
= VariantChangeType(&varStr
, &value
, 0, VT_BSTR
)))
2831 bstr
= V_BSTR(&varStr
);
2834 bstr
= V_BSTR(&value
);
2837 if (lstrcmpiW(bstr
, PropValueXPathW
) == 0)
2838 This
->properties
->XPath
= TRUE
;
2839 else if (lstrcmpiW(bstr
, PropValueXSLPatternW
) == 0)
2840 This
->properties
->XPath
= FALSE
;
2844 VariantClear(&varStr
);
2847 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2849 xmlChar
*nsStr
= (xmlChar
*)This
->properties
->selectNsStr
;
2850 struct list
*pNsList
;
2855 V_VT(&varStr
) = VT_EMPTY
;
2856 if (V_VT(&value
) != VT_BSTR
)
2858 if (FAILED(hr
= VariantChangeType(&varStr
, &value
, 0, VT_BSTR
)))
2860 bstr
= V_BSTR(&varStr
);
2863 bstr
= V_BSTR(&value
);
2867 pNsList
= &(This
->properties
->selectNsList
);
2868 clear_selectNsList(pNsList
);
2870 nsStr
= xmlchar_from_wchar(bstr
);
2872 TRACE("property value: \"%s\"\n", debugstr_w(bstr
));
2874 This
->properties
->selectNsStr
= nsStr
;
2875 This
->properties
->selectNsStr_len
= xmlStrlen(nsStr
);
2878 xmlChar
*pTokBegin
, *pTokEnd
, *pTokInner
;
2879 select_ns_entry
* ns_entry
= NULL
;
2880 xmlXPathContextPtr ctx
;
2882 ctx
= xmlXPathNewContext(This
->node
.node
->doc
);
2885 /* skip leading spaces */
2886 while (*pTokBegin
== ' ' || *pTokBegin
== '\n' ||
2887 *pTokBegin
== '\t' || *pTokBegin
== '\r')
2890 for (; *pTokBegin
; pTokBegin
= pTokEnd
)
2893 memset(ns_entry
, 0, sizeof(select_ns_entry
));
2895 ns_entry
= heap_alloc_zero(sizeof(select_ns_entry
));
2897 while (*pTokBegin
== ' ')
2899 pTokEnd
= pTokBegin
;
2900 while (*pTokEnd
!= ' ' && *pTokEnd
!= 0)
2903 /* so it failed to advance which means we've got some trailing spaces */
2904 if (pTokEnd
== pTokBegin
) break;
2906 if (xmlStrncmp(pTokBegin
, (xmlChar
const*)"xmlns", 5) != 0)
2909 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2910 debugstr_w(bstr
), debugstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2915 if (*pTokBegin
== '=')
2917 /*valid for XSLPattern?*/
2918 FIXME("Setting default xmlns not supported - skipping.\n");
2921 else if (*pTokBegin
== ':')
2923 ns_entry
->prefix
= ++pTokBegin
;
2924 for (pTokInner
= pTokBegin
; pTokInner
!= pTokEnd
&& *pTokInner
!= '='; ++pTokInner
)
2927 if (pTokInner
== pTokEnd
)
2930 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2931 debugstr_w(bstr
), debugstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2935 ns_entry
->prefix_end
= *pTokInner
;
2939 if (pTokEnd
-pTokInner
> 1 &&
2940 ((*pTokInner
== '\'' && *(pTokEnd
-1) == '\'') ||
2941 (*pTokInner
== '"' && *(pTokEnd
-1) == '"')))
2943 ns_entry
->href
= ++pTokInner
;
2944 ns_entry
->href_end
= *(pTokEnd
-1);
2946 list_add_tail(pNsList
, &ns_entry
->entry
);
2947 /*let libxml figure out if they're valid from here ;)*/
2948 if (xmlXPathRegisterNs(ctx
, ns_entry
->prefix
, ns_entry
->href
) != 0)
2957 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2958 debugstr_w(bstr
), debugstr_an((const char*)pTokInner
, pTokEnd
-pTokInner
));
2959 list_add_tail(pNsList
, &ns_entry
->entry
);
2972 heap_free(ns_entry
);
2973 xmlXPathFreeContext(ctx
);
2976 VariantClear(&varStr
);
2979 else if (lstrcmpiW(p
, PropertyProhibitDTDW
) == 0 ||
2980 lstrcmpiW(p
, PropertyNewParserW
) == 0 ||
2981 lstrcmpiW(p
, PropertyResolveExternalsW
) == 0)
2984 FIXME("Ignoring property %s, value %d\n", debugstr_w(p
), V_BOOL(&value
));
2988 FIXME("Unknown property %s\n", debugstr_w(p
));
2992 static HRESULT WINAPI
domdoc_getProperty(
2993 IXMLDOMDocument3
* iface
,
2997 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2999 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
3002 return E_INVALIDARG
;
3004 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
3006 V_VT(var
) = VT_BSTR
;
3007 V_BSTR(var
) = This
->properties
->XPath
?
3008 SysAllocString(PropValueXPathW
) :
3009 SysAllocString(PropValueXSLPatternW
);
3010 return V_BSTR(var
) ? S_OK
: E_OUTOFMEMORY
;
3012 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
3015 BSTR rebuiltStr
, cur
;
3016 const xmlChar
*nsStr
;
3017 struct list
*pNsList
;
3018 select_ns_entry
* pNsEntry
;
3020 V_VT(var
) = VT_BSTR
;
3021 nsStr
= This
->properties
->selectNsStr
;
3022 pNsList
= &This
->properties
->selectNsList
;
3023 lenA
= This
->properties
->selectNsStr_len
;
3024 lenW
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, NULL
, 0);
3025 rebuiltStr
= heap_alloc(lenW
*sizeof(WCHAR
));
3026 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, rebuiltStr
, lenW
);
3028 /* this is fine because all of the chars that end tokens are ASCII*/
3029 LIST_FOR_EACH_ENTRY(pNsEntry
, pNsList
, select_ns_entry
, entry
)
3031 while (*cur
!= 0) ++cur
;
3032 if (pNsEntry
->prefix_end
)
3034 *cur
= pNsEntry
->prefix_end
;
3035 while (*cur
!= 0) ++cur
;
3038 if (pNsEntry
->href_end
)
3040 *cur
= pNsEntry
->href_end
;
3043 V_BSTR(var
) = SysAllocString(rebuiltStr
);
3044 heap_free(rebuiltStr
);
3048 FIXME("Unknown property %s\n", debugstr_w(p
));
3052 static HRESULT WINAPI
domdoc_importNode(
3053 IXMLDOMDocument3
* iface
,
3056 IXMLDOMNode
** clone
)
3058 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
3059 FIXME("(%p)->(%p %d %p): stub\n", This
, node
, deep
, clone
);
3063 static const struct IXMLDOMDocument3Vtbl XMLDOMDocument3Vtbl
=
3065 domdoc_QueryInterface
,
3068 domdoc_GetTypeInfoCount
,
3070 domdoc_GetIDsOfNames
,
3072 domdoc_get_nodeName
,
3073 domdoc_get_nodeValue
,
3074 domdoc_put_nodeValue
,
3075 domdoc_get_nodeType
,
3076 domdoc_get_parentNode
,
3077 domdoc_get_childNodes
,
3078 domdoc_get_firstChild
,
3079 domdoc_get_lastChild
,
3080 domdoc_get_previousSibling
,
3081 domdoc_get_nextSibling
,
3082 domdoc_get_attributes
,
3083 domdoc_insertBefore
,
3084 domdoc_replaceChild
,
3087 domdoc_hasChildNodes
,
3088 domdoc_get_ownerDocument
,
3090 domdoc_get_nodeTypeString
,
3093 domdoc_get_specified
,
3094 domdoc_get_definition
,
3095 domdoc_get_nodeTypedValue
,
3096 domdoc_put_nodeTypedValue
,
3097 domdoc_get_dataType
,
3098 domdoc_put_dataType
,
3100 domdoc_transformNode
,
3102 domdoc_selectSingleNode
,
3104 domdoc_get_namespaceURI
,
3106 domdoc_get_baseName
,
3107 domdoc_transformNodeToObject
,
3109 domdoc_get_implementation
,
3110 domdoc_get_documentElement
,
3111 domdoc_put_documentElement
,
3112 domdoc_createElement
,
3113 domdoc_createDocumentFragment
,
3114 domdoc_createTextNode
,
3115 domdoc_createComment
,
3116 domdoc_createCDATASection
,
3117 domdoc_createProcessingInstruction
,
3118 domdoc_createAttribute
,
3119 domdoc_createEntityReference
,
3120 domdoc_getElementsByTagName
,
3124 domdoc_get_readyState
,
3125 domdoc_get_parseError
,
3132 domdoc_get_validateOnParse
,
3133 domdoc_put_validateOnParse
,
3134 domdoc_get_resolveExternals
,
3135 domdoc_put_resolveExternals
,
3136 domdoc_get_preserveWhiteSpace
,
3137 domdoc_put_preserveWhiteSpace
,
3138 domdoc_put_onreadystatechange
,
3139 domdoc_put_onDataAvailable
,
3140 domdoc_put_onTransformNode
,
3141 domdoc_get_namespaces
,
3143 domdoc_putref_schemas
,
3147 domdoc_validateNode
,
3151 /* IConnectionPointContainer */
3152 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
3153 REFIID riid
, void **ppv
)
3155 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3156 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3159 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
3161 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3162 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3165 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
3167 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3168 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3171 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
3172 IEnumConnectionPoints
**ppEnum
)
3174 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3175 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3179 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
3180 REFIID riid
, IConnectionPoint
**cp
)
3182 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3183 ConnectionPoint
*iter
;
3185 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), cp
);
3189 for(iter
= This
->cp_list
; iter
; iter
= iter
->next
)
3191 if (IsEqualGUID(iter
->iid
, riid
))
3192 *cp
= &iter
->IConnectionPoint_iface
;
3197 IConnectionPoint_AddRef(*cp
);
3201 FIXME("unsupported riid %s\n", debugstr_guid(riid
));
3202 return CONNECT_E_NOCONNECTION
;
3206 static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
3208 ConnectionPointContainer_QueryInterface
,
3209 ConnectionPointContainer_AddRef
,
3210 ConnectionPointContainer_Release
,
3211 ConnectionPointContainer_EnumConnectionPoints
,
3212 ConnectionPointContainer_FindConnectionPoint
3215 /* IConnectionPoint */
3216 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
3217 REFIID riid
, void **ppv
)
3219 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3221 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
3225 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
3226 IsEqualGUID(&IID_IConnectionPoint
, riid
))
3233 IConnectionPoint_AddRef(iface
);
3237 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
3238 return E_NOINTERFACE
;
3241 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
3243 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3244 return IConnectionPointContainer_AddRef(This
->container
);
3247 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
3249 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3250 return IConnectionPointContainer_Release(This
->container
);
3253 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*iid
)
3255 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3257 TRACE("(%p)->(%p)\n", This
, iid
);
3259 if (!iid
) return E_POINTER
;
3265 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
3266 IConnectionPointContainer
**container
)
3268 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3270 TRACE("(%p)->(%p)\n", This
, container
);
3272 if (!container
) return E_POINTER
;
3274 *container
= This
->container
;
3275 IConnectionPointContainer_AddRef(*container
);
3279 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*unk_sink
,
3282 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3287 TRACE("(%p)->(%p %p)\n", This
, unk_sink
, cookie
);
3289 hr
= IUnknown_QueryInterface(unk_sink
, This
->iid
, (void**)&sink
);
3290 if(FAILED(hr
) && !IsEqualGUID(&IID_IPropertyNotifySink
, This
->iid
))
3291 hr
= IUnknown_QueryInterface(unk_sink
, &IID_IDispatch
, (void**)&sink
);
3293 return CONNECT_E_CANNOTCONNECT
;
3297 for (i
= 0; i
< This
->sinks_size
; i
++)
3298 if (!This
->sinks
[i
].unk
)
3301 if (i
== This
->sinks_size
)
3302 This
->sinks
= heap_realloc(This
->sinks
,(++This
->sinks_size
)*sizeof(*This
->sinks
));
3306 This
->sinks
= heap_alloc(sizeof(*This
->sinks
));
3307 This
->sinks_size
= 1;
3311 This
->sinks
[i
].unk
= sink
;
3318 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD cookie
)
3320 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3322 TRACE("(%p)->(%d)\n", This
, cookie
);
3324 if (cookie
== 0 || cookie
> This
->sinks_size
|| !This
->sinks
[cookie
-1].unk
)
3325 return CONNECT_E_NOCONNECTION
;
3327 IUnknown_Release(This
->sinks
[cookie
-1].unk
);
3328 This
->sinks
[cookie
-1].unk
= NULL
;
3333 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
3334 IEnumConnections
**ppEnum
)
3336 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3337 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3341 static const IConnectionPointVtbl ConnectionPointVtbl
=
3343 ConnectionPoint_QueryInterface
,
3344 ConnectionPoint_AddRef
,
3345 ConnectionPoint_Release
,
3346 ConnectionPoint_GetConnectionInterface
,
3347 ConnectionPoint_GetConnectionPointContainer
,
3348 ConnectionPoint_Advise
,
3349 ConnectionPoint_Unadvise
,
3350 ConnectionPoint_EnumConnections
3353 static void ConnectionPoint_Init(ConnectionPoint
*cp
, struct domdoc
*doc
, REFIID riid
)
3355 cp
->IConnectionPoint_iface
.lpVtbl
= &ConnectionPointVtbl
;
3361 cp
->next
= doc
->cp_list
;
3364 cp
->container
= &doc
->IConnectionPointContainer_iface
;
3367 /* domdoc implementation of IObjectWithSite */
3368 static HRESULT WINAPI
3369 domdoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
3371 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3372 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObject
);
3375 static ULONG WINAPI
domdoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
3377 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3378 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3381 static ULONG WINAPI
domdoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
3383 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3384 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3387 static HRESULT WINAPI
domdoc_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
3389 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3391 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
3396 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
3399 static HRESULT WINAPI
domdoc_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
3401 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3403 TRACE("(%p)->(%p)\n", iface
, punk
);
3409 IUnknown_Release( This
->site
);
3416 IUnknown_AddRef( punk
);
3419 IUnknown_Release( This
->site
);
3426 static const IObjectWithSiteVtbl domdocObjectSite
=
3428 domdoc_ObjectWithSite_QueryInterface
,
3429 domdoc_ObjectWithSite_AddRef
,
3430 domdoc_ObjectWithSite_Release
,
3431 domdoc_ObjectWithSite_SetSite
,
3432 domdoc_ObjectWithSite_GetSite
3435 static HRESULT WINAPI
domdoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
3437 domdoc
*This
= impl_from_IObjectSafety(iface
);
3438 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3441 static ULONG WINAPI
domdoc_Safety_AddRef(IObjectSafety
*iface
)
3443 domdoc
*This
= impl_from_IObjectSafety(iface
);
3444 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3447 static ULONG WINAPI
domdoc_Safety_Release(IObjectSafety
*iface
)
3449 domdoc
*This
= impl_from_IObjectSafety(iface
);
3450 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3453 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
3455 static HRESULT WINAPI
domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3456 DWORD
*supported
, DWORD
*enabled
)
3458 domdoc
*This
= impl_from_IObjectSafety(iface
);
3460 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
3462 if(!supported
|| !enabled
) return E_POINTER
;
3464 *supported
= SAFETY_SUPPORTED_OPTIONS
;
3465 *enabled
= This
->safeopt
;
3470 static HRESULT WINAPI
domdoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3471 DWORD mask
, DWORD enabled
)
3473 domdoc
*This
= impl_from_IObjectSafety(iface
);
3474 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
3476 if ((mask
& ~SAFETY_SUPPORTED_OPTIONS
) != 0)
3479 This
->safeopt
= (This
->safeopt
& ~mask
) | (mask
& enabled
);
3484 #undef SAFETY_SUPPORTED_OPTIONS
3486 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
3487 domdoc_Safety_QueryInterface
,
3488 domdoc_Safety_AddRef
,
3489 domdoc_Safety_Release
,
3490 domdoc_Safety_GetInterfaceSafetyOptions
,
3491 domdoc_Safety_SetInterfaceSafetyOptions
3494 static const tid_t domdoc_iface_tids
[] = {
3495 IXMLDOMDocument3_tid
,
3499 static dispex_static_data_t domdoc_dispex
= {
3501 IXMLDOMDocument3_tid
,
3506 HRESULT
get_domdoc_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument3
**document
)
3510 doc
= heap_alloc( sizeof (*doc
) );
3512 return E_OUTOFMEMORY
;
3514 doc
->IXMLDOMDocument3_iface
.lpVtbl
= &XMLDOMDocument3Vtbl
;
3515 doc
->IPersistStreamInit_iface
.lpVtbl
= &xmldoc_IPersistStreamInit_VTable
;
3516 doc
->IObjectWithSite_iface
.lpVtbl
= &domdocObjectSite
;
3517 doc
->IObjectSafety_iface
.lpVtbl
= &domdocObjectSafetyVtbl
;
3518 doc
->IConnectionPointContainer_iface
.lpVtbl
= &ConnectionPointContainerVtbl
;
3520 doc
->async
= VARIANT_TRUE
;
3521 doc
->validating
= 0;
3523 doc
->properties
= properties_from_xmlDocPtr(xmldoc
);
3528 doc
->cp_list
= NULL
;
3529 doc
->namespaces
= NULL
;
3530 memset(doc
->events
, 0, sizeof(doc
->events
));
3532 /* events connection points */
3533 ConnectionPoint_Init(&doc
->cp_dispatch
, doc
, &IID_IDispatch
);
3534 ConnectionPoint_Init(&doc
->cp_propnotif
, doc
, &IID_IPropertyNotifySink
);
3535 ConnectionPoint_Init(&doc
->cp_domdocevents
, doc
, &DIID_XMLDOMDocumentEvents
);
3537 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IXMLDOMNode
*)&doc
->IXMLDOMDocument3_iface
,
3540 *document
= &doc
->IXMLDOMDocument3_iface
;
3542 TRACE("returning iface %p\n", *document
);
3546 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3551 TRACE("(%d, %p, %p)\n", version
, pUnkOuter
, ppObj
);
3553 xmldoc
= xmlNewDoc(NULL
);
3555 return E_OUTOFMEMORY
;
3557 xmldoc_init(xmldoc
, version
);
3559 hr
= get_domdoc_from_xmldoc(xmldoc
, (IXMLDOMDocument3
**)ppObj
);
3562 free_properties(properties_from_xmlDocPtr(xmldoc
));
3563 heap_free(xmldoc
->_private
);
3571 IUnknown
* create_domdoc( xmlNodePtr document
)
3576 TRACE("(%p)\n", document
);
3578 hr
= get_domdoc_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument3
**)&pObj
);
3587 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3589 MESSAGE("This program tried to use a DOMDocument object, but\n"
3590 "libxml2 support was not present at compile time.\n");