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
;
144 /* connection list */
145 ConnectionPoint
*cp_list
;
146 ConnectionPoint cp_domdocevents
;
147 ConnectionPoint cp_propnotif
;
148 ConnectionPoint cp_dispatch
;
151 IDispatch
*events
[EVENTID_LAST
];
153 IXMLDOMSchemaCollection2
*namespaces
;
156 static HRESULT
set_doc_event(domdoc
*doc
, eventid_t eid
, const VARIANT
*v
)
164 IUnknown_QueryInterface(V_UNKNOWN(v
), &IID_IDispatch
, (void**)&disp
);
169 disp
= V_DISPATCH(v
);
170 if (disp
) IDispatch_AddRef(disp
);
173 return DISP_E_TYPEMISMATCH
;
176 if (doc
->events
[eid
]) IDispatch_Release(doc
->events
[eid
]);
177 doc
->events
[eid
] = disp
;
182 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
184 return CONTAINING_RECORD(iface
, ConnectionPoint
, IConnectionPoint_iface
);
188 In native windows, the whole lifetime management of XMLDOMNodes is
189 managed automatically using reference counts. Wine emulates that by
190 maintaining a reference count to the document that is increased for
191 each IXMLDOMNode pointer passed out for this document. If all these
192 pointers are gone, the document is unreachable and gets freed, that
193 is, all nodes in the tree of the document get freed.
195 You are able to create nodes that are associated to a document (in
196 fact, in msxml's XMLDOM model, all nodes are associated to a document),
197 but not in the tree of that document, for example using the createFoo
198 functions from IXMLDOMDocument. These nodes do not get cleaned up
199 by libxml, so we have to do it ourselves.
201 To catch these nodes, a list of "orphan nodes" is introduced.
202 It contains pointers to all roots of node trees that are
203 associated with the document without being part of the document
204 tree. All nodes with parent==NULL (except for the document root nodes)
205 should be in the orphan node list of their document. All orphan nodes
206 get freed together with the document itself.
209 typedef struct _xmldoc_priv
{
212 domdoc_properties
* properties
;
215 typedef struct _orphan_entry
{
220 typedef struct _select_ns_entry
{
222 xmlChar
const* prefix
;
228 static inline xmldoc_priv
* priv_from_xmlDocPtr(const xmlDocPtr doc
)
230 return doc
->_private
;
233 static inline domdoc_properties
* properties_from_xmlDocPtr(xmlDocPtr doc
)
235 return priv_from_xmlDocPtr(doc
)->properties
;
238 BOOL
is_xpathmode(const xmlDocPtr doc
)
240 return properties_from_xmlDocPtr(doc
)->XPath
;
243 void set_xpathmode(xmlDocPtr doc
, BOOL xpath
)
245 properties_from_xmlDocPtr(doc
)->XPath
= xpath
;
248 int registerNamespaces(xmlXPathContextPtr ctxt
)
251 const select_ns_entry
* ns
= NULL
;
252 const struct list
* pNsList
= &properties_from_xmlDocPtr(ctxt
->doc
)->selectNsList
;
254 TRACE("(%p)\n", ctxt
);
256 LIST_FOR_EACH_ENTRY( ns
, pNsList
, select_ns_entry
, entry
)
258 xmlXPathRegisterNs(ctxt
, ns
->prefix
, ns
->href
);
265 static inline void clear_selectNsList(struct list
* pNsList
)
267 select_ns_entry
*ns
, *ns2
;
268 LIST_FOR_EACH_ENTRY_SAFE( ns
, ns2
, pNsList
, select_ns_entry
, entry
)
275 static xmldoc_priv
* create_priv(void)
278 priv
= heap_alloc( sizeof (*priv
) );
283 list_init( &priv
->orphans
);
284 priv
->properties
= NULL
;
290 static domdoc_properties
*create_properties(MSXML_VERSION version
)
292 domdoc_properties
*properties
= heap_alloc(sizeof(domdoc_properties
));
294 list_init(&properties
->selectNsList
);
295 properties
->preserving
= VARIANT_FALSE
;
296 properties
->schemaCache
= NULL
;
297 properties
->selectNsStr
= heap_alloc_zero(sizeof(xmlChar
));
298 properties
->selectNsStr_len
= 0;
300 /* properties that are dependent on object versions */
301 properties
->version
= version
;
302 properties
->XPath
= (version
== MSXML4
|| version
== MSXML6
);
307 static domdoc_properties
* copy_properties(domdoc_properties
const* properties
)
309 domdoc_properties
* pcopy
= heap_alloc(sizeof(domdoc_properties
));
310 select_ns_entry
const* ns
= NULL
;
311 select_ns_entry
* new_ns
= NULL
;
312 int len
= (properties
->selectNsStr_len
+1)*sizeof(xmlChar
);
317 pcopy
->version
= properties
->version
;
318 pcopy
->preserving
= properties
->preserving
;
319 pcopy
->schemaCache
= properties
->schemaCache
;
320 if (pcopy
->schemaCache
)
321 IXMLDOMSchemaCollection2_AddRef(pcopy
->schemaCache
);
322 pcopy
->XPath
= properties
->XPath
;
323 pcopy
->selectNsStr_len
= properties
->selectNsStr_len
;
324 list_init( &pcopy
->selectNsList
);
325 pcopy
->selectNsStr
= heap_alloc(len
);
326 memcpy((xmlChar
*)pcopy
->selectNsStr
, properties
->selectNsStr
, len
);
327 offset
= pcopy
->selectNsStr
- properties
->selectNsStr
;
329 LIST_FOR_EACH_ENTRY( ns
, (&properties
->selectNsList
), select_ns_entry
, entry
)
331 new_ns
= heap_alloc(sizeof(select_ns_entry
));
332 memcpy(new_ns
, ns
, sizeof(select_ns_entry
));
333 new_ns
->href
+= offset
;
334 new_ns
->prefix
+= offset
;
335 list_add_tail(&pcopy
->selectNsList
, &new_ns
->entry
);
343 static void free_properties(domdoc_properties
* properties
)
347 if (properties
->schemaCache
)
348 IXMLDOMSchemaCollection2_Release(properties
->schemaCache
);
349 clear_selectNsList(&properties
->selectNsList
);
350 heap_free((xmlChar
*)properties
->selectNsStr
);
351 heap_free(properties
);
355 static void release_namespaces(domdoc
*This
)
357 if (This
->namespaces
)
359 IXMLDOMSchemaCollection2_Release(This
->namespaces
);
360 This
->namespaces
= NULL
;
364 /* links a "<?xml" node as a first child */
365 void xmldoc_link_xmldecl(xmlDocPtr doc
, xmlNodePtr node
)
368 if (doc
->standalone
!= -1) xmlAddPrevSibling( doc
->children
, node
);
371 /* unlinks a first "<?xml" child if it was created */
372 xmlNodePtr
xmldoc_unlink_xmldecl(xmlDocPtr doc
)
374 static const xmlChar xmlA
[] = "xml";
375 xmlNodePtr node
, first_child
;
379 /* xml declaration node could be created automatically after parsing or added
381 first_child
= doc
->children
;
382 if (first_child
&& first_child
->type
== XML_PI_NODE
&& xmlStrEqual(first_child
->name
, xmlA
))
385 xmlUnlinkNode( node
);
393 BOOL
is_preserving_whitespace(xmlNodePtr node
)
395 domdoc_properties
* properties
= NULL
;
396 /* during parsing the xmlDoc._private stuff is not there */
397 if (priv_from_xmlDocPtr(node
->doc
))
398 properties
= properties_from_xmlDocPtr(node
->doc
);
399 return ((properties
&& properties
->preserving
== VARIANT_TRUE
) ||
400 xmlNodeGetSpacePreserve(node
) == 1);
403 static inline BOOL
strn_isspace(xmlChar
const* str
, int len
)
405 for (; str
&& len
> 0 && *str
; ++str
, --len
)
412 static void sax_characters(void *ctx
, const xmlChar
*ch
, int len
)
414 xmlParserCtxtPtr ctxt
;
417 ctxt
= (xmlParserCtxtPtr
) ctx
;
418 This
= (const domdoc
*) ctxt
->_private
;
422 /* during domdoc_loadXML() the xmlDocPtr->_private data is not available */
423 if (!This
->properties
->preserving
&&
424 !is_preserving_whitespace(ctxt
->node
) &&
425 strn_isspace(ch
, len
))
429 xmlSAX2Characters(ctxt
, ch
, len
);
432 static void LIBXML2_LOG_CALLBACK
sax_error(void* ctx
, char const* msg
, ...)
436 LIBXML2_CALLBACK_ERR(doparse
, msg
, ap
);
440 static void LIBXML2_LOG_CALLBACK
sax_warning(void* ctx
, char const* msg
, ...)
444 LIBXML2_CALLBACK_WARN(doparse
, msg
, ap
);
448 static void sax_serror(void* ctx
, xmlErrorPtr err
)
450 LIBXML2_CALLBACK_SERROR(doparse
, err
);
453 static xmlDocPtr
doparse(domdoc
* This
, char const* ptr
, int len
, xmlCharEncoding encoding
)
455 xmlDocPtr doc
= NULL
;
456 xmlParserCtxtPtr pctx
;
457 static xmlSAXHandler sax_handler
= {
458 xmlSAX2InternalSubset
, /* internalSubset */
459 xmlSAX2IsStandalone
, /* isStandalone */
460 xmlSAX2HasInternalSubset
, /* hasInternalSubset */
461 xmlSAX2HasExternalSubset
, /* hasExternalSubset */
462 xmlSAX2ResolveEntity
, /* resolveEntity */
463 xmlSAX2GetEntity
, /* getEntity */
464 xmlSAX2EntityDecl
, /* entityDecl */
465 xmlSAX2NotationDecl
, /* notationDecl */
466 xmlSAX2AttributeDecl
, /* attributeDecl */
467 xmlSAX2ElementDecl
, /* elementDecl */
468 xmlSAX2UnparsedEntityDecl
, /* unparsedEntityDecl */
469 xmlSAX2SetDocumentLocator
, /* setDocumentLocator */
470 xmlSAX2StartDocument
, /* startDocument */
471 xmlSAX2EndDocument
, /* endDocument */
472 xmlSAX2StartElement
, /* startElement */
473 xmlSAX2EndElement
, /* endElement */
474 xmlSAX2Reference
, /* reference */
475 sax_characters
, /* characters */
476 sax_characters
, /* ignorableWhitespace */
477 xmlSAX2ProcessingInstruction
, /* processingInstruction */
478 xmlSAX2Comment
, /* comment */
479 sax_warning
, /* warning */
480 sax_error
, /* error */
481 sax_error
, /* fatalError */
482 xmlSAX2GetParameterEntity
, /* getParameterEntity */
483 xmlSAX2CDataBlock
, /* cdataBlock */
484 xmlSAX2ExternalSubset
, /* externalSubset */
487 xmlSAX2StartElementNs
, /* startElementNs */
488 xmlSAX2EndElementNs
, /* endElementNs */
489 sax_serror
/* serror */
492 pctx
= xmlCreateMemoryParserCtxt(ptr
, len
);
495 ERR("Failed to create parser context\n");
499 if (pctx
->sax
) xmlFree(pctx
->sax
);
500 pctx
->sax
= &sax_handler
;
501 pctx
->_private
= This
;
504 if (encoding
!= XML_CHAR_ENCODING_NONE
)
505 xmlSwitchEncoding(pctx
, encoding
);
507 xmlParseDocument(pctx
);
509 if (pctx
->wellFormed
)
515 xmlFreeDoc(pctx
->myDoc
);
519 xmlFreeParserCtxt(pctx
);
521 /* TODO: put this in one of the SAX callbacks */
522 /* create first child as a <?xml...?> */
523 if (doc
&& doc
->standalone
!= -1)
527 xmlChar
*xmlbuff
= (xmlChar
*)buff
;
529 node
= xmlNewDocPI( doc
, (xmlChar
*)"xml", NULL
);
531 /* version attribute can't be omitted */
532 sprintf(buff
, "version=\"%s\"", doc
->version
? (char*)doc
->version
: "1.0");
533 xmlNodeAddContent( node
, xmlbuff
);
537 sprintf(buff
, " encoding=\"%s\"", doc
->encoding
);
538 xmlNodeAddContent( node
, xmlbuff
);
541 if (doc
->standalone
!= -2)
543 sprintf(buff
, " standalone=\"%s\"", doc
->standalone
== 0 ? "no" : "yes");
544 xmlNodeAddContent( node
, xmlbuff
);
547 xmldoc_link_xmldecl( doc
, node
);
553 void xmldoc_init(xmlDocPtr doc
, MSXML_VERSION version
)
555 doc
->_private
= create_priv();
556 priv_from_xmlDocPtr(doc
)->properties
= create_properties(version
);
559 LONG
xmldoc_add_ref(xmlDocPtr doc
)
561 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
562 TRACE("(%p)->(%d)\n", doc
, ref
);
566 LONG
xmldoc_release(xmlDocPtr doc
)
568 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
569 LONG ref
= InterlockedDecrement(&priv
->refs
);
570 TRACE("(%p)->(%d)\n", doc
, ref
);
573 orphan_entry
*orphan
, *orphan2
;
574 TRACE("freeing docptr %p\n", doc
);
576 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
578 xmlFreeNode( orphan
->node
);
581 free_properties(priv
->properties
);
582 heap_free(doc
->_private
);
590 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
592 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
595 entry
= heap_alloc( sizeof (*entry
) );
597 return E_OUTOFMEMORY
;
600 list_add_head( &priv
->orphans
, &entry
->entry
);
604 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
606 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
607 orphan_entry
*entry
, *entry2
;
609 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
611 if( entry
->node
== node
)
613 list_remove( &entry
->entry
);
622 static inline xmlDocPtr
get_doc( domdoc
*This
)
624 return (xmlDocPtr
)This
->node
.node
;
627 static HRESULT
attach_xmldoc(domdoc
*This
, xmlDocPtr xml
)
629 release_namespaces(This
);
633 priv_from_xmlDocPtr(get_doc(This
))->properties
= NULL
;
634 if (xmldoc_release(get_doc(This
)) != 0)
635 priv_from_xmlDocPtr(get_doc(This
))->properties
=
636 copy_properties(This
->properties
);
639 This
->node
.node
= (xmlNodePtr
) xml
;
643 xmldoc_add_ref(get_doc(This
));
644 priv_from_xmlDocPtr(get_doc(This
))->properties
= This
->properties
;
650 static inline domdoc
*impl_from_IXMLDOMDocument3( IXMLDOMDocument3
*iface
)
652 return CONTAINING_RECORD(iface
, domdoc
, IXMLDOMDocument3_iface
);
655 static inline domdoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
657 return CONTAINING_RECORD(iface
, domdoc
, IPersistStreamInit_iface
);
660 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
662 return CONTAINING_RECORD(iface
, domdoc
, IObjectWithSite_iface
);
665 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
667 return CONTAINING_RECORD(iface
, domdoc
, IObjectSafety_iface
);
670 static inline domdoc
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
672 return CONTAINING_RECORD(iface
, domdoc
, IConnectionPointContainer_iface
);
675 /************************************************************************
676 * domdoc implementation of IPersistStream.
678 static HRESULT WINAPI
PersistStreamInit_QueryInterface(
679 IPersistStreamInit
*iface
, REFIID riid
, void **ppvObj
)
681 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
682 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObj
);
685 static ULONG WINAPI
PersistStreamInit_AddRef(
686 IPersistStreamInit
*iface
)
688 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
689 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
692 static ULONG WINAPI
PersistStreamInit_Release(
693 IPersistStreamInit
*iface
)
695 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
696 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
699 static HRESULT WINAPI
PersistStreamInit_GetClassID(
700 IPersistStreamInit
*iface
, CLSID
*classid
)
702 domdoc
* This
= impl_from_IPersistStreamInit(iface
);
703 TRACE("(%p)->(%p)\n", This
, classid
);
708 *classid
= *DOMDocument_version(This
->properties
->version
);
713 static HRESULT WINAPI
PersistStreamInit_IsDirty(
714 IPersistStreamInit
*iface
)
716 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
717 FIXME("(%p): stub!\n", This
);
721 static HRESULT WINAPI
PersistStreamInit_Load(
722 IPersistStreamInit
*iface
, LPSTREAM pStm
)
724 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
727 DWORD read
, written
, len
;
730 xmlDocPtr xmldoc
= NULL
;
732 TRACE("(%p)->(%p)\n", This
, pStm
);
737 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
743 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
744 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
745 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
749 ERR("Failed to copy stream\n");
753 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
757 len
= GlobalSize(hglobal
);
758 ptr
= GlobalLock(hglobal
);
760 xmldoc
= doparse(This
, ptr
, len
, XML_CHAR_ENCODING_NONE
);
761 GlobalUnlock(hglobal
);
765 ERR("Failed to parse xml\n");
769 xmldoc
->_private
= create_priv();
771 return attach_xmldoc(This
, xmldoc
);
774 static HRESULT WINAPI
PersistStreamInit_Save(
775 IPersistStreamInit
*iface
, IStream
*stream
, BOOL clr_dirty
)
777 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
781 TRACE("(%p)->(%p %d)\n", This
, stream
, clr_dirty
);
783 hr
= IXMLDOMDocument3_get_xml(&This
->IXMLDOMDocument3_iface
, &xmlString
);
786 DWORD len
= SysStringLen(xmlString
) * sizeof(WCHAR
);
788 hr
= IStream_Write( stream
, xmlString
, len
, NULL
);
789 SysFreeString(xmlString
);
792 TRACE("ret 0x%08x\n", hr
);
797 static HRESULT WINAPI
PersistStreamInit_GetSizeMax(
798 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
800 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
801 TRACE("(%p)->(%p): stub!\n", This
, pcbSize
);
805 static HRESULT WINAPI
PersistStreamInit_InitNew(
806 IPersistStreamInit
*iface
)
808 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
809 TRACE("(%p)\n", This
);
813 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
815 PersistStreamInit_QueryInterface
,
816 PersistStreamInit_AddRef
,
817 PersistStreamInit_Release
,
818 PersistStreamInit_GetClassID
,
819 PersistStreamInit_IsDirty
,
820 PersistStreamInit_Load
,
821 PersistStreamInit_Save
,
822 PersistStreamInit_GetSizeMax
,
823 PersistStreamInit_InitNew
826 /* IXMLDOMDocument3 interface */
828 static const tid_t domdoc_se_tids
[] = {
831 IXMLDOMDocument2_tid
,
832 IXMLDOMDocument3_tid
,
836 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument3
*iface
, REFIID riid
, void** ppvObject
)
838 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
840 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppvObject
);
844 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
845 IsEqualGUID( riid
, &IID_IDispatch
) ||
846 IsEqualGUID( riid
, &IID_IXMLDOMNode
) ||
847 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
848 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
)||
849 IsEqualGUID( riid
, &IID_IXMLDOMDocument3
))
853 else if (IsEqualGUID(&IID_IPersistStream
, riid
) ||
854 IsEqualGUID(&IID_IPersistStreamInit
, riid
))
856 *ppvObject
= &This
->IPersistStreamInit_iface
;
858 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
860 *ppvObject
= &This
->IObjectWithSite_iface
;
862 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
864 *ppvObject
= &This
->IObjectSafety_iface
;
866 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
868 return node_create_supporterrorinfo(domdoc_se_tids
, ppvObject
);
870 else if(node_query_interface(&This
->node
, riid
, ppvObject
))
872 return *ppvObject
? S_OK
: E_NOINTERFACE
;
874 else if (IsEqualGUID( riid
, &IID_IConnectionPointContainer
))
876 *ppvObject
= &This
->IConnectionPointContainer_iface
;
880 TRACE("interface %s not implemented\n", debugstr_guid(riid
));
881 return E_NOINTERFACE
;
884 IUnknown_AddRef((IUnknown
*)*ppvObject
);
889 static ULONG WINAPI
domdoc_AddRef( IXMLDOMDocument3
*iface
)
891 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
892 ULONG ref
= InterlockedIncrement( &This
->ref
);
893 TRACE("(%p)->(%d)\n", This
, ref
);
897 static ULONG WINAPI
domdoc_Release( IXMLDOMDocument3
*iface
)
899 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
900 LONG ref
= InterlockedDecrement( &This
->ref
);
902 TRACE("(%p)->(%d)\n", This
, ref
);
909 detach_bsc(This
->bsc
);
912 IUnknown_Release( This
->site
);
913 destroy_xmlnode(&This
->node
);
915 IStream_Release(This
->stream
);
917 for (eid
= 0; eid
< EVENTID_LAST
; eid
++)
918 if (This
->events
[eid
]) IDispatch_Release(This
->events
[eid
]);
920 release_namespaces(This
);
927 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument3
*iface
, UINT
* pctinfo
)
929 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
930 return IDispatchEx_GetTypeInfoCount(&This
->node
.dispex
.IDispatchEx_iface
, pctinfo
);
933 static HRESULT WINAPI
domdoc_GetTypeInfo(
934 IXMLDOMDocument3
*iface
,
935 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
937 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
938 return IDispatchEx_GetTypeInfo(&This
->node
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
941 static HRESULT WINAPI
domdoc_GetIDsOfNames(
942 IXMLDOMDocument3
*iface
,
949 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
950 return IDispatchEx_GetIDsOfNames(&This
->node
.dispex
.IDispatchEx_iface
,
951 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
954 static HRESULT WINAPI
domdoc_Invoke(
955 IXMLDOMDocument3
*iface
,
960 DISPPARAMS
* pDispParams
,
962 EXCEPINFO
* pExcepInfo
,
965 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
966 return IDispatchEx_Invoke(&This
->node
.dispex
.IDispatchEx_iface
,
967 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
970 static HRESULT WINAPI
domdoc_get_nodeName(
971 IXMLDOMDocument3
*iface
,
974 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
976 static const WCHAR documentW
[] = {'#','d','o','c','u','m','e','n','t',0};
978 TRACE("(%p)->(%p)\n", This
, name
);
980 return return_bstr(documentW
, name
);
984 static HRESULT WINAPI
domdoc_get_nodeValue(
985 IXMLDOMDocument3
*iface
,
988 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
990 TRACE("(%p)->(%p)\n", This
, value
);
995 V_VT(value
) = VT_NULL
;
996 V_BSTR(value
) = NULL
; /* tests show that we should do this */
1001 static HRESULT WINAPI
domdoc_put_nodeValue(
1002 IXMLDOMDocument3
*iface
,
1005 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1006 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&value
));
1011 static HRESULT WINAPI
domdoc_get_nodeType(
1012 IXMLDOMDocument3
*iface
,
1015 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1017 TRACE("(%p)->(%p)\n", This
, type
);
1019 *type
= NODE_DOCUMENT
;
1024 static HRESULT WINAPI
domdoc_get_parentNode(
1025 IXMLDOMDocument3
*iface
,
1026 IXMLDOMNode
** parent
)
1028 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1030 TRACE("(%p)->(%p)\n", This
, parent
);
1032 return node_get_parent(&This
->node
, parent
);
1036 static HRESULT WINAPI
domdoc_get_childNodes(
1037 IXMLDOMDocument3
*iface
,
1038 IXMLDOMNodeList
** childList
)
1040 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1042 TRACE("(%p)->(%p)\n", This
, childList
);
1044 return node_get_child_nodes(&This
->node
, childList
);
1048 static HRESULT WINAPI
domdoc_get_firstChild(
1049 IXMLDOMDocument3
*iface
,
1050 IXMLDOMNode
** firstChild
)
1052 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1054 TRACE("(%p)->(%p)\n", This
, firstChild
);
1056 return node_get_first_child(&This
->node
, firstChild
);
1060 static HRESULT WINAPI
domdoc_get_lastChild(
1061 IXMLDOMDocument3
*iface
,
1062 IXMLDOMNode
** lastChild
)
1064 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1066 TRACE("(%p)->(%p)\n", This
, lastChild
);
1068 return node_get_last_child(&This
->node
, lastChild
);
1072 static HRESULT WINAPI
domdoc_get_previousSibling(
1073 IXMLDOMDocument3
*iface
,
1074 IXMLDOMNode
** previousSibling
)
1076 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1078 TRACE("(%p)->(%p)\n", This
, previousSibling
);
1080 return return_null_node(previousSibling
);
1084 static HRESULT WINAPI
domdoc_get_nextSibling(
1085 IXMLDOMDocument3
*iface
,
1086 IXMLDOMNode
** nextSibling
)
1088 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1090 TRACE("(%p)->(%p)\n", This
, nextSibling
);
1092 return return_null_node(nextSibling
);
1096 static HRESULT WINAPI
domdoc_get_attributes(
1097 IXMLDOMDocument3
*iface
,
1098 IXMLDOMNamedNodeMap
** attributeMap
)
1100 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1102 TRACE("(%p)->(%p)\n", This
, attributeMap
);
1104 return return_null_ptr((void**)attributeMap
);
1108 static HRESULT WINAPI
domdoc_insertBefore(
1109 IXMLDOMDocument3
*iface
,
1110 IXMLDOMNode
* newChild
,
1112 IXMLDOMNode
** outNewChild
)
1114 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1116 TRACE("(%p)->(%p %s %p)\n", This
, newChild
, debugstr_variant(&refChild
), outNewChild
);
1118 return node_insert_before(&This
->node
, newChild
, &refChild
, outNewChild
);
1122 static HRESULT WINAPI
domdoc_replaceChild(
1123 IXMLDOMDocument3
*iface
,
1124 IXMLDOMNode
* newChild
,
1125 IXMLDOMNode
* oldChild
,
1126 IXMLDOMNode
** outOldChild
)
1128 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1130 TRACE("(%p)->(%p %p %p)\n", This
, newChild
, oldChild
, outOldChild
);
1132 return node_replace_child(&This
->node
, newChild
, oldChild
, outOldChild
);
1136 static HRESULT WINAPI
domdoc_removeChild(
1137 IXMLDOMDocument3
*iface
,
1139 IXMLDOMNode
**oldChild
)
1141 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1142 TRACE("(%p)->(%p %p)\n", This
, child
, oldChild
);
1143 return node_remove_child(&This
->node
, child
, oldChild
);
1147 static HRESULT WINAPI
domdoc_appendChild(
1148 IXMLDOMDocument3
*iface
,
1150 IXMLDOMNode
**outChild
)
1152 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1153 TRACE("(%p)->(%p %p)\n", This
, child
, outChild
);
1154 return node_append_child(&This
->node
, child
, outChild
);
1158 static HRESULT WINAPI
domdoc_hasChildNodes(
1159 IXMLDOMDocument3
*iface
,
1162 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1163 TRACE("(%p)->(%p)\n", This
, ret
);
1164 return node_has_childnodes(&This
->node
, ret
);
1168 static HRESULT WINAPI
domdoc_get_ownerDocument(
1169 IXMLDOMDocument3
*iface
,
1170 IXMLDOMDocument
**doc
)
1172 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1173 TRACE("(%p)->(%p)\n", This
, doc
);
1174 return node_get_owner_doc(&This
->node
, doc
);
1178 static HRESULT WINAPI
domdoc_cloneNode(
1179 IXMLDOMDocument3
*iface
,
1181 IXMLDOMNode
** outNode
)
1183 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1184 TRACE("(%p)->(%d %p)\n", This
, deep
, outNode
);
1185 return node_clone( &This
->node
, deep
, outNode
);
1189 static HRESULT WINAPI
domdoc_get_nodeTypeString(
1190 IXMLDOMDocument3
*iface
,
1193 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1194 static const WCHAR documentW
[] = {'d','o','c','u','m','e','n','t',0};
1196 TRACE("(%p)->(%p)\n", This
, p
);
1198 return return_bstr(documentW
, p
);
1202 static HRESULT WINAPI
domdoc_get_text(
1203 IXMLDOMDocument3
*iface
,
1206 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1207 TRACE("(%p)->(%p)\n", This
, p
);
1208 return node_get_text(&This
->node
, p
);
1212 static HRESULT WINAPI
domdoc_put_text(
1213 IXMLDOMDocument3
*iface
,
1216 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1217 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
1222 static HRESULT WINAPI
domdoc_get_specified(
1223 IXMLDOMDocument3
*iface
,
1224 VARIANT_BOOL
* isSpecified
)
1226 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1227 FIXME("(%p)->(%p) stub!\n", This
, isSpecified
);
1228 *isSpecified
= VARIANT_TRUE
;
1233 static HRESULT WINAPI
domdoc_get_definition(
1234 IXMLDOMDocument3
*iface
,
1235 IXMLDOMNode
** definitionNode
)
1237 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1238 FIXME("(%p)->(%p)\n", This
, definitionNode
);
1243 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
1244 IXMLDOMDocument3
*iface
,
1247 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1248 TRACE("(%p)->(%p)\n", This
, v
);
1249 return return_null_var(v
);
1252 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
1253 IXMLDOMDocument3
*iface
,
1254 VARIANT typedValue
)
1256 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1257 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&typedValue
));
1262 static HRESULT WINAPI
domdoc_get_dataType(
1263 IXMLDOMDocument3
*iface
,
1266 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1267 TRACE("(%p)->(%p)\n", This
, typename
);
1268 return return_null_var( typename
);
1272 static HRESULT WINAPI
domdoc_put_dataType(
1273 IXMLDOMDocument3
*iface
,
1276 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1278 FIXME("(%p)->(%s)\n", This
, debugstr_w(dataTypeName
));
1281 return E_INVALIDARG
;
1286 static int XMLCALL
domdoc_get_xml_writecallback(void *ctx
, const char *data
, int len
)
1288 return xmlBufferAdd((xmlBufferPtr
)ctx
, (xmlChar
*)data
, len
) == 0 ? len
: 0;
1291 static HRESULT WINAPI
domdoc_get_xml(
1292 IXMLDOMDocument3
*iface
,
1295 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1296 xmlSaveCtxtPtr ctxt
;
1301 TRACE("(%p)->(%p)\n", This
, p
);
1304 return E_INVALIDARG
;
1308 buf
= xmlBufferCreate();
1310 return E_OUTOFMEMORY
;
1312 options
= XML_SAVE_FORMAT
| XML_SAVE_NO_DECL
;
1313 ctxt
= xmlSaveToIO(domdoc_get_xml_writecallback
, NULL
, buf
, "UTF-8", options
);
1318 return E_OUTOFMEMORY
;
1321 ret
= xmlSaveDoc(ctxt
, get_doc(This
));
1322 /* flushes on close */
1325 TRACE("%ld, len=%d\n", ret
, xmlBufferLength(buf
));
1326 if(ret
!= -1 && xmlBufferLength(buf
) > 0)
1330 content
= bstr_from_xmlChar(xmlBufferContent(buf
));
1331 content
= EnsureCorrectEOL(content
);
1337 *p
= SysAllocStringLen(NULL
, 0);
1342 return *p
? S_OK
: E_OUTOFMEMORY
;
1346 static HRESULT WINAPI
domdoc_transformNode(
1347 IXMLDOMDocument3
*iface
,
1351 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1352 TRACE("(%p)->(%p %p)\n", This
, node
, p
);
1353 return node_transform_node(&This
->node
, node
, p
);
1357 static HRESULT WINAPI
domdoc_selectNodes(
1358 IXMLDOMDocument3
*iface
,
1360 IXMLDOMNodeList
**outList
)
1362 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1363 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outList
);
1364 return node_select_nodes(&This
->node
, p
, outList
);
1368 static HRESULT WINAPI
domdoc_selectSingleNode(
1369 IXMLDOMDocument3
*iface
,
1371 IXMLDOMNode
**outNode
)
1373 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1374 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(p
), outNode
);
1375 return node_select_singlenode(&This
->node
, p
, outNode
);
1379 static HRESULT WINAPI
domdoc_get_parsed(
1380 IXMLDOMDocument3
*iface
,
1381 VARIANT_BOOL
* isParsed
)
1383 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1384 FIXME("(%p)->(%p) stub!\n", This
, isParsed
);
1385 *isParsed
= VARIANT_TRUE
;
1389 static HRESULT WINAPI
domdoc_get_namespaceURI(
1390 IXMLDOMDocument3
*iface
,
1391 BSTR
* namespaceURI
)
1393 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1394 TRACE("(%p)->(%p)\n", This
, namespaceURI
);
1395 return return_null_bstr( namespaceURI
);
1398 static HRESULT WINAPI
domdoc_get_prefix(
1399 IXMLDOMDocument3
*iface
,
1402 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1403 TRACE("(%p)->(%p)\n", This
, prefix
);
1404 return return_null_bstr( prefix
);
1408 static HRESULT WINAPI
domdoc_get_baseName(
1409 IXMLDOMDocument3
*iface
,
1412 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1413 TRACE("(%p)->(%p)\n", This
, name
);
1414 return return_null_bstr( name
);
1418 static HRESULT WINAPI
domdoc_transformNodeToObject(
1419 IXMLDOMDocument3
*iface
,
1420 IXMLDOMNode
* stylesheet
,
1421 VARIANT outputObject
)
1423 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1424 FIXME("(%p)->(%p %s)\n", This
, stylesheet
, debugstr_variant(&outputObject
));
1429 static HRESULT WINAPI
domdoc_get_doctype(
1430 IXMLDOMDocument3
*iface
,
1431 IXMLDOMDocumentType
** doctype
)
1433 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1438 TRACE("(%p)->(%p)\n", This
, doctype
);
1440 if (!doctype
) return E_INVALIDARG
;
1444 dtd
= xmlGetIntSubset(get_doc(This
));
1445 if (!dtd
) return S_FALSE
;
1447 node
= create_node((xmlNodePtr
)dtd
);
1448 if (!node
) return S_FALSE
;
1450 hr
= IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentType
, (void**)doctype
);
1451 IXMLDOMNode_Release(node
);
1457 static HRESULT WINAPI
domdoc_get_implementation(
1458 IXMLDOMDocument3
*iface
,
1459 IXMLDOMImplementation
** impl
)
1461 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1463 TRACE("(%p)->(%p)\n", This
, impl
);
1466 return E_INVALIDARG
;
1468 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
1473 static HRESULT WINAPI
domdoc_get_documentElement(
1474 IXMLDOMDocument3
*iface
,
1475 IXMLDOMElement
** DOMElement
)
1477 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1478 IXMLDOMNode
*element_node
;
1482 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1485 return E_INVALIDARG
;
1489 root
= xmlDocGetRootElement( get_doc(This
) );
1493 element_node
= create_node( root
);
1494 if(!element_node
) return S_FALSE
;
1496 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (void**)DOMElement
);
1497 IXMLDOMNode_Release(element_node
);
1503 static HRESULT WINAPI
domdoc_put_documentElement(
1504 IXMLDOMDocument3
*iface
,
1505 IXMLDOMElement
* DOMElement
)
1507 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1508 IXMLDOMNode
*elementNode
;
1513 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1515 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1519 xmlNode
= get_node_obj( elementNode
);
1520 if(!xmlNode
) return E_FAIL
;
1522 if(!xmlNode
->node
->parent
)
1523 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1524 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1526 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1527 IXMLDOMNode_Release( elementNode
);
1530 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1536 static HRESULT WINAPI
domdoc_createElement(
1537 IXMLDOMDocument3
*iface
,
1539 IXMLDOMElement
** element
)
1541 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1546 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagname
), element
);
1548 if (!element
|| !tagname
) return E_INVALIDARG
;
1550 V_VT(&type
) = VT_I1
;
1551 V_I1(&type
) = NODE_ELEMENT
;
1553 hr
= IXMLDOMDocument3_createNode(iface
, type
, tagname
, NULL
, &node
);
1556 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMElement
, (void**)element
);
1557 IXMLDOMNode_Release(node
);
1564 static HRESULT WINAPI
domdoc_createDocumentFragment(
1565 IXMLDOMDocument3
*iface
,
1566 IXMLDOMDocumentFragment
** frag
)
1568 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1573 TRACE("(%p)->(%p)\n", This
, frag
);
1575 if (!frag
) return E_INVALIDARG
;
1579 V_VT(&type
) = VT_I1
;
1580 V_I1(&type
) = NODE_DOCUMENT_FRAGMENT
;
1582 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1585 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentFragment
, (void**)frag
);
1586 IXMLDOMNode_Release(node
);
1593 static HRESULT WINAPI
domdoc_createTextNode(
1594 IXMLDOMDocument3
*iface
,
1596 IXMLDOMText
** text
)
1598 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1603 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), text
);
1605 if (!text
) return E_INVALIDARG
;
1609 V_VT(&type
) = VT_I1
;
1610 V_I1(&type
) = NODE_TEXT
;
1612 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1615 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)text
);
1616 IXMLDOMNode_Release(node
);
1617 hr
= IXMLDOMText_put_data(*text
, data
);
1624 static HRESULT WINAPI
domdoc_createComment(
1625 IXMLDOMDocument3
*iface
,
1627 IXMLDOMComment
** comment
)
1629 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1634 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), comment
);
1636 if (!comment
) return E_INVALIDARG
;
1640 V_VT(&type
) = VT_I1
;
1641 V_I1(&type
) = NODE_COMMENT
;
1643 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1646 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)comment
);
1647 IXMLDOMNode_Release(node
);
1648 hr
= IXMLDOMComment_put_data(*comment
, data
);
1655 static HRESULT WINAPI
domdoc_createCDATASection(
1656 IXMLDOMDocument3
*iface
,
1658 IXMLDOMCDATASection
** cdata
)
1660 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1665 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), cdata
);
1667 if (!cdata
) return E_INVALIDARG
;
1671 V_VT(&type
) = VT_I1
;
1672 V_I1(&type
) = NODE_CDATA_SECTION
;
1674 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1677 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)cdata
);
1678 IXMLDOMNode_Release(node
);
1679 hr
= IXMLDOMCDATASection_put_data(*cdata
, data
);
1686 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1687 IXMLDOMDocument3
*iface
,
1690 IXMLDOMProcessingInstruction
** pi
)
1692 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1697 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(target
), debugstr_w(data
), pi
);
1699 if (!pi
) return E_INVALIDARG
;
1703 V_VT(&type
) = VT_I1
;
1704 V_I1(&type
) = NODE_PROCESSING_INSTRUCTION
;
1706 hr
= IXMLDOMDocument3_createNode(iface
, type
, target
, NULL
, &node
);
1711 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1712 node_obj
= get_node_obj(node
);
1713 hr
= node_set_content(node_obj
, data
);
1715 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMProcessingInstruction
, (void**)pi
);
1716 IXMLDOMNode_Release(node
);
1723 static HRESULT WINAPI
domdoc_createAttribute(
1724 IXMLDOMDocument3
*iface
,
1726 IXMLDOMAttribute
** attribute
)
1728 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1733 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), attribute
);
1735 if (!attribute
|| !name
) return E_INVALIDARG
;
1737 V_VT(&type
) = VT_I1
;
1738 V_I1(&type
) = NODE_ATTRIBUTE
;
1740 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1743 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMAttribute
, (void**)attribute
);
1744 IXMLDOMNode_Release(node
);
1751 static HRESULT WINAPI
domdoc_createEntityReference(
1752 IXMLDOMDocument3
*iface
,
1754 IXMLDOMEntityReference
** entityref
)
1756 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1761 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), entityref
);
1763 if (!entityref
) return E_INVALIDARG
;
1767 V_VT(&type
) = VT_I1
;
1768 V_I1(&type
) = NODE_ENTITY_REFERENCE
;
1770 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1773 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMEntityReference
, (void**)entityref
);
1774 IXMLDOMNode_Release(node
);
1780 xmlChar
* tagName_to_XPath(const BSTR tagName
)
1782 xmlChar
*query
, *tmp
;
1783 static const xmlChar mod_pre
[] = "*[local-name()='";
1784 static const xmlChar mod_post
[] = "']";
1785 static const xmlChar prefix
[] = "descendant::";
1786 const WCHAR
*tokBegin
, *tokEnd
;
1789 query
= xmlStrdup(prefix
);
1792 while (tokBegin
&& *tokBegin
)
1797 query
= xmlStrcat(query
, BAD_CAST
"/");
1801 query
= xmlStrcat(query
, BAD_CAST
"*");
1805 query
= xmlStrcat(query
, mod_pre
);
1807 while (*tokEnd
&& *tokEnd
!= '/')
1809 len
= WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, NULL
, 0, NULL
, NULL
);
1810 tmp
= xmlMalloc(len
);
1811 WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, (char*)tmp
, len
, NULL
, NULL
);
1812 query
= xmlStrncat(query
, tmp
, len
);
1815 query
= xmlStrcat(query
, mod_post
);
1822 static HRESULT WINAPI
domdoc_getElementsByTagName(
1823 IXMLDOMDocument3
*iface
,
1825 IXMLDOMNodeList
** resultList
)
1827 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1832 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(tagName
), resultList
);
1834 if (!tagName
|| !resultList
) return E_INVALIDARG
;
1836 XPath
= This
->properties
->XPath
;
1837 This
->properties
->XPath
= TRUE
;
1838 query
= tagName_to_XPath(tagName
);
1839 hr
= create_selection((xmlNodePtr
)get_doc(This
), query
, resultList
);
1841 This
->properties
->XPath
= XPath
;
1846 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1852 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1854 return E_INVALIDARG
;
1861 static HRESULT WINAPI
domdoc_createNode(
1862 IXMLDOMDocument3
*iface
,
1866 IXMLDOMNode
** node
)
1868 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1869 DOMNodeType node_type
;
1871 xmlChar
*xml_name
, *href
;
1874 TRACE("(%p)->(%s %s %s %p)\n", This
, debugstr_variant(&Type
), debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1876 if(!node
) return E_INVALIDARG
;
1878 hr
= get_node_type(Type
, &node_type
);
1879 if(FAILED(hr
)) return hr
;
1881 if(namespaceURI
&& namespaceURI
[0] && node_type
!= NODE_ELEMENT
)
1882 FIXME("nodes with namespaces currently not supported.\n");
1884 TRACE("node_type %d\n", node_type
);
1886 /* exit earlier for types that need name */
1890 case NODE_ATTRIBUTE
:
1891 case NODE_ENTITY_REFERENCE
:
1892 case NODE_PROCESSING_INSTRUCTION
:
1893 if (!name
|| *name
== 0) return E_FAIL
;
1899 xml_name
= xmlchar_from_wchar(name
);
1900 /* prevent empty href to be allocated */
1901 href
= namespaceURI
? xmlchar_from_wchar(namespaceURI
) : NULL
;
1907 xmlChar
*local
, *prefix
;
1909 local
= xmlSplitQName2(xml_name
, &prefix
);
1911 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, local
? local
: xml_name
, NULL
);
1913 /* allow to create default namespace xmlns= */
1914 if (local
|| (href
&& *href
))
1916 xmlNsPtr ns
= xmlNewNs(xmlnode
, href
, prefix
);
1917 xmlSetNs(xmlnode
, ns
);
1925 case NODE_ATTRIBUTE
:
1926 xmlnode
= (xmlNodePtr
)xmlNewDocProp(get_doc(This
), xml_name
, NULL
);
1929 xmlnode
= (xmlNodePtr
)xmlNewDocText(get_doc(This
), NULL
);
1931 case NODE_CDATA_SECTION
:
1932 xmlnode
= xmlNewCDataBlock(get_doc(This
), NULL
, 0);
1934 case NODE_ENTITY_REFERENCE
:
1935 xmlnode
= xmlNewReference(get_doc(This
), xml_name
);
1937 case NODE_PROCESSING_INSTRUCTION
:
1938 #ifdef HAVE_XMLNEWDOCPI
1939 xmlnode
= xmlNewDocPI(get_doc(This
), xml_name
, NULL
);
1941 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1946 xmlnode
= xmlNewDocComment(get_doc(This
), NULL
);
1948 case NODE_DOCUMENT_FRAGMENT
:
1949 xmlnode
= xmlNewDocFragment(get_doc(This
));
1951 /* unsupported types */
1953 case NODE_DOCUMENT_TYPE
:
1956 heap_free(xml_name
);
1957 return E_INVALIDARG
;
1959 FIXME("unhandled node type %d\n", node_type
);
1964 *node
= create_node(xmlnode
);
1965 heap_free(xml_name
);
1970 TRACE("created node (%d, %p, %p)\n", node_type
, *node
, xmlnode
);
1971 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1978 static HRESULT WINAPI
domdoc_nodeFromID(
1979 IXMLDOMDocument3
*iface
,
1981 IXMLDOMNode
** node
)
1983 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1984 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(idString
), node
);
1988 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
1993 xmldoc
= doparse(This
, ptr
, len
, XML_CHAR_ENCODING_NONE
);
1995 xmldoc
->_private
= create_priv();
1996 return attach_xmldoc(This
, xmldoc
);
2002 static HRESULT
domdoc_load_moniker(domdoc
*This
, IMoniker
*mon
)
2007 hr
= bind_url(mon
, domdoc_onDataAvailable
, This
, &bsc
);
2012 hr
= detach_bsc(This
->bsc
);
2021 static HRESULT WINAPI
domdoc_load(
2022 IXMLDOMDocument3
*iface
,
2024 VARIANT_BOOL
* isSuccessful
)
2026 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2027 LPWSTR filename
= NULL
;
2028 HRESULT hr
= S_FALSE
;
2029 IXMLDOMDocument3
*pNewDoc
= NULL
;
2030 IStream
*pStream
= NULL
;
2033 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&source
));
2037 *isSuccessful
= VARIANT_FALSE
;
2039 assert( &This
->node
);
2041 switch( V_VT(&source
) )
2044 filename
= V_BSTR(&source
);
2046 case VT_BSTR
|VT_BYREF
:
2047 if (!V_BSTRREF(&source
)) return E_INVALIDARG
;
2048 filename
= *V_BSTRREF(&source
);
2050 case VT_ARRAY
|VT_UI1
:
2052 SAFEARRAY
*psa
= V_ARRAY(&source
);
2055 UINT dim
= SafeArrayGetDim(psa
);
2060 ERR("SAFEARRAY == NULL\n");
2061 hr
= This
->error
= E_INVALIDARG
;
2064 /* Only takes UTF-8 strings.
2065 * NOT NULL-terminated. */
2066 SafeArrayAccessData(psa
, (void**)&str
);
2067 SafeArrayGetUBound(psa
, 1, &len
);
2069 if ((xmldoc
= doparse(This
, str
, ++len
, XML_CHAR_ENCODING_UTF8
)))
2071 hr
= This
->error
= S_OK
;
2072 *isSuccessful
= VARIANT_TRUE
;
2073 TRACE("parsed document %p\n", xmldoc
);
2077 This
->error
= E_FAIL
;
2078 TRACE("failed to parse document\n");
2081 SafeArrayUnaccessData(psa
);
2085 xmldoc
->_private
= create_priv();
2086 return attach_xmldoc(This
, xmldoc
);
2090 FIXME("unhandled SAFEARRAY dim: %d\n", dim
);
2091 hr
= This
->error
= E_NOTIMPL
;
2096 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IXMLDOMDocument3
, (void**)&pNewDoc
);
2101 domdoc
*newDoc
= impl_from_IXMLDOMDocument3( pNewDoc
);
2103 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
2104 xmldoc
->_private
= create_priv();
2105 hr
= attach_xmldoc(This
, xmldoc
);
2108 *isSuccessful
= VARIANT_TRUE
;
2113 hr
= IUnknown_QueryInterface(V_UNKNOWN(&source
), &IID_IStream
, (void**)&pStream
);
2116 IPersistStream
*pDocStream
;
2117 hr
= IUnknown_QueryInterface(iface
, &IID_IPersistStream
, (void**)&pDocStream
);
2120 hr
= IPersistStream_Load(pDocStream
, pStream
);
2121 IStream_Release(pStream
);
2124 *isSuccessful
= VARIANT_TRUE
;
2126 TRACE("Using IStream to load Document\n");
2131 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr
);
2136 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr
);
2141 /* ISequentialStream */
2142 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr
, pNewDoc
, V_UNKNOWN(&source
)->lpVtbl
);
2146 FIXME("VT type not supported (%d)\n", V_VT(&source
));
2153 hr
= create_moniker_from_url( filename
, &mon
);
2154 if ( SUCCEEDED(hr
) )
2156 hr
= domdoc_load_moniker( This
, mon
);
2157 IMoniker_Release(mon
);
2161 This
->error
= E_FAIL
;
2164 hr
= This
->error
= S_OK
;
2165 *isSuccessful
= VARIANT_TRUE
;
2169 if(!filename
|| FAILED(hr
)) {
2170 xmldoc
= xmlNewDoc(NULL
);
2171 xmldoc
->_private
= create_priv();
2172 hr
= attach_xmldoc(This
, xmldoc
);
2177 TRACE("ret (%d)\n", hr
);
2183 static HRESULT WINAPI
domdoc_get_readyState(
2184 IXMLDOMDocument3
*iface
,
2187 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2188 FIXME("stub! (%p)->(%p)\n", This
, value
);
2191 return E_INVALIDARG
;
2193 *value
= READYSTATE_COMPLETE
;
2198 static HRESULT WINAPI
domdoc_get_parseError(
2199 IXMLDOMDocument3
*iface
,
2200 IXMLDOMParseError
** errorObj
)
2202 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2203 static const WCHAR err
[] = {'e','r','r','o','r',0};
2204 BSTR error_string
= NULL
;
2206 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
2209 error_string
= SysAllocString(err
);
2211 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
2212 if(!*errorObj
) return E_OUTOFMEMORY
;
2217 static HRESULT WINAPI
domdoc_get_url(
2218 IXMLDOMDocument3
*iface
,
2221 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2222 FIXME("(%p)->(%p)\n", This
, urlString
);
2227 static HRESULT WINAPI
domdoc_get_async(
2228 IXMLDOMDocument3
*iface
,
2229 VARIANT_BOOL
* isAsync
)
2231 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2233 TRACE("(%p)->(%p: %d)\n", This
, isAsync
, This
->async
);
2234 *isAsync
= This
->async
;
2239 static HRESULT WINAPI
domdoc_put_async(
2240 IXMLDOMDocument3
*iface
,
2241 VARIANT_BOOL isAsync
)
2243 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2245 TRACE("(%p)->(%d)\n", This
, isAsync
);
2246 This
->async
= isAsync
;
2251 static HRESULT WINAPI
domdoc_abort(
2252 IXMLDOMDocument3
*iface
)
2254 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2255 FIXME("%p\n", This
);
2259 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2260 static HRESULT WINAPI
domdoc_loadXML(
2261 IXMLDOMDocument3
*iface
,
2263 VARIANT_BOOL
* isSuccessful
)
2265 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2266 xmlDocPtr xmldoc
= NULL
;
2267 HRESULT hr
= S_FALSE
, hr2
;
2269 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), isSuccessful
);
2271 assert ( &This
->node
);
2275 *isSuccessful
= VARIANT_FALSE
;
2281 /* skip leading spaces if needed */
2282 if (This
->properties
->version
== MSXML_DEFAULT
|| This
->properties
->version
== MSXML26
)
2283 while (*ptr
&& isspaceW(*ptr
)) ptr
++;
2285 xmldoc
= doparse(This
, (char*)ptr
, strlenW(ptr
)*sizeof(WCHAR
), XML_CHAR_ENCODING_UTF16LE
);
2288 This
->error
= E_FAIL
;
2289 TRACE("failed to parse document\n");
2293 hr
= This
->error
= S_OK
;
2294 *isSuccessful
= VARIANT_TRUE
;
2295 TRACE("parsed document %p\n", xmldoc
);
2301 xmldoc
= xmlNewDoc(NULL
);
2302 xmldoc
->_private
= create_priv();
2303 hr2
= attach_xmldoc(This
, xmldoc
);
2310 static int XMLCALL
domdoc_save_writecallback(void *ctx
, const char *buffer
, int len
)
2314 if(!WriteFile(ctx
, buffer
, len
, &written
, NULL
))
2316 WARN("write error\n");
2323 static int XMLCALL
domdoc_save_closecallback(void *ctx
)
2325 return CloseHandle(ctx
) ? 0 : -1;
2328 static int XMLCALL
domdoc_stream_save_writecallback(void *ctx
, const char *buffer
, int len
)
2333 hr
= IStream_Write((IStream
*)ctx
, buffer
, len
, &written
);
2334 TRACE("0x%08x %p %d %u\n", hr
, buffer
, len
, written
);
2337 WARN("stream write error: 0x%08x\n", hr
);
2344 static int XMLCALL
domdoc_stream_save_closecallback(void *ctx
)
2346 IStream_Release((IStream
*)ctx
);
2350 static HRESULT WINAPI
domdoc_save(
2351 IXMLDOMDocument3
*iface
,
2352 VARIANT destination
)
2354 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2355 xmlSaveCtxtPtr ctx
= NULL
;
2359 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&destination
));
2361 switch (V_VT(&destination
))
2365 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
2366 IXMLDOMDocument3
*document
;
2369 ret
= IUnknown_QueryInterface(pUnk
, &IID_IXMLDOMDocument3
, (void**)&document
);
2372 VARIANT_BOOL success
;
2375 ret
= IXMLDOMDocument3_get_xml(iface
, &xml
);
2378 ret
= IXMLDOMDocument3_loadXML(document
, xml
, &success
);
2382 IXMLDOMDocument3_Release(document
);
2386 ret
= IUnknown_QueryInterface(pUnk
, &IID_IStream
, (void**)&stream
);
2389 int options
= get_doc(This
)->standalone
== -1 ? XML_SAVE_NO_DECL
: 0;
2390 ctx
= xmlSaveToIO(domdoc_stream_save_writecallback
,
2391 domdoc_stream_save_closecallback
, stream
, NULL
, options
);
2395 IStream_Release(stream
);
2403 case VT_BSTR
| VT_BYREF
:
2405 int options
= get_doc(This
)->standalone
== -1 ? XML_SAVE_NO_DECL
: 0;
2407 /* save with file path */
2408 HANDLE handle
= CreateFileW( (V_VT(&destination
) & VT_BYREF
)? *V_BSTRREF(&destination
) : V_BSTR(&destination
),
2409 GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2410 if( handle
== INVALID_HANDLE_VALUE
)
2412 WARN("failed to create file\n");
2416 /* disable top XML declaration */
2417 ctx
= xmlSaveToIO(domdoc_save_writecallback
, domdoc_save_closecallback
,
2418 handle
, NULL
, options
);
2421 CloseHandle(handle
);
2428 FIXME("Unhandled VARIANT: %s\n", debugstr_variant(&destination
));
2432 xmldecl
= xmldoc_unlink_xmldecl(get_doc(This
));
2433 if (xmlSaveDoc(ctx
, get_doc(This
)) == -1) ret
= S_FALSE
;
2434 xmldoc_link_xmldecl(get_doc(This
), xmldecl
);
2436 /* will release resources through close callback */
2442 static HRESULT WINAPI
domdoc_get_validateOnParse(
2443 IXMLDOMDocument3
*iface
,
2444 VARIANT_BOOL
* isValidating
)
2446 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2447 TRACE("(%p)->(%p: %d)\n", This
, isValidating
, This
->validating
);
2448 *isValidating
= This
->validating
;
2453 static HRESULT WINAPI
domdoc_put_validateOnParse(
2454 IXMLDOMDocument3
*iface
,
2455 VARIANT_BOOL isValidating
)
2457 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2458 TRACE("(%p)->(%d)\n", This
, isValidating
);
2459 This
->validating
= isValidating
;
2464 static HRESULT WINAPI
domdoc_get_resolveExternals(
2465 IXMLDOMDocument3
*iface
,
2466 VARIANT_BOOL
* isResolving
)
2468 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2469 TRACE("(%p)->(%p: %d)\n", This
, isResolving
, This
->resolving
);
2470 *isResolving
= This
->resolving
;
2475 static HRESULT WINAPI
domdoc_put_resolveExternals(
2476 IXMLDOMDocument3
*iface
,
2477 VARIANT_BOOL isResolving
)
2479 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2480 TRACE("(%p)->(%d)\n", This
, isResolving
);
2481 This
->resolving
= isResolving
;
2486 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
2487 IXMLDOMDocument3
*iface
,
2488 VARIANT_BOOL
* isPreserving
)
2490 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2491 TRACE("(%p)->(%p: %d)\n", This
, isPreserving
, This
->properties
->preserving
);
2492 *isPreserving
= This
->properties
->preserving
;
2497 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
2498 IXMLDOMDocument3
*iface
,
2499 VARIANT_BOOL isPreserving
)
2501 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2502 TRACE("(%p)->(%d)\n", This
, isPreserving
);
2503 This
->properties
->preserving
= isPreserving
;
2508 static HRESULT WINAPI
domdoc_put_onreadystatechange(
2509 IXMLDOMDocument3
*iface
,
2512 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2514 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&event
));
2515 return set_doc_event(This
, EVENTID_READYSTATECHANGE
, &event
);
2519 static HRESULT WINAPI
domdoc_put_onDataAvailable(IXMLDOMDocument3
*iface
, VARIANT sink
)
2521 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2522 FIXME("(%p)->(%s): stub\n", This
, debugstr_variant(&sink
));
2526 static HRESULT WINAPI
domdoc_put_onTransformNode(IXMLDOMDocument3
*iface
, VARIANT sink
)
2528 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2529 FIXME("(%p)->(%s): stub\n", This
, debugstr_variant(&sink
));
2533 static HRESULT WINAPI
domdoc_get_namespaces(
2534 IXMLDOMDocument3
* iface
,
2535 IXMLDOMSchemaCollection
** collection
)
2537 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2540 FIXME("(%p)->(%p): semi-stub\n", This
, collection
);
2542 if (!collection
) return E_POINTER
;
2544 if (!This
->namespaces
)
2546 hr
= SchemaCache_create(This
->properties
->version
, NULL
, (void**)&This
->namespaces
);
2547 if (hr
!= S_OK
) return hr
;
2549 hr
= cache_from_doc_ns(This
->namespaces
, &This
->node
);
2551 release_namespaces(This
);
2554 if (This
->namespaces
)
2555 return IXMLDOMSchemaCollection2_QueryInterface(This
->namespaces
,
2556 &IID_IXMLDOMSchemaCollection
, (void**)collection
);
2561 static HRESULT WINAPI
domdoc_get_schemas(
2562 IXMLDOMDocument3
* iface
,
2565 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2566 IXMLDOMSchemaCollection2
* cur_schema
= This
->properties
->schemaCache
;
2567 HRESULT hr
= S_FALSE
;
2569 TRACE("(%p)->(%p)\n", This
, schema
);
2571 V_VT(schema
) = VT_NULL
;
2572 /* just to reset pointer part, cause that's what application is expected to use */
2573 V_DISPATCH(schema
) = NULL
;
2577 hr
= IXMLDOMSchemaCollection2_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(schema
));
2579 V_VT(schema
) = VT_DISPATCH
;
2584 static HRESULT WINAPI
domdoc_putref_schemas(
2585 IXMLDOMDocument3
* iface
,
2588 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2589 HRESULT hr
= E_FAIL
;
2590 IXMLDOMSchemaCollection2
* new_schema
= NULL
;
2592 FIXME("(%p)->(%s): semi-stub\n", This
, debugstr_variant(&schema
));
2593 switch(V_VT(&schema
))
2596 if (V_UNKNOWN(&schema
))
2598 hr
= IUnknown_QueryInterface(V_UNKNOWN(&schema
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2603 if (V_DISPATCH(&schema
))
2605 hr
= IDispatch_QueryInterface(V_DISPATCH(&schema
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2615 WARN("Can't get schema from vt %x\n", V_VT(&schema
));
2620 IXMLDOMSchemaCollection2
* old_schema
= InterlockedExchangePointer((void**)&This
->properties
->schemaCache
, new_schema
);
2621 if(old_schema
) IXMLDOMSchemaCollection2_Release(old_schema
);
2627 static inline BOOL
is_wellformed(xmlDocPtr doc
)
2629 #ifdef HAVE_XMLDOC_PROPERTIES
2630 return doc
->properties
& XML_DOC_WELLFORMED
;
2632 /* Not a full check, but catches the worst violations */
2636 for (child
= doc
->children
; child
!= NULL
; child
= child
->next
)
2638 switch (child
->type
)
2640 case XML_ELEMENT_NODE
:
2645 case XML_CDATA_SECTION_NODE
:
2657 static void LIBXML2_LOG_CALLBACK
validate_error(void* ctx
, char const* msg
, ...)
2661 LIBXML2_CALLBACK_ERR(domdoc_validateNode
, msg
, ap
);
2665 static void LIBXML2_LOG_CALLBACK
validate_warning(void* ctx
, char const* msg
, ...)
2669 LIBXML2_CALLBACK_WARN(domdoc_validateNode
, msg
, ap
);
2673 static HRESULT WINAPI
domdoc_validateNode(
2674 IXMLDOMDocument3
* iface
,
2676 IXMLDOMParseError
** err
)
2678 domdoc
* This
= impl_from_IXMLDOMDocument3(iface
);
2679 LONG state
, err_code
= 0;
2683 TRACE("(%p)->(%p, %p)\n", This
, node
, err
);
2684 IXMLDOMDocument3_get_readyState(iface
, &state
);
2685 if (state
!= READYSTATE_COMPLETE
)
2688 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2695 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2699 if (!get_node_obj(node
)->node
|| get_node_obj(node
)->node
->doc
!= get_doc(This
))
2702 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2706 if (!is_wellformed(get_doc(This
)))
2708 ERR("doc not well-formed\n");
2710 *err
= create_parseError(E_XML_NOTWF
, NULL
, NULL
, NULL
, 0, 0, 0);
2714 /* DTD validation */
2715 if (get_doc(This
)->intSubset
|| get_doc(This
)->extSubset
)
2717 xmlValidCtxtPtr vctx
= xmlNewValidCtxt();
2718 vctx
->error
= validate_error
;
2719 vctx
->warning
= validate_warning
;
2722 if (!((node
== (IXMLDOMNode
*)iface
)?
2723 xmlValidateDocument(vctx
, get_doc(This
)) :
2724 xmlValidateElement(vctx
, get_doc(This
), get_node_obj(node
)->node
)))
2726 /* TODO: get a real error code here */
2727 TRACE("DTD validation failed\n");
2728 err_code
= E_XML_INVALID
;
2731 xmlFreeValidCtxt(vctx
);
2734 /* Schema validation */
2735 if (hr
== S_OK
&& This
->properties
->schemaCache
!= NULL
)
2738 hr
= SchemaCache_validate_tree(This
->properties
->schemaCache
, get_node_obj(node
)->node
);
2742 /* TODO: get a real error code here */
2745 TRACE("schema validation succeeded\n");
2749 ERR("schema validation failed\n");
2750 err_code
= E_XML_INVALID
;
2755 /* not really OK, just didn't find a schema for the ns */
2762 ERR("no DTD or schema found\n");
2763 err_code
= E_XML_NODTD
;
2768 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2773 static HRESULT WINAPI
domdoc_validate(
2774 IXMLDOMDocument3
* iface
,
2775 IXMLDOMParseError
** err
)
2777 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2778 TRACE("(%p)->(%p)\n", This
, err
);
2779 return IXMLDOMDocument3_validateNode(iface
, (IXMLDOMNode
*)iface
, err
);
2782 static HRESULT WINAPI
domdoc_setProperty(
2783 IXMLDOMDocument3
* iface
,
2787 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2789 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(p
), debugstr_variant(&value
));
2791 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2797 V_VT(&varStr
) = VT_EMPTY
;
2798 if (V_VT(&value
) != VT_BSTR
)
2800 if (FAILED(hr
= VariantChangeType(&varStr
, &value
, 0, VT_BSTR
)))
2802 bstr
= V_BSTR(&varStr
);
2805 bstr
= V_BSTR(&value
);
2808 if (lstrcmpiW(bstr
, PropValueXPathW
) == 0)
2809 This
->properties
->XPath
= TRUE
;
2810 else if (lstrcmpiW(bstr
, PropValueXSLPatternW
) == 0)
2811 This
->properties
->XPath
= FALSE
;
2815 VariantClear(&varStr
);
2818 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2820 xmlChar
*nsStr
= (xmlChar
*)This
->properties
->selectNsStr
;
2821 struct list
*pNsList
;
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
);
2838 pNsList
= &(This
->properties
->selectNsList
);
2839 clear_selectNsList(pNsList
);
2841 nsStr
= xmlchar_from_wchar(bstr
);
2843 TRACE("property value: \"%s\"\n", debugstr_w(bstr
));
2845 This
->properties
->selectNsStr
= nsStr
;
2846 This
->properties
->selectNsStr_len
= xmlStrlen(nsStr
);
2849 xmlChar
*pTokBegin
, *pTokEnd
, *pTokInner
;
2850 select_ns_entry
* ns_entry
= NULL
;
2851 xmlXPathContextPtr ctx
;
2853 ctx
= xmlXPathNewContext(This
->node
.node
->doc
);
2856 /* skip leading spaces */
2857 while (*pTokBegin
== ' ' || *pTokBegin
== '\n' ||
2858 *pTokBegin
== '\t' || *pTokBegin
== '\r')
2861 for (; *pTokBegin
; pTokBegin
= pTokEnd
)
2864 memset(ns_entry
, 0, sizeof(select_ns_entry
));
2866 ns_entry
= heap_alloc_zero(sizeof(select_ns_entry
));
2868 while (*pTokBegin
== ' ')
2870 pTokEnd
= pTokBegin
;
2871 while (*pTokEnd
!= ' ' && *pTokEnd
!= 0)
2874 if (xmlStrncmp(pTokBegin
, (xmlChar
const*)"xmlns", 5) != 0)
2877 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2878 debugstr_w(bstr
), debugstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2883 if (*pTokBegin
== '=')
2885 /*valid for XSLPattern?*/
2886 FIXME("Setting default xmlns not supported - skipping.\n");
2889 else if (*pTokBegin
== ':')
2891 ns_entry
->prefix
= ++pTokBegin
;
2892 for (pTokInner
= pTokBegin
; pTokInner
!= pTokEnd
&& *pTokInner
!= '='; ++pTokInner
)
2895 if (pTokInner
== pTokEnd
)
2898 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2899 debugstr_w(bstr
), debugstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2903 ns_entry
->prefix_end
= *pTokInner
;
2907 if (pTokEnd
-pTokInner
> 1 &&
2908 ((*pTokInner
== '\'' && *(pTokEnd
-1) == '\'') ||
2909 (*pTokInner
== '"' && *(pTokEnd
-1) == '"')))
2911 ns_entry
->href
= ++pTokInner
;
2912 ns_entry
->href_end
= *(pTokEnd
-1);
2914 list_add_tail(pNsList
, &ns_entry
->entry
);
2915 /*let libxml figure out if they're valid from here ;)*/
2916 if (xmlXPathRegisterNs(ctx
, ns_entry
->prefix
, ns_entry
->href
) != 0)
2925 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2926 debugstr_w(bstr
), debugstr_an((const char*)pTokInner
, pTokEnd
-pTokInner
));
2927 list_add_tail(pNsList
, &ns_entry
->entry
);
2940 heap_free(ns_entry
);
2941 xmlXPathFreeContext(ctx
);
2944 VariantClear(&varStr
);
2947 else if (lstrcmpiW(p
, PropertyProhibitDTDW
) == 0 ||
2948 lstrcmpiW(p
, PropertyNewParserW
) == 0 ||
2949 lstrcmpiW(p
, PropertyResolveExternalsW
) == 0)
2952 FIXME("Ignoring property %s, value %d\n", debugstr_w(p
), V_BOOL(&value
));
2956 FIXME("Unknown property %s\n", debugstr_w(p
));
2960 static HRESULT WINAPI
domdoc_getProperty(
2961 IXMLDOMDocument3
* iface
,
2965 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2967 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
2970 return E_INVALIDARG
;
2972 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2974 V_VT(var
) = VT_BSTR
;
2975 V_BSTR(var
) = This
->properties
->XPath
?
2976 SysAllocString(PropValueXPathW
) :
2977 SysAllocString(PropValueXSLPatternW
);
2978 return V_BSTR(var
) ? S_OK
: E_OUTOFMEMORY
;
2980 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2983 BSTR rebuiltStr
, cur
;
2984 const xmlChar
*nsStr
;
2985 struct list
*pNsList
;
2986 select_ns_entry
* pNsEntry
;
2988 V_VT(var
) = VT_BSTR
;
2989 nsStr
= This
->properties
->selectNsStr
;
2990 pNsList
= &This
->properties
->selectNsList
;
2991 lenA
= This
->properties
->selectNsStr_len
;
2992 lenW
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, NULL
, 0);
2993 rebuiltStr
= heap_alloc(lenW
*sizeof(WCHAR
));
2994 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, rebuiltStr
, lenW
);
2996 /* this is fine because all of the chars that end tokens are ASCII*/
2997 LIST_FOR_EACH_ENTRY(pNsEntry
, pNsList
, select_ns_entry
, entry
)
2999 while (*cur
!= 0) ++cur
;
3000 if (pNsEntry
->prefix_end
)
3002 *cur
= pNsEntry
->prefix_end
;
3003 while (*cur
!= 0) ++cur
;
3006 if (pNsEntry
->href_end
)
3008 *cur
= pNsEntry
->href_end
;
3011 V_BSTR(var
) = SysAllocString(rebuiltStr
);
3012 heap_free(rebuiltStr
);
3016 FIXME("Unknown property %s\n", debugstr_w(p
));
3020 static HRESULT WINAPI
domdoc_importNode(
3021 IXMLDOMDocument3
* iface
,
3024 IXMLDOMNode
** clone
)
3026 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
3027 FIXME("(%p)->(%p %d %p): stub\n", This
, node
, deep
, clone
);
3031 static const struct IXMLDOMDocument3Vtbl XMLDOMDocument3Vtbl
=
3033 domdoc_QueryInterface
,
3036 domdoc_GetTypeInfoCount
,
3038 domdoc_GetIDsOfNames
,
3040 domdoc_get_nodeName
,
3041 domdoc_get_nodeValue
,
3042 domdoc_put_nodeValue
,
3043 domdoc_get_nodeType
,
3044 domdoc_get_parentNode
,
3045 domdoc_get_childNodes
,
3046 domdoc_get_firstChild
,
3047 domdoc_get_lastChild
,
3048 domdoc_get_previousSibling
,
3049 domdoc_get_nextSibling
,
3050 domdoc_get_attributes
,
3051 domdoc_insertBefore
,
3052 domdoc_replaceChild
,
3055 domdoc_hasChildNodes
,
3056 domdoc_get_ownerDocument
,
3058 domdoc_get_nodeTypeString
,
3061 domdoc_get_specified
,
3062 domdoc_get_definition
,
3063 domdoc_get_nodeTypedValue
,
3064 domdoc_put_nodeTypedValue
,
3065 domdoc_get_dataType
,
3066 domdoc_put_dataType
,
3068 domdoc_transformNode
,
3070 domdoc_selectSingleNode
,
3072 domdoc_get_namespaceURI
,
3074 domdoc_get_baseName
,
3075 domdoc_transformNodeToObject
,
3077 domdoc_get_implementation
,
3078 domdoc_get_documentElement
,
3079 domdoc_put_documentElement
,
3080 domdoc_createElement
,
3081 domdoc_createDocumentFragment
,
3082 domdoc_createTextNode
,
3083 domdoc_createComment
,
3084 domdoc_createCDATASection
,
3085 domdoc_createProcessingInstruction
,
3086 domdoc_createAttribute
,
3087 domdoc_createEntityReference
,
3088 domdoc_getElementsByTagName
,
3092 domdoc_get_readyState
,
3093 domdoc_get_parseError
,
3100 domdoc_get_validateOnParse
,
3101 domdoc_put_validateOnParse
,
3102 domdoc_get_resolveExternals
,
3103 domdoc_put_resolveExternals
,
3104 domdoc_get_preserveWhiteSpace
,
3105 domdoc_put_preserveWhiteSpace
,
3106 domdoc_put_onreadystatechange
,
3107 domdoc_put_onDataAvailable
,
3108 domdoc_put_onTransformNode
,
3109 domdoc_get_namespaces
,
3111 domdoc_putref_schemas
,
3115 domdoc_validateNode
,
3119 /* IConnectionPointContainer */
3120 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
3121 REFIID riid
, void **ppv
)
3123 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3124 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3127 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
3129 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3130 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3133 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
3135 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3136 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3139 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
3140 IEnumConnectionPoints
**ppEnum
)
3142 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3143 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3147 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
3148 REFIID riid
, IConnectionPoint
**cp
)
3150 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3151 ConnectionPoint
*iter
;
3153 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), cp
);
3157 for(iter
= This
->cp_list
; iter
; iter
= iter
->next
)
3159 if (IsEqualGUID(iter
->iid
, riid
))
3160 *cp
= &iter
->IConnectionPoint_iface
;
3165 IConnectionPoint_AddRef(*cp
);
3169 FIXME("unsupported riid %s\n", debugstr_guid(riid
));
3170 return CONNECT_E_NOCONNECTION
;
3174 static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
3176 ConnectionPointContainer_QueryInterface
,
3177 ConnectionPointContainer_AddRef
,
3178 ConnectionPointContainer_Release
,
3179 ConnectionPointContainer_EnumConnectionPoints
,
3180 ConnectionPointContainer_FindConnectionPoint
3183 /* IConnectionPoint */
3184 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
3185 REFIID riid
, void **ppv
)
3187 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3189 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
3193 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
3194 IsEqualGUID(&IID_IConnectionPoint
, riid
))
3201 IConnectionPoint_AddRef(iface
);
3205 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
3206 return E_NOINTERFACE
;
3209 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
3211 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3212 return IConnectionPointContainer_AddRef(This
->container
);
3215 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
3217 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3218 return IConnectionPointContainer_Release(This
->container
);
3221 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*iid
)
3223 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3225 TRACE("(%p)->(%p)\n", This
, iid
);
3227 if (!iid
) return E_POINTER
;
3233 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
3234 IConnectionPointContainer
**container
)
3236 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3238 TRACE("(%p)->(%p)\n", This
, container
);
3240 if (!container
) return E_POINTER
;
3242 *container
= This
->container
;
3243 IConnectionPointContainer_AddRef(*container
);
3247 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
3250 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3251 FIXME("(%p)->(%p %p): stub\n", This
, pUnkSink
, pdwCookie
);
3255 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD cookie
)
3257 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3259 TRACE("(%p)->(%d)\n", This
, cookie
);
3261 if (cookie
== 0 || cookie
> This
->sinks_size
|| !This
->sinks
[cookie
-1].unk
)
3262 return CONNECT_E_NOCONNECTION
;
3264 IUnknown_Release(This
->sinks
[cookie
-1].unk
);
3265 This
->sinks
[cookie
-1].unk
= NULL
;
3270 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
3271 IEnumConnections
**ppEnum
)
3273 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3274 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3278 static const IConnectionPointVtbl ConnectionPointVtbl
=
3280 ConnectionPoint_QueryInterface
,
3281 ConnectionPoint_AddRef
,
3282 ConnectionPoint_Release
,
3283 ConnectionPoint_GetConnectionInterface
,
3284 ConnectionPoint_GetConnectionPointContainer
,
3285 ConnectionPoint_Advise
,
3286 ConnectionPoint_Unadvise
,
3287 ConnectionPoint_EnumConnections
3290 static void ConnectionPoint_Init(ConnectionPoint
*cp
, struct domdoc
*doc
, REFIID riid
)
3292 cp
->IConnectionPoint_iface
.lpVtbl
= &ConnectionPointVtbl
;
3298 cp
->next
= doc
->cp_list
;
3301 cp
->container
= &doc
->IConnectionPointContainer_iface
;
3304 /* domdoc implementation of IObjectWithSite */
3305 static HRESULT WINAPI
3306 domdoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
3308 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3309 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppvObject
);
3312 static ULONG WINAPI
domdoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
3314 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3315 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3318 static ULONG WINAPI
domdoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
3320 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3321 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3324 static HRESULT WINAPI
domdoc_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
3326 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3328 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
3333 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
3336 static HRESULT WINAPI
domdoc_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
3338 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3340 TRACE("(%p)->(%p)\n", iface
, punk
);
3346 IUnknown_Release( This
->site
);
3353 IUnknown_AddRef( punk
);
3356 IUnknown_Release( This
->site
);
3363 static const IObjectWithSiteVtbl domdocObjectSite
=
3365 domdoc_ObjectWithSite_QueryInterface
,
3366 domdoc_ObjectWithSite_AddRef
,
3367 domdoc_ObjectWithSite_Release
,
3368 domdoc_ObjectWithSite_SetSite
,
3369 domdoc_ObjectWithSite_GetSite
3372 static HRESULT WINAPI
domdoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
3374 domdoc
*This
= impl_from_IObjectSafety(iface
);
3375 return IXMLDOMDocument3_QueryInterface(&This
->IXMLDOMDocument3_iface
, riid
, ppv
);
3378 static ULONG WINAPI
domdoc_Safety_AddRef(IObjectSafety
*iface
)
3380 domdoc
*This
= impl_from_IObjectSafety(iface
);
3381 return IXMLDOMDocument3_AddRef(&This
->IXMLDOMDocument3_iface
);
3384 static ULONG WINAPI
domdoc_Safety_Release(IObjectSafety
*iface
)
3386 domdoc
*This
= impl_from_IObjectSafety(iface
);
3387 return IXMLDOMDocument3_Release(&This
->IXMLDOMDocument3_iface
);
3390 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
3392 static HRESULT WINAPI
domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3393 DWORD
*supported
, DWORD
*enabled
)
3395 domdoc
*This
= impl_from_IObjectSafety(iface
);
3397 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
3399 if(!supported
|| !enabled
) return E_POINTER
;
3401 *supported
= SAFETY_SUPPORTED_OPTIONS
;
3402 *enabled
= This
->safeopt
;
3407 static HRESULT WINAPI
domdoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3408 DWORD mask
, DWORD enabled
)
3410 domdoc
*This
= impl_from_IObjectSafety(iface
);
3411 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
3413 if ((mask
& ~SAFETY_SUPPORTED_OPTIONS
) != 0)
3416 This
->safeopt
= (This
->safeopt
& ~mask
) | (mask
& enabled
);
3421 #undef SAFETY_SUPPORTED_OPTIONS
3423 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
3424 domdoc_Safety_QueryInterface
,
3425 domdoc_Safety_AddRef
,
3426 domdoc_Safety_Release
,
3427 domdoc_Safety_GetInterfaceSafetyOptions
,
3428 domdoc_Safety_SetInterfaceSafetyOptions
3431 static const tid_t domdoc_iface_tids
[] = {
3432 IXMLDOMDocument3_tid
,
3436 static dispex_static_data_t domdoc_dispex
= {
3438 IXMLDOMDocument3_tid
,
3443 HRESULT
get_domdoc_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument3
**document
)
3447 doc
= heap_alloc( sizeof (*doc
) );
3449 return E_OUTOFMEMORY
;
3451 doc
->IXMLDOMDocument3_iface
.lpVtbl
= &XMLDOMDocument3Vtbl
;
3452 doc
->IPersistStreamInit_iface
.lpVtbl
= &xmldoc_IPersistStreamInit_VTable
;
3453 doc
->IObjectWithSite_iface
.lpVtbl
= &domdocObjectSite
;
3454 doc
->IObjectSafety_iface
.lpVtbl
= &domdocObjectSafetyVtbl
;
3455 doc
->IConnectionPointContainer_iface
.lpVtbl
= &ConnectionPointContainerVtbl
;
3457 doc
->async
= VARIANT_TRUE
;
3458 doc
->validating
= 0;
3460 doc
->properties
= properties_from_xmlDocPtr(xmldoc
);
3466 doc
->cp_list
= NULL
;
3467 doc
->namespaces
= NULL
;
3468 memset(doc
->events
, 0, sizeof(doc
->events
));
3470 /* events connection points */
3471 ConnectionPoint_Init(&doc
->cp_dispatch
, doc
, &IID_IDispatch
);
3472 ConnectionPoint_Init(&doc
->cp_propnotif
, doc
, &IID_IPropertyNotifySink
);
3473 ConnectionPoint_Init(&doc
->cp_domdocevents
, doc
, &DIID_XMLDOMDocumentEvents
);
3475 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IXMLDOMNode
*)&doc
->IXMLDOMDocument3_iface
,
3478 *document
= &doc
->IXMLDOMDocument3_iface
;
3480 TRACE("returning iface %p\n", *document
);
3484 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3489 TRACE("(%d, %p, %p)\n", version
, pUnkOuter
, ppObj
);
3491 xmldoc
= xmlNewDoc(NULL
);
3493 return E_OUTOFMEMORY
;
3495 xmldoc_init(xmldoc
, version
);
3497 hr
= get_domdoc_from_xmldoc(xmldoc
, (IXMLDOMDocument3
**)ppObj
);
3500 free_properties(properties_from_xmlDocPtr(xmldoc
));
3501 heap_free(xmldoc
->_private
);
3509 IUnknown
* create_domdoc( xmlNodePtr document
)
3514 TRACE("(%p)\n", document
);
3516 hr
= get_domdoc_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument3
**)&pObj
);
3525 HRESULT
DOMDocument_create(MSXML_VERSION version
, IUnknown
*pUnkOuter
, void **ppObj
)
3527 MESSAGE("This program tried to use a DOMDocument object, but\n"
3528 "libxml2 support was not present at compile time.\n");