2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
5 * Copyright 2010 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
43 #include "wine/debug.h"
44 #include "wine/list.h"
46 #include "msxml_private.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
52 #include <libxml/xpathInternals.h>
53 #include <libxml/xmlsave.h>
54 #include <libxml/SAX2.h>
55 #include <libxml/parserInternals.h>
57 /* not defined in older versions */
58 #define XML_SAVE_FORMAT 1
59 #define XML_SAVE_NO_DECL 2
60 #define XML_SAVE_NO_EMPTY 4
61 #define XML_SAVE_NO_XHTML 8
62 #define XML_SAVE_XHTML 16
63 #define XML_SAVE_AS_XML 32
64 #define XML_SAVE_AS_HTML 64
66 static const WCHAR PropertySelectionLanguageW
[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
67 static const WCHAR PropertySelectionNamespacesW
[] = {'S','e','l','e','c','t','i','o','n','N','a','m','e','s','p','a','c','e','s',0};
68 static const WCHAR PropertyProhibitDTDW
[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
69 static const WCHAR PropertyNewParserW
[] = {'N','e','w','P','a','r','s','e','r',0};
70 static const WCHAR PropValueXPathW
[] = {'X','P','a','t','h',0};
71 static const WCHAR PropValueXSLPatternW
[] = {'X','S','L','P','a','t','t','e','r','n',0};
73 /* Data used by domdoc_getProperty()/domdoc_setProperty().
74 * We need to preserve this when reloading a document,
75 * and also need access to it from the libxml backend. */
76 typedef struct _domdoc_properties
{
77 struct list selectNsList
;
78 xmlChar
const* selectNsStr
;
83 typedef struct ConnectionPoint ConnectionPoint
;
84 typedef struct domdoc domdoc
;
86 struct ConnectionPoint
88 const IConnectionPointVtbl
*lpVtblConnectionPoint
;
91 ConnectionPoint
*next
;
92 IConnectionPointContainer
*container
;
99 IPropertyNotifySink
*propnotif
;
107 const struct IXMLDOMDocument3Vtbl
*lpVtbl
;
108 const struct IPersistStreamInitVtbl
*lpvtblIPersistStreamInit
;
109 const struct IObjectWithSiteVtbl
*lpvtblIObjectWithSite
;
110 const struct IObjectSafetyVtbl
*lpvtblIObjectSafety
;
111 const struct ISupportErrorInfoVtbl
*lpvtblISupportErrorInfo
;
112 const struct IConnectionPointContainerVtbl
*lpVtblConnectionPointContainer
;
115 VARIANT_BOOL validating
;
116 VARIANT_BOOL resolving
;
117 VARIANT_BOOL preserving
;
118 domdoc_properties
* properties
;
119 IXMLDOMSchemaCollection2
* schema
;
132 /* connection list */
133 ConnectionPoint
*cp_list
;
134 ConnectionPoint cp_domdocevents
;
135 ConnectionPoint cp_propnotif
;
136 ConnectionPoint cp_dispatch
;
139 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
141 return (ConnectionPoint
*)((char*)iface
- FIELD_OFFSET(ConnectionPoint
, lpVtblConnectionPoint
));
145 In native windows, the whole lifetime management of XMLDOMNodes is
146 managed automatically using reference counts. Wine emulates that by
147 maintaining a reference count to the document that is increased for
148 each IXMLDOMNode pointer passed out for this document. If all these
149 pointers are gone, the document is unreachable and gets freed, that
150 is, all nodes in the tree of the document get freed.
152 You are able to create nodes that are associated to a document (in
153 fact, in msxml's XMLDOM model, all nodes are associated to a document),
154 but not in the tree of that document, for example using the createFoo
155 functions from IXMLDOMDocument. These nodes do not get cleaned up
156 by libxml, so we have to do it ourselves.
158 To catch these nodes, a list of "orphan nodes" is introduced.
159 It contains pointers to all roots of node trees that are
160 associated with the document without being part of the document
161 tree. All nodes with parent==NULL (except for the document root nodes)
162 should be in the orphan node list of their document. All orphan nodes
163 get freed together with the document itself.
166 typedef struct _xmldoc_priv
{
169 domdoc_properties
* properties
;
172 typedef struct _orphan_entry
{
177 typedef struct _select_ns_entry
{
179 xmlChar
const* prefix
;
185 static inline xmldoc_priv
* priv_from_xmlDocPtr(const xmlDocPtr doc
)
187 return doc
->_private
;
190 static inline domdoc_properties
* properties_from_xmlDocPtr(xmlDocPtr doc
)
192 return priv_from_xmlDocPtr(doc
)->properties
;
195 BOOL
is_xpathmode(const xmlDocPtr doc
)
197 return properties_from_xmlDocPtr(doc
)->XPath
;
200 int registerNamespaces(xmlXPathContextPtr ctxt
)
203 const select_ns_entry
* ns
= NULL
;
204 const struct list
* pNsList
= &properties_from_xmlDocPtr(ctxt
->doc
)->selectNsList
;
206 TRACE("(%p)\n", ctxt
);
208 LIST_FOR_EACH_ENTRY( ns
, pNsList
, select_ns_entry
, entry
)
210 xmlXPathRegisterNs(ctxt
, ns
->prefix
, ns
->href
);
217 static inline void clear_selectNsList(struct list
* pNsList
)
219 select_ns_entry
*ns
, *ns2
;
220 LIST_FOR_EACH_ENTRY_SAFE( ns
, ns2
, pNsList
, select_ns_entry
, entry
)
227 static xmldoc_priv
* create_priv(void)
230 priv
= heap_alloc( sizeof (*priv
) );
235 list_init( &priv
->orphans
);
236 priv
->properties
= NULL
;
242 static domdoc_properties
* create_properties(const GUID
*clsid
)
244 domdoc_properties
*properties
= heap_alloc(sizeof(domdoc_properties
));
246 list_init( &properties
->selectNsList
);
247 properties
->selectNsStr
= heap_alloc_zero(sizeof(xmlChar
));
248 properties
->selectNsStr_len
= 0;
249 properties
->XPath
= FALSE
;
251 /* properties that are dependent on object versions */
252 if (IsEqualCLSID( clsid
, &CLSID_DOMDocument40
) ||
253 IsEqualCLSID( clsid
, &CLSID_DOMDocument60
))
255 properties
->XPath
= TRUE
;
261 static domdoc_properties
* copy_properties(domdoc_properties
const* properties
)
263 domdoc_properties
* pcopy
= heap_alloc(sizeof(domdoc_properties
));
264 select_ns_entry
const* ns
= NULL
;
265 select_ns_entry
* new_ns
= NULL
;
266 int len
= (properties
->selectNsStr_len
+1)*sizeof(xmlChar
);
271 pcopy
->XPath
= properties
->XPath
;
272 pcopy
->selectNsStr_len
= properties
->selectNsStr_len
;
273 list_init( &pcopy
->selectNsList
);
274 pcopy
->selectNsStr
= heap_alloc(len
);
275 memcpy((xmlChar
*)pcopy
->selectNsStr
, properties
->selectNsStr
, len
);
276 offset
= pcopy
->selectNsStr
- properties
->selectNsStr
;
278 LIST_FOR_EACH_ENTRY( ns
, (&properties
->selectNsList
), select_ns_entry
, entry
)
280 new_ns
= heap_alloc(sizeof(select_ns_entry
));
281 memcpy(new_ns
, ns
, sizeof(select_ns_entry
));
282 new_ns
->href
+= offset
;
283 new_ns
->prefix
+= offset
;
284 list_add_tail(&pcopy
->selectNsList
, &new_ns
->entry
);
292 static void free_properties(domdoc_properties
* properties
)
296 clear_selectNsList(&properties
->selectNsList
);
297 heap_free((xmlChar
*)properties
->selectNsStr
);
298 heap_free(properties
);
302 /* links a "<?xml" node as a first child */
303 void xmldoc_link_xmldecl(xmlDocPtr doc
, xmlNodePtr node
)
306 if (doc
->standalone
!= -1) xmlAddPrevSibling( doc
->children
, node
);
309 /* unlinks a first "<?xml" child if it was created */
310 xmlNodePtr
xmldoc_unlink_xmldecl(xmlDocPtr doc
)
316 if (doc
->standalone
!= -1)
318 node
= doc
->children
;
319 xmlUnlinkNode( node
);
327 static inline BOOL
strn_isspace(xmlChar
const* str
, int len
)
329 for (; str
&& len
> 0 && *str
; ++str
, --len
)
336 static void sax_characters(void *ctx
, const xmlChar
*ch
, int len
)
338 xmlParserCtxtPtr pctx
;
341 pctx
= (xmlParserCtxtPtr
) ctx
;
342 This
= (domdoc
const*) pctx
->_private
;
344 if (!This
->preserving
)
346 xmlChar
* ws
= xmlGetNsProp(pctx
->node
, BAD_CAST
"space", XML_XML_NAMESPACE
);
347 if ((!ws
|| xmlStrcmp(ws
, BAD_CAST
"preserve") != 0) &&
348 strn_isspace(ch
, len
))
356 xmlSAX2Characters(ctx
, ch
, len
);
359 static void LIBXML2_LOG_CALLBACK
sax_error(void* ctx
, char const* msg
, ...)
363 LIBXML2_CALLBACK_ERR(doparse
, msg
, ap
);
367 static void LIBXML2_LOG_CALLBACK
sax_warning(void* ctx
, char const* msg
, ...)
371 LIBXML2_CALLBACK_WARN(doparse
, msg
, ap
);
375 static void sax_serror(void* ctx
, xmlErrorPtr err
)
377 LIBXML2_CALLBACK_SERROR(doparse
, err
);
380 static xmlDocPtr
doparse(domdoc
* This
, char *ptr
, int len
, xmlChar
const* encoding
)
382 xmlDocPtr doc
= NULL
;
383 xmlParserCtxtPtr pctx
;
384 static xmlSAXHandler sax_handler
= {
385 xmlSAX2InternalSubset
, /* internalSubset */
386 xmlSAX2IsStandalone
, /* isStandalone */
387 xmlSAX2HasInternalSubset
, /* hasInternalSubset */
388 xmlSAX2HasExternalSubset
, /* hasExternalSubset */
389 xmlSAX2ResolveEntity
, /* resolveEntity */
390 xmlSAX2GetEntity
, /* getEntity */
391 xmlSAX2EntityDecl
, /* entityDecl */
392 xmlSAX2NotationDecl
, /* notationDecl */
393 xmlSAX2AttributeDecl
, /* attributeDecl */
394 xmlSAX2ElementDecl
, /* elementDecl */
395 xmlSAX2UnparsedEntityDecl
, /* unparsedEntityDecl */
396 xmlSAX2SetDocumentLocator
, /* setDocumentLocator */
397 xmlSAX2StartDocument
, /* startDocument */
398 xmlSAX2EndDocument
, /* endDocument */
399 xmlSAX2StartElement
, /* startElement */
400 xmlSAX2EndElement
, /* endElement */
401 xmlSAX2Reference
, /* reference */
402 sax_characters
, /* characters */
403 sax_characters
, /* ignorableWhitespace */
404 xmlSAX2ProcessingInstruction
, /* processingInstruction */
405 xmlSAX2Comment
, /* comment */
406 sax_warning
, /* warning */
407 sax_error
, /* error */
408 sax_error
, /* fatalError */
409 xmlSAX2GetParameterEntity
, /* getParameterEntity */
410 xmlSAX2CDataBlock
, /* cdataBlock */
411 xmlSAX2ExternalSubset
, /* externalSubset */
414 xmlSAX2StartElementNs
, /* startElementNs */
415 xmlSAX2EndElementNs
, /* endElementNs */
416 sax_serror
/* serror */
420 pctx
= xmlCreateMemoryParserCtxt(ptr
, len
);
423 ERR("Failed to create parser context\n");
427 if (pctx
->sax
) xmlFree(pctx
->sax
);
428 pctx
->sax
= &sax_handler
;
429 pctx
->_private
= This
;
431 pctx
->encoding
= xmlStrdup(encoding
);
432 xmlParseDocument(pctx
);
434 if (pctx
->wellFormed
)
440 xmlFreeDoc(pctx
->myDoc
);
444 xmlFreeParserCtxt(pctx
);
446 /* TODO: put this in one of the SAX callbacks */
447 /* create first child as a <?xml...?> */
448 if (doc
&& doc
->standalone
!= -1)
452 xmlChar
*xmlbuff
= (xmlChar
*)buff
;
454 node
= xmlNewDocPI( doc
, (xmlChar
*)"xml", NULL
);
456 /* version attribute can't be omitted */
457 sprintf(buff
, "version=\"%s\"", doc
->version
? (char*)doc
->version
: "1.0");
458 xmlNodeAddContent( node
, xmlbuff
);
462 sprintf(buff
, " encoding=\"%s\"", doc
->encoding
);
463 xmlNodeAddContent( node
, xmlbuff
);
466 if (doc
->standalone
!= -2)
468 sprintf(buff
, " standalone=\"%s\"", doc
->standalone
== 0 ? "no" : "yes");
469 xmlNodeAddContent( node
, xmlbuff
);
472 xmldoc_link_xmldecl( doc
, node
);
478 void xmldoc_init(xmlDocPtr doc
, const GUID
*clsid
)
480 doc
->_private
= create_priv();
481 priv_from_xmlDocPtr(doc
)->properties
= create_properties(clsid
);
484 LONG
xmldoc_add_ref(xmlDocPtr doc
)
486 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
487 TRACE("(%p)->(%d)\n", doc
, ref
);
491 LONG
xmldoc_release(xmlDocPtr doc
)
493 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
494 LONG ref
= InterlockedDecrement(&priv
->refs
);
495 TRACE("(%p)->(%d)\n", doc
, ref
);
498 orphan_entry
*orphan
, *orphan2
;
499 TRACE("freeing docptr %p\n", doc
);
501 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
503 xmlFreeNode( orphan
->node
);
506 free_properties(priv
->properties
);
507 heap_free(doc
->_private
);
515 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
517 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
520 entry
= heap_alloc( sizeof (*entry
) );
522 return E_OUTOFMEMORY
;
525 list_add_head( &priv
->orphans
, &entry
->entry
);
529 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
531 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
532 orphan_entry
*entry
, *entry2
;
534 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
536 if( entry
->node
== node
)
538 list_remove( &entry
->entry
);
547 static inline xmlDocPtr
get_doc( domdoc
*This
)
549 return (xmlDocPtr
)This
->node
.node
;
552 static HRESULT
attach_xmldoc(domdoc
*This
, xmlDocPtr xml
)
556 priv_from_xmlDocPtr(get_doc(This
))->properties
= NULL
;
557 if (xmldoc_release(get_doc(This
)) != 0)
558 priv_from_xmlDocPtr(get_doc(This
))->properties
=
559 copy_properties(This
->properties
);
562 This
->node
.node
= (xmlNodePtr
) xml
;
566 xmldoc_add_ref(get_doc(This
));
567 priv_from_xmlDocPtr(get_doc(This
))->properties
= This
->properties
;
573 static inline domdoc
*impl_from_IXMLDOMDocument3( IXMLDOMDocument3
*iface
)
575 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpVtbl
));
578 static inline domdoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
580 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIPersistStreamInit
));
583 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
585 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectWithSite
));
588 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
590 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectSafety
));
593 static inline domdoc
*impl_from_ISupportErrorInfo(ISupportErrorInfo
*iface
)
595 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblISupportErrorInfo
));
598 static inline domdoc
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
600 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpVtblConnectionPointContainer
));
603 /************************************************************************
604 * domdoc implementation of IPersistStream.
606 static HRESULT WINAPI
domdoc_IPersistStreamInit_QueryInterface(
607 IPersistStreamInit
*iface
, REFIID riid
, void **ppvObj
)
609 domdoc
*this = impl_from_IPersistStreamInit(iface
);
610 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2
*)this, riid
, ppvObj
);
613 static ULONG WINAPI
domdoc_IPersistStreamInit_AddRef(
614 IPersistStreamInit
*iface
)
616 domdoc
*this = impl_from_IPersistStreamInit(iface
);
617 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2
*)this);
620 static ULONG WINAPI
domdoc_IPersistStreamInit_Release(
621 IPersistStreamInit
*iface
)
623 domdoc
*this = impl_from_IPersistStreamInit(iface
);
624 return IXMLDOMDocument2_Release((IXMLDOMDocument2
*)this);
627 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetClassID(
628 IPersistStreamInit
*iface
, CLSID
*classid
)
630 TRACE("(%p,%p): stub!\n", iface
, classid
);
635 *classid
= CLSID_DOMDocument2
;
640 static HRESULT WINAPI
domdoc_IPersistStreamInit_IsDirty(
641 IPersistStreamInit
*iface
)
643 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
644 FIXME("(%p): stub!\n", This
);
648 static HRESULT WINAPI
domdoc_IPersistStreamInit_Load(
649 IPersistStreamInit
*iface
, LPSTREAM pStm
)
651 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
654 DWORD read
, written
, len
;
657 xmlDocPtr xmldoc
= NULL
;
659 TRACE("(%p)->(%p)\n", This
, pStm
);
664 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
670 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
671 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
672 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
676 ERR("Failed to copy stream\n");
680 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
684 len
= GlobalSize(hglobal
);
685 ptr
= GlobalLock(hglobal
);
687 xmldoc
= doparse(This
, ptr
, len
, NULL
);
688 GlobalUnlock(hglobal
);
692 ERR("Failed to parse xml\n");
696 xmldoc
->_private
= create_priv();
698 return attach_xmldoc(This
, xmldoc
);
701 static HRESULT WINAPI
domdoc_IPersistStreamInit_Save(
702 IPersistStreamInit
*iface
, IStream
*stream
, BOOL clr_dirty
)
704 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
708 TRACE("(%p)->(%p %d)\n", This
, stream
, clr_dirty
);
710 hr
= IXMLDOMDocument3_get_xml( (IXMLDOMDocument3
*)&This
->lpVtbl
, &xmlString
);
713 DWORD len
= SysStringLen(xmlString
) * sizeof(WCHAR
);
715 hr
= IStream_Write( stream
, xmlString
, len
, NULL
);
716 SysFreeString(xmlString
);
719 TRACE("ret 0x%08x\n", hr
);
724 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetSizeMax(
725 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
727 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
728 TRACE("(%p)->(%p): stub!\n", This
, pcbSize
);
732 static HRESULT WINAPI
domdoc_IPersistStreamInit_InitNew(
733 IPersistStreamInit
*iface
)
735 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
736 TRACE("(%p)\n", This
);
740 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
742 domdoc_IPersistStreamInit_QueryInterface
,
743 domdoc_IPersistStreamInit_AddRef
,
744 domdoc_IPersistStreamInit_Release
,
745 domdoc_IPersistStreamInit_GetClassID
,
746 domdoc_IPersistStreamInit_IsDirty
,
747 domdoc_IPersistStreamInit_Load
,
748 domdoc_IPersistStreamInit_Save
,
749 domdoc_IPersistStreamInit_GetSizeMax
,
750 domdoc_IPersistStreamInit_InitNew
753 /* ISupportErrorInfo interface */
754 static HRESULT WINAPI
support_error_QueryInterface(
755 ISupportErrorInfo
*iface
,
756 REFIID riid
, void** ppvObj
)
758 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
759 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3
*)This
, riid
, ppvObj
);
762 static ULONG WINAPI
support_error_AddRef(
763 ISupportErrorInfo
*iface
)
765 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
766 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
769 static ULONG WINAPI
support_error_Release(
770 ISupportErrorInfo
*iface
)
772 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
773 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
776 static HRESULT WINAPI
support_error_InterfaceSupportsErrorInfo(
777 ISupportErrorInfo
*iface
,
780 FIXME("(%p)->(%s)\n", iface
, debugstr_guid(riid
));
784 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
786 support_error_QueryInterface
,
787 support_error_AddRef
,
788 support_error_Release
,
789 support_error_InterfaceSupportsErrorInfo
792 /* IXMLDOMDocument2 interface */
793 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument3
*iface
, REFIID riid
, void** ppvObject
)
795 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
797 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppvObject
);
801 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
802 IsEqualGUID( riid
, &IID_IDispatch
) ||
803 IsEqualGUID( riid
, &IID_IXMLDOMNode
) ||
804 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
805 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
)||
806 IsEqualGUID( riid
, &IID_IXMLDOMDocument3
))
810 else if (IsEqualGUID(&IID_IPersistStream
, riid
) ||
811 IsEqualGUID(&IID_IPersistStreamInit
, riid
))
813 *ppvObject
= &(This
->lpvtblIPersistStreamInit
);
815 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
817 *ppvObject
= &(This
->lpvtblIObjectWithSite
);
819 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
821 *ppvObject
= &(This
->lpvtblIObjectSafety
);
823 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
825 *ppvObject
= &This
->lpvtblISupportErrorInfo
;
827 else if(node_query_interface(&This
->node
, riid
, ppvObject
))
829 return *ppvObject
? S_OK
: E_NOINTERFACE
;
831 else if (IsEqualGUID( riid
, &IID_IConnectionPointContainer
))
833 *ppvObject
= &This
->lpVtblConnectionPointContainer
;
835 else if(IsEqualGUID(&IID_IRunnableObject
, riid
))
837 TRACE("IID_IRunnableObject not supported returning NULL\n");
838 return E_NOINTERFACE
;
842 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
843 return E_NOINTERFACE
;
846 IUnknown_AddRef((IUnknown
*)*ppvObject
);
852 static ULONG WINAPI
domdoc_AddRef(
853 IXMLDOMDocument3
*iface
)
855 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
856 TRACE("%p\n", This
);
857 return InterlockedIncrement( &This
->ref
);
861 static ULONG WINAPI
domdoc_Release(
862 IXMLDOMDocument3
*iface
)
864 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
867 TRACE("%p\n", This
);
869 ref
= InterlockedDecrement( &This
->ref
);
873 detach_bsc(This
->bsc
);
876 IUnknown_Release( This
->site
);
877 destroy_xmlnode(&This
->node
);
878 if(This
->schema
) IXMLDOMSchemaCollection2_Release(This
->schema
);
879 if (This
->stream
) IStream_Release(This
->stream
);
880 HeapFree( GetProcessHeap(), 0, This
);
886 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument3
*iface
, UINT
* pctinfo
)
888 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
890 TRACE("(%p)->(%p)\n", This
, pctinfo
);
897 static HRESULT WINAPI
domdoc_GetTypeInfo(
898 IXMLDOMDocument3
*iface
,
899 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
901 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
904 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
906 hr
= get_typeinfo(IXMLDOMDocument2_tid
, ppTInfo
);
911 static HRESULT WINAPI
domdoc_GetIDsOfNames(
912 IXMLDOMDocument3
*iface
,
919 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
923 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
926 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
929 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
932 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
933 ITypeInfo_Release(typeinfo
);
940 static HRESULT WINAPI
domdoc_Invoke(
941 IXMLDOMDocument3
*iface
,
946 DISPPARAMS
* pDispParams
,
948 EXCEPINFO
* pExcepInfo
,
951 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
955 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
956 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
958 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
961 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
962 pVarResult
, pExcepInfo
, puArgErr
);
963 ITypeInfo_Release(typeinfo
);
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 FIXME("(%p)->(v%d)\n", This
, V_VT(&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 x%d %p)\n", This
, newChild
, V_VT(&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
,
1138 IXMLDOMNode
* childNode
,
1139 IXMLDOMNode
** oldChild
)
1141 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1142 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This
->node
), childNode
, oldChild
);
1146 static HRESULT WINAPI
domdoc_appendChild(
1147 IXMLDOMDocument3
*iface
,
1148 IXMLDOMNode
* newChild
,
1149 IXMLDOMNode
** outNewChild
)
1151 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1152 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This
->node
), newChild
, outNewChild
);
1156 static HRESULT WINAPI
domdoc_hasChildNodes(
1157 IXMLDOMDocument3
*iface
,
1158 VARIANT_BOOL
* hasChild
)
1160 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1161 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This
->node
), hasChild
);
1165 static HRESULT WINAPI
domdoc_get_ownerDocument(
1166 IXMLDOMDocument3
*iface
,
1167 IXMLDOMDocument
** DOMDocument
)
1169 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1170 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This
->node
), DOMDocument
);
1174 static HRESULT WINAPI
domdoc_cloneNode(
1175 IXMLDOMDocument3
*iface
,
1177 IXMLDOMNode
** outNode
)
1179 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1180 TRACE("(%p)->(%d %p)\n", This
, deep
, outNode
);
1181 return node_clone( &This
->node
, deep
, outNode
);
1185 static HRESULT WINAPI
domdoc_get_nodeTypeString(
1186 IXMLDOMDocument3
*iface
,
1189 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1190 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This
->node
), nodeType
);
1194 static HRESULT WINAPI
domdoc_get_text(
1195 IXMLDOMDocument3
*iface
,
1198 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1199 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This
->node
), text
);
1203 static HRESULT WINAPI
domdoc_put_text(
1204 IXMLDOMDocument3
*iface
,
1207 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1208 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
1213 static HRESULT WINAPI
domdoc_get_specified(
1214 IXMLDOMDocument3
*iface
,
1215 VARIANT_BOOL
* isSpecified
)
1217 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1218 FIXME("(%p)->(%p) stub!\n", This
, isSpecified
);
1219 *isSpecified
= VARIANT_TRUE
;
1224 static HRESULT WINAPI
domdoc_get_definition(
1225 IXMLDOMDocument3
*iface
,
1226 IXMLDOMNode
** definitionNode
)
1228 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1229 FIXME("(%p)->(%p)\n", This
, definitionNode
);
1234 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
1235 IXMLDOMDocument3
*iface
,
1236 VARIANT
* typedValue
)
1238 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1239 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
1242 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
1243 IXMLDOMDocument3
*iface
,
1244 VARIANT typedValue
)
1246 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1247 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
1251 static HRESULT WINAPI
domdoc_get_dataType(
1252 IXMLDOMDocument3
*iface
,
1255 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1256 TRACE("(%p)->(%p)\n", This
, typename
);
1257 return return_null_var( typename
);
1261 static HRESULT WINAPI
domdoc_put_dataType(
1262 IXMLDOMDocument3
*iface
,
1265 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1266 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This
->node
), dataTypeName
);
1270 static HRESULT WINAPI
domdoc_get_xml(
1271 IXMLDOMDocument3
*iface
,
1274 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1276 TRACE("(%p)->(%p)\n", This
, p
);
1278 return node_get_xml(&This
->node
, TRUE
, TRUE
, p
);
1282 static HRESULT WINAPI
domdoc_transformNode(
1283 IXMLDOMDocument3
*iface
,
1284 IXMLDOMNode
* styleSheet
,
1287 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1288 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This
->node
), styleSheet
, xmlString
);
1292 static HRESULT WINAPI
domdoc_selectNodes(
1293 IXMLDOMDocument3
*iface
,
1295 IXMLDOMNodeList
** resultList
)
1297 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1298 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultList
);
1302 static HRESULT WINAPI
domdoc_selectSingleNode(
1303 IXMLDOMDocument3
*iface
,
1305 IXMLDOMNode
** resultNode
)
1307 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1308 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultNode
);
1312 static HRESULT WINAPI
domdoc_get_parsed(
1313 IXMLDOMDocument3
*iface
,
1314 VARIANT_BOOL
* isParsed
)
1316 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1317 FIXME("(%p)->(%p) stub!\n", This
, isParsed
);
1318 *isParsed
= VARIANT_TRUE
;
1323 static HRESULT WINAPI
domdoc_get_namespaceURI(
1324 IXMLDOMDocument3
*iface
,
1325 BSTR
* namespaceURI
)
1327 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1328 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This
->node
), namespaceURI
);
1332 static HRESULT WINAPI
domdoc_get_prefix(
1333 IXMLDOMDocument3
*iface
,
1336 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1337 TRACE("(%p)->(%p)\n", This
, prefix
);
1338 return return_null_bstr( prefix
);
1342 static HRESULT WINAPI
domdoc_get_baseName(
1343 IXMLDOMDocument3
*iface
,
1346 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1347 TRACE("(%p)->(%p)\n", This
, name
);
1348 return return_null_bstr( name
);
1352 static HRESULT WINAPI
domdoc_transformNodeToObject(
1353 IXMLDOMDocument3
*iface
,
1354 IXMLDOMNode
* stylesheet
,
1355 VARIANT outputObject
)
1357 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1358 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This
->node
), stylesheet
, outputObject
);
1362 static HRESULT WINAPI
domdoc_get_doctype(
1363 IXMLDOMDocument3
*iface
,
1364 IXMLDOMDocumentType
** documentType
)
1366 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1367 FIXME("(%p)\n", This
);
1372 static HRESULT WINAPI
domdoc_get_implementation(
1373 IXMLDOMDocument3
*iface
,
1374 IXMLDOMImplementation
** impl
)
1376 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1378 TRACE("(%p)->(%p)\n", This
, impl
);
1381 return E_INVALIDARG
;
1383 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
1388 static HRESULT WINAPI
domdoc_get_documentElement(
1389 IXMLDOMDocument3
*iface
,
1390 IXMLDOMElement
** DOMElement
)
1392 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1393 IXMLDOMNode
*element_node
;
1397 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1400 return E_INVALIDARG
;
1404 root
= xmlDocGetRootElement( get_doc(This
) );
1408 element_node
= create_node( root
);
1409 if(!element_node
) return S_FALSE
;
1411 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (void**)DOMElement
);
1412 IXMLDOMNode_Release(element_node
);
1418 static HRESULT WINAPI
domdoc_put_documentElement(
1419 IXMLDOMDocument3
*iface
,
1420 IXMLDOMElement
* DOMElement
)
1422 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1423 IXMLDOMNode
*elementNode
;
1428 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1430 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1434 xmlNode
= get_node_obj( elementNode
);
1436 FIXME("elementNode is not our object\n");
1440 if(!xmlNode
->node
->parent
)
1441 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1442 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1444 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1445 IXMLDOMNode_Release( elementNode
);
1448 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1454 static HRESULT WINAPI
domdoc_createElement(
1455 IXMLDOMDocument3
*iface
,
1457 IXMLDOMElement
** element
)
1459 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1464 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagname
), element
);
1466 if (!element
|| !tagname
) return E_INVALIDARG
;
1468 V_VT(&type
) = VT_I1
;
1469 V_I1(&type
) = NODE_ELEMENT
;
1471 hr
= IXMLDOMDocument3_createNode(iface
, type
, tagname
, NULL
, &node
);
1474 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMElement
, (void**)element
);
1475 IXMLDOMNode_Release(node
);
1482 static HRESULT WINAPI
domdoc_createDocumentFragment(
1483 IXMLDOMDocument3
*iface
,
1484 IXMLDOMDocumentFragment
** frag
)
1486 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1491 TRACE("(%p)->(%p)\n", This
, frag
);
1493 if (!frag
) return E_INVALIDARG
;
1497 V_VT(&type
) = VT_I1
;
1498 V_I1(&type
) = NODE_DOCUMENT_FRAGMENT
;
1500 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1503 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentFragment
, (void**)frag
);
1504 IXMLDOMNode_Release(node
);
1511 static HRESULT WINAPI
domdoc_createTextNode(
1512 IXMLDOMDocument3
*iface
,
1514 IXMLDOMText
** text
)
1516 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1521 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), text
);
1523 if (!text
) return E_INVALIDARG
;
1527 V_VT(&type
) = VT_I1
;
1528 V_I1(&type
) = NODE_TEXT
;
1530 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1533 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)text
);
1534 IXMLDOMNode_Release(node
);
1535 hr
= IXMLDOMText_put_data(*text
, data
);
1542 static HRESULT WINAPI
domdoc_createComment(
1543 IXMLDOMDocument3
*iface
,
1545 IXMLDOMComment
** comment
)
1547 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1552 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), comment
);
1554 if (!comment
) return E_INVALIDARG
;
1558 V_VT(&type
) = VT_I1
;
1559 V_I1(&type
) = NODE_COMMENT
;
1561 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1564 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)comment
);
1565 IXMLDOMNode_Release(node
);
1566 hr
= IXMLDOMComment_put_data(*comment
, data
);
1573 static HRESULT WINAPI
domdoc_createCDATASection(
1574 IXMLDOMDocument3
*iface
,
1576 IXMLDOMCDATASection
** cdata
)
1578 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1583 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), cdata
);
1585 if (!cdata
) return E_INVALIDARG
;
1589 V_VT(&type
) = VT_I1
;
1590 V_I1(&type
) = NODE_CDATA_SECTION
;
1592 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1595 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)cdata
);
1596 IXMLDOMNode_Release(node
);
1597 hr
= IXMLDOMCDATASection_put_data(*cdata
, data
);
1604 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1605 IXMLDOMDocument3
*iface
,
1608 IXMLDOMProcessingInstruction
** pi
)
1610 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1615 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(target
), debugstr_w(data
), pi
);
1617 if (!pi
) return E_INVALIDARG
;
1621 V_VT(&type
) = VT_I1
;
1622 V_I1(&type
) = NODE_PROCESSING_INSTRUCTION
;
1624 hr
= IXMLDOMDocument3_createNode(iface
, type
, target
, NULL
, &node
);
1629 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1630 node_obj
= get_node_obj(node
);
1631 hr
= node_set_content(node_obj
, data
);
1633 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMProcessingInstruction
, (void**)pi
);
1634 IXMLDOMNode_Release(node
);
1641 static HRESULT WINAPI
domdoc_createAttribute(
1642 IXMLDOMDocument3
*iface
,
1644 IXMLDOMAttribute
** attribute
)
1646 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1651 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), attribute
);
1653 if (!attribute
|| !name
) return E_INVALIDARG
;
1655 V_VT(&type
) = VT_I1
;
1656 V_I1(&type
) = NODE_ATTRIBUTE
;
1658 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1661 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMAttribute
, (void**)attribute
);
1662 IXMLDOMNode_Release(node
);
1669 static HRESULT WINAPI
domdoc_createEntityReference(
1670 IXMLDOMDocument3
*iface
,
1672 IXMLDOMEntityReference
** entityref
)
1674 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1679 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), entityref
);
1681 if (!entityref
) return E_INVALIDARG
;
1685 V_VT(&type
) = VT_I1
;
1686 V_I1(&type
) = NODE_ENTITY_REFERENCE
;
1688 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1691 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMEntityReference
, (void**)entityref
);
1692 IXMLDOMNode_Release(node
);
1699 static HRESULT WINAPI
domdoc_getElementsByTagName(
1700 IXMLDOMDocument3
*iface
,
1702 IXMLDOMNodeList
** resultList
)
1704 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1707 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagName
), resultList
);
1709 if (!tagName
|| !resultList
) return E_INVALIDARG
;
1711 if (tagName
[0] == '*' && tagName
[1] == 0)
1713 static const WCHAR formatallW
[] = {'/','/','*',0};
1714 hr
= queryresult_create((xmlNodePtr
)get_doc(This
), formatallW
, resultList
);
1718 static const WCHAR xpathformat
[] =
1719 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
1720 static const WCHAR closeW
[] = { '\'',']',0 };
1726 length
= lstrlenW(tagName
);
1728 /* without two WCHARs from format specifier */
1729 ptr
= pattern
= heap_alloc(sizeof(xpathformat
) + length
*sizeof(WCHAR
) + sizeof(closeW
));
1731 memcpy(ptr
, xpathformat
, sizeof(xpathformat
));
1732 ptr
+= sizeof(xpathformat
)/sizeof(WCHAR
);
1733 memcpy(ptr
, tagName
, length
*sizeof(WCHAR
));
1735 memcpy(ptr
, closeW
, sizeof(closeW
));
1737 hr
= queryresult_create((xmlNodePtr
)get_doc(This
), pattern
, resultList
);
1744 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1750 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1752 return E_INVALIDARG
;
1759 static HRESULT WINAPI
domdoc_createNode(
1760 IXMLDOMDocument3
*iface
,
1764 IXMLDOMNode
** node
)
1766 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1767 DOMNodeType node_type
;
1769 xmlChar
*xml_name
, *href
;
1772 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1774 if(!node
) return E_INVALIDARG
;
1776 hr
= get_node_type(Type
, &node_type
);
1777 if(FAILED(hr
)) return hr
;
1779 if(namespaceURI
&& namespaceURI
[0] && node_type
!= NODE_ELEMENT
)
1780 FIXME("nodes with namespaces currently not supported.\n");
1782 TRACE("node_type %d\n", node_type
);
1784 /* exit earlier for types that need name */
1788 case NODE_ATTRIBUTE
:
1789 case NODE_ENTITY_REFERENCE
:
1790 case NODE_PROCESSING_INSTRUCTION
:
1791 if (!name
|| *name
== 0) return E_FAIL
;
1796 xml_name
= xmlChar_from_wchar(name
);
1797 /* prevent empty href to be allocated */
1798 href
= namespaceURI
? xmlChar_from_wchar(namespaceURI
) : NULL
;
1804 xmlChar
*local
, *prefix
;
1806 local
= xmlSplitQName2(xml_name
, &prefix
);
1808 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, local
? local
: xml_name
, NULL
);
1810 /* allow to create default namespace xmlns= */
1811 if (local
|| (href
&& *href
))
1813 xmlNsPtr ns
= xmlNewNs(xmlnode
, href
, prefix
);
1814 xmlSetNs(xmlnode
, ns
);
1822 case NODE_ATTRIBUTE
:
1823 xmlnode
= (xmlNodePtr
)xmlNewDocProp(get_doc(This
), xml_name
, NULL
);
1826 xmlnode
= (xmlNodePtr
)xmlNewDocText(get_doc(This
), NULL
);
1828 case NODE_CDATA_SECTION
:
1829 xmlnode
= xmlNewCDataBlock(get_doc(This
), NULL
, 0);
1831 case NODE_ENTITY_REFERENCE
:
1832 xmlnode
= xmlNewReference(get_doc(This
), xml_name
);
1834 case NODE_PROCESSING_INSTRUCTION
:
1835 #ifdef HAVE_XMLNEWDOCPI
1836 xmlnode
= xmlNewDocPI(get_doc(This
), xml_name
, NULL
);
1838 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1843 xmlnode
= xmlNewDocComment(get_doc(This
), NULL
);
1845 case NODE_DOCUMENT_FRAGMENT
:
1846 xmlnode
= xmlNewDocFragment(get_doc(This
));
1848 /* unsupported types */
1850 case NODE_DOCUMENT_TYPE
:
1853 heap_free(xml_name
);
1854 return E_INVALIDARG
;
1856 FIXME("unhandled node type %d\n", node_type
);
1861 *node
= create_node(xmlnode
);
1862 heap_free(xml_name
);
1867 TRACE("created node (%d, %p, %p)\n", node_type
, *node
, xmlnode
);
1868 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1875 static HRESULT WINAPI
domdoc_nodeFromID(
1876 IXMLDOMDocument3
*iface
,
1878 IXMLDOMNode
** node
)
1880 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1881 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(idString
), node
);
1885 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
1890 xmldoc
= doparse(This
, ptr
, len
, NULL
);
1892 xmldoc
->_private
= create_priv();
1893 return attach_xmldoc(This
, xmldoc
);
1899 static HRESULT
doread( domdoc
*This
, LPWSTR filename
)
1904 hr
= bind_url(filename
, domdoc_onDataAvailable
, This
, &bsc
);
1909 detach_bsc(This
->bsc
);
1915 static HRESULT WINAPI
domdoc_load(
1916 IXMLDOMDocument3
*iface
,
1918 VARIANT_BOOL
* isSuccessful
)
1920 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1921 LPWSTR filename
= NULL
;
1922 HRESULT hr
= S_FALSE
;
1923 IXMLDOMDocument3
*pNewDoc
= NULL
;
1924 IStream
*pStream
= NULL
;
1927 TRACE("(%p)->type %d\n", This
, V_VT(&xmlSource
) );
1929 *isSuccessful
= VARIANT_FALSE
;
1931 assert( &This
->node
);
1933 switch( V_VT(&xmlSource
) )
1936 filename
= V_BSTR(&xmlSource
);
1939 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IXMLDOMDocument3
, (void**)&pNewDoc
);
1944 domdoc
*newDoc
= impl_from_IXMLDOMDocument3( pNewDoc
);
1945 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
1946 hr
= attach_xmldoc(This
, xmldoc
);
1949 *isSuccessful
= VARIANT_TRUE
;
1954 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IStream
, (void**)&pStream
);
1957 IPersistStream
*pDocStream
;
1958 hr
= IUnknown_QueryInterface(iface
, &IID_IPersistStream
, (void**)&pDocStream
);
1961 hr
= IPersistStream_Load(pDocStream
, pStream
);
1962 IStream_Release(pStream
);
1965 *isSuccessful
= VARIANT_TRUE
;
1967 TRACE("Using IStream to load Document\n");
1972 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr
);
1977 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr
);
1982 /* ISequentialStream */
1983 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr
, pNewDoc
, V_UNKNOWN(&xmlSource
)->lpVtbl
);
1987 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource
));
1990 TRACE("filename (%s)\n", debugstr_w(filename
));
1994 hr
= doread( This
, filename
);
1997 This
->error
= E_FAIL
;
2000 hr
= This
->error
= S_OK
;
2001 *isSuccessful
= VARIANT_TRUE
;
2005 if(!filename
|| FAILED(hr
)) {
2006 xmldoc
= xmlNewDoc(NULL
);
2007 xmldoc
->_private
= create_priv();
2008 hr
= attach_xmldoc(This
, xmldoc
);
2013 TRACE("ret (%d)\n", hr
);
2019 static HRESULT WINAPI
domdoc_get_readyState(
2020 IXMLDOMDocument3
*iface
,
2023 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2024 FIXME("stub! (%p)->(%p)\n", This
, value
);
2027 return E_INVALIDARG
;
2029 *value
= READYSTATE_COMPLETE
;
2034 static HRESULT WINAPI
domdoc_get_parseError(
2035 IXMLDOMDocument3
*iface
,
2036 IXMLDOMParseError
** errorObj
)
2038 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2039 static const WCHAR err
[] = {'e','r','r','o','r',0};
2040 BSTR error_string
= NULL
;
2042 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
2045 error_string
= SysAllocString(err
);
2047 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
2048 if(!*errorObj
) return E_OUTOFMEMORY
;
2053 static HRESULT WINAPI
domdoc_get_url(
2054 IXMLDOMDocument3
*iface
,
2057 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2058 FIXME("(%p)->(%p)\n", This
, urlString
);
2063 static HRESULT WINAPI
domdoc_get_async(
2064 IXMLDOMDocument3
*iface
,
2065 VARIANT_BOOL
* isAsync
)
2067 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2069 TRACE("(%p)->(%p: %d)\n", This
, isAsync
, This
->async
);
2070 *isAsync
= This
->async
;
2075 static HRESULT WINAPI
domdoc_put_async(
2076 IXMLDOMDocument3
*iface
,
2077 VARIANT_BOOL isAsync
)
2079 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2081 TRACE("(%p)->(%d)\n", This
, isAsync
);
2082 This
->async
= isAsync
;
2087 static HRESULT WINAPI
domdoc_abort(
2088 IXMLDOMDocument3
*iface
)
2090 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2091 FIXME("%p\n", This
);
2096 static BOOL
bstr_to_utf8( BSTR bstr
, char **pstr
, int *plen
)
2101 len
= WideCharToMultiByte( CP_UTF8
, 0, bstr
, -1, NULL
, 0, NULL
, NULL
);
2102 str
= heap_alloc( len
);
2105 WideCharToMultiByte( CP_UTF8
, 0, bstr
, -1, str
, len
, NULL
, NULL
);
2111 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2112 static HRESULT WINAPI
domdoc_loadXML(
2113 IXMLDOMDocument3
*iface
,
2115 VARIANT_BOOL
* isSuccessful
)
2117 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2118 static const xmlChar encoding
[] = "UTF-8";
2119 xmlDocPtr xmldoc
= NULL
;
2120 HRESULT hr
= S_FALSE
, hr2
;
2124 TRACE("(%p)->(%s %p)\n", This
, debugstr_w( bstrXML
), isSuccessful
);
2126 assert ( &This
->node
);
2130 *isSuccessful
= VARIANT_FALSE
;
2132 if ( bstrXML
&& bstr_to_utf8( bstrXML
, &str
, &len
) )
2134 xmldoc
= doparse(This
, str
, len
, encoding
);
2138 This
->error
= E_FAIL
;
2139 TRACE("failed to parse document\n");
2143 hr
= This
->error
= S_OK
;
2144 *isSuccessful
= VARIANT_TRUE
;
2145 TRACE("parsed document %p\n", xmldoc
);
2150 xmldoc
= xmlNewDoc(NULL
);
2152 xmldoc
->_private
= create_priv();
2154 hr2
= attach_xmldoc(This
, xmldoc
);
2161 static int XMLCALL
domdoc_save_writecallback(void *ctx
, const char *buffer
, int len
)
2165 if(!WriteFile(ctx
, buffer
, len
, &written
, NULL
))
2167 WARN("write error\n");
2174 static int XMLCALL
domdoc_save_closecallback(void *ctx
)
2176 return CloseHandle(ctx
) ? 0 : -1;
2179 static int XMLCALL
domdoc_stream_save_writecallback(void *ctx
, const char *buffer
, int len
)
2184 hr
= IStream_Write((IStream
*)ctx
, buffer
, len
, &written
);
2187 WARN("stream write error: 0x%08x\n", hr
);
2194 static int XMLCALL
domdoc_stream_save_closecallback(void *ctx
)
2196 IStream_Release((IStream
*)ctx
);
2200 static HRESULT WINAPI
domdoc_save(
2201 IXMLDOMDocument3
*iface
,
2202 VARIANT destination
)
2204 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2205 xmlSaveCtxtPtr ctx
= NULL
;
2209 TRACE("(%p)->(var(vt %d, %s))\n", This
, V_VT(&destination
),
2210 V_VT(&destination
) == VT_BSTR
? debugstr_w(V_BSTR(&destination
)) : NULL
);
2212 if(V_VT(&destination
) != VT_BSTR
&& V_VT(&destination
) != VT_UNKNOWN
)
2214 FIXME("Unhandled vt %d\n", V_VT(&destination
));
2218 if(V_VT(&destination
) == VT_UNKNOWN
)
2220 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
2221 IXMLDOMDocument2
*document
;
2224 ret
= IUnknown_QueryInterface(pUnk
, &IID_IXMLDOMDocument3
, (void**)&document
);
2227 VARIANT_BOOL success
;
2230 ret
= IXMLDOMDocument3_get_xml(iface
, &xml
);
2233 ret
= IXMLDOMDocument3_loadXML(document
, xml
, &success
);
2237 IXMLDOMDocument3_Release(document
);
2241 ret
= IUnknown_QueryInterface(pUnk
, &IID_IStream
, (void**)&stream
);
2244 ctx
= xmlSaveToIO(domdoc_stream_save_writecallback
,
2245 domdoc_stream_save_closecallback
, stream
, NULL
, XML_SAVE_NO_DECL
);
2249 IStream_Release(stream
);
2256 /* save with file path */
2257 HANDLE handle
= CreateFileW( V_BSTR(&destination
), GENERIC_WRITE
, 0,
2258 NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2259 if( handle
== INVALID_HANDLE_VALUE
)
2261 WARN("failed to create file\n");
2265 /* disable top XML declaration */
2266 ctx
= xmlSaveToIO(domdoc_save_writecallback
, domdoc_save_closecallback
,
2267 handle
, NULL
, XML_SAVE_NO_DECL
);
2270 CloseHandle(handle
);
2275 xmldecl
= xmldoc_unlink_xmldecl(get_doc(This
));
2276 if (xmlSaveDoc(ctx
, get_doc(This
)) == -1) ret
= S_FALSE
;
2277 xmldoc_link_xmldecl(get_doc(This
), xmldecl
);
2279 /* will release resources through close callback */
2285 static HRESULT WINAPI
domdoc_get_validateOnParse(
2286 IXMLDOMDocument3
*iface
,
2287 VARIANT_BOOL
* isValidating
)
2289 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2290 TRACE("(%p)->(%p: %d)\n", This
, isValidating
, This
->validating
);
2291 *isValidating
= This
->validating
;
2296 static HRESULT WINAPI
domdoc_put_validateOnParse(
2297 IXMLDOMDocument3
*iface
,
2298 VARIANT_BOOL isValidating
)
2300 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2301 TRACE("(%p)->(%d)\n", This
, isValidating
);
2302 This
->validating
= isValidating
;
2307 static HRESULT WINAPI
domdoc_get_resolveExternals(
2308 IXMLDOMDocument3
*iface
,
2309 VARIANT_BOOL
* isResolving
)
2311 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2312 TRACE("(%p)->(%p: %d)\n", This
, isResolving
, This
->resolving
);
2313 *isResolving
= This
->resolving
;
2318 static HRESULT WINAPI
domdoc_put_resolveExternals(
2319 IXMLDOMDocument3
*iface
,
2320 VARIANT_BOOL isResolving
)
2322 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2323 TRACE("(%p)->(%d)\n", This
, isResolving
);
2324 This
->resolving
= isResolving
;
2329 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
2330 IXMLDOMDocument3
*iface
,
2331 VARIANT_BOOL
* isPreserving
)
2333 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2334 TRACE("(%p)->(%p: %d)\n", This
, isPreserving
, This
->preserving
);
2335 *isPreserving
= This
->preserving
;
2340 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
2341 IXMLDOMDocument3
*iface
,
2342 VARIANT_BOOL isPreserving
)
2344 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2345 TRACE("(%p)->(%d)\n", This
, isPreserving
);
2346 This
->preserving
= isPreserving
;
2351 static HRESULT WINAPI
domdoc_put_onReadyStateChange(
2352 IXMLDOMDocument3
*iface
,
2353 VARIANT readyStateChangeSink
)
2355 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2356 FIXME("%p\n", This
);
2361 static HRESULT WINAPI
domdoc_put_onDataAvailable(
2362 IXMLDOMDocument3
*iface
,
2363 VARIANT onDataAvailableSink
)
2365 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2366 FIXME("%p\n", This
);
2370 static HRESULT WINAPI
domdoc_put_onTransformNode(
2371 IXMLDOMDocument3
*iface
,
2372 VARIANT onTransformNodeSink
)
2374 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2375 FIXME("%p\n", This
);
2379 static HRESULT WINAPI
domdoc_get_namespaces(
2380 IXMLDOMDocument3
* iface
,
2381 IXMLDOMSchemaCollection
** schemaCollection
)
2383 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2384 FIXME("(%p)->(%p)\n", This
, schemaCollection
);
2388 static HRESULT WINAPI
domdoc_get_schemas(
2389 IXMLDOMDocument3
* iface
,
2392 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2393 HRESULT hr
= S_FALSE
;
2394 IXMLDOMSchemaCollection2
* cur_schema
= This
->schema
;
2396 TRACE("(%p)->(%p)\n", This
, var1
);
2398 VariantInit(var1
); /* Test shows we don't call VariantClear here */
2399 V_VT(var1
) = VT_NULL
;
2403 hr
= IXMLDOMSchemaCollection2_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(var1
));
2405 V_VT(var1
) = VT_DISPATCH
;
2410 static HRESULT WINAPI
domdoc_putref_schemas(
2411 IXMLDOMDocument3
* iface
,
2414 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2415 HRESULT hr
= E_FAIL
;
2416 IXMLDOMSchemaCollection2
* new_schema
= NULL
;
2418 FIXME("(%p): semi-stub\n", This
);
2422 hr
= IUnknown_QueryInterface(V_UNKNOWN(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2426 hr
= IDispatch_QueryInterface(V_DISPATCH(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2435 WARN("Can't get schema from vt %x\n", V_VT(&var1
));
2440 IXMLDOMSchemaCollection2
* old_schema
= InterlockedExchangePointer((void**)&This
->schema
, new_schema
);
2441 if(old_schema
) IXMLDOMSchemaCollection2_Release(old_schema
);
2447 static inline BOOL
is_wellformed(xmlDocPtr doc
)
2449 #ifdef HAVE_XMLDOC_PROPERTIES
2450 return doc
->properties
& XML_DOC_WELLFORMED
;
2452 /* Not a full check, but catches the worst violations */
2456 for (child
= doc
->children
; child
!= NULL
; child
= child
->next
)
2458 switch (child
->type
)
2460 case XML_ELEMENT_NODE
:
2465 case XML_CDATA_SECTION_NODE
:
2477 static void LIBXML2_LOG_CALLBACK
validate_error(void* ctx
, char const* msg
, ...)
2481 LIBXML2_CALLBACK_ERR(domdoc_validateNode
, msg
, ap
);
2485 static void LIBXML2_LOG_CALLBACK
validate_warning(void* ctx
, char const* msg
, ...)
2489 LIBXML2_CALLBACK_WARN(domdoc_validateNode
, msg
, ap
);
2493 static HRESULT WINAPI
domdoc_validateNode(
2494 IXMLDOMDocument3
* iface
,
2496 IXMLDOMParseError
** err
)
2498 domdoc
* This
= impl_from_IXMLDOMDocument3(iface
);
2499 LONG state
, err_code
= 0;
2503 TRACE("(%p)->(%p, %p)\n", This
, node
, err
);
2504 domdoc_get_readyState(iface
, &state
);
2505 if (state
!= READYSTATE_COMPLETE
)
2508 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2515 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2519 if (!get_node_obj(node
)->node
|| get_node_obj(node
)->node
->doc
!= get_doc(This
))
2522 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2526 if (!is_wellformed(get_doc(This
)))
2528 ERR("doc not well-formed");
2530 *err
= create_parseError(E_XML_NOTWF
, NULL
, NULL
, NULL
, 0, 0, 0);
2534 /* DTD validation */
2535 if (get_doc(This
)->intSubset
|| get_doc(This
)->extSubset
)
2537 xmlValidCtxtPtr vctx
= xmlNewValidCtxt();
2538 vctx
->error
= validate_error
;
2539 vctx
->warning
= validate_warning
;
2542 if (!((node
== (IXMLDOMNode
*)iface
)?
2543 xmlValidateDocument(vctx
, get_doc(This
)) :
2544 xmlValidateElement(vctx
, get_doc(This
), get_node_obj(node
)->node
)))
2546 /* TODO: get a real error code here */
2547 TRACE("DTD validation failed\n");
2548 err_code
= E_XML_INVALID
;
2551 xmlFreeValidCtxt(vctx
);
2554 /* Schema validation */
2555 if (hr
== S_OK
&& This
->schema
!= NULL
)
2558 hr
= SchemaCache_validate_tree(This
->schema
, get_node_obj(node
)->node
);
2562 /* TODO: get a real error code here */
2563 TRACE("schema validation failed\n");
2565 err_code
= E_XML_INVALID
;
2569 /* not really OK, just didn't find a schema for the ns */
2576 TRACE("no DTD or schema found\n");
2577 err_code
= E_XML_NODTD
;
2582 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2587 static HRESULT WINAPI
domdoc_validate(
2588 IXMLDOMDocument3
* iface
,
2589 IXMLDOMParseError
** err
)
2591 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2592 TRACE("(%p)->(%p)\n", This
, err
);
2593 return domdoc_validateNode(iface
, (IXMLDOMNode
*)iface
, err
);
2596 static HRESULT WINAPI
domdoc_setProperty(
2597 IXMLDOMDocument3
* iface
,
2601 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2603 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
2605 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2611 V_VT(&varStr
) = VT_EMPTY
;
2612 if (V_VT(&var
) != VT_BSTR
)
2614 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2616 bstr
= V_BSTR(&varStr
);
2619 bstr
= V_BSTR(&var
);
2622 if (lstrcmpiW(bstr
, PropValueXPathW
) == 0)
2623 This
->properties
->XPath
= TRUE
;
2624 else if (lstrcmpiW(bstr
, PropValueXSLPatternW
) == 0)
2625 This
->properties
->XPath
= FALSE
;
2629 VariantClear(&varStr
);
2632 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2637 xmlChar
*pTokBegin
, *pTokEnd
, *pTokInner
;
2638 xmlChar
*nsStr
= (xmlChar
*)This
->properties
->selectNsStr
;
2639 xmlXPathContextPtr ctx
;
2640 struct list
*pNsList
;
2641 select_ns_entry
* pNsEntry
= NULL
;
2643 V_VT(&varStr
) = VT_EMPTY
;
2644 if (V_VT(&var
) != VT_BSTR
)
2646 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2648 bstr
= V_BSTR(&varStr
);
2651 bstr
= V_BSTR(&var
);
2655 pNsList
= &(This
->properties
->selectNsList
);
2656 clear_selectNsList(pNsList
);
2658 nsStr
= xmlChar_from_wchar(bstr
);
2661 TRACE("Setting SelectionNamespaces property to: %s\n", nsStr
);
2663 This
->properties
->selectNsStr
= nsStr
;
2664 This
->properties
->selectNsStr_len
= xmlStrlen(nsStr
);
2667 ctx
= xmlXPathNewContext(This
->node
.node
->doc
);
2670 for (; *pTokBegin
; pTokBegin
= pTokEnd
)
2672 if (pNsEntry
!= NULL
)
2673 memset(pNsEntry
, 0, sizeof(select_ns_entry
));
2675 pNsEntry
= heap_alloc_zero(sizeof(select_ns_entry
));
2677 while (*pTokBegin
== ' ')
2679 pTokEnd
= pTokBegin
;
2680 while (*pTokEnd
!= ' ' && *pTokEnd
!= 0)
2683 if (xmlStrncmp(pTokBegin
, (xmlChar
const*)"xmlns", 5) != 0)
2686 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2687 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2692 if (*pTokBegin
== '=')
2694 /*valid for XSLPattern?*/
2695 FIXME("Setting default xmlns not supported - skipping.\n");
2696 pTokBegin
= pTokEnd
;
2699 else if (*pTokBegin
== ':')
2701 pNsEntry
->prefix
= ++pTokBegin
;
2702 for (pTokInner
= pTokBegin
; pTokInner
!= pTokEnd
&& *pTokInner
!= '='; ++pTokInner
)
2705 if (pTokInner
== pTokEnd
)
2708 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2709 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2713 pNsEntry
->prefix_end
= *pTokInner
;
2717 if (pTokEnd
-pTokInner
> 1 &&
2718 ((*pTokInner
== '\'' && *(pTokEnd
-1) == '\'') ||
2719 (*pTokInner
== '"' && *(pTokEnd
-1) == '"')))
2721 pNsEntry
->href
= ++pTokInner
;
2722 pNsEntry
->href_end
= *(pTokEnd
-1);
2724 list_add_tail(pNsList
, &pNsEntry
->entry
);
2725 /*let libxml figure out if they're valid from here ;)*/
2726 if (xmlXPathRegisterNs(ctx
, pNsEntry
->prefix
, pNsEntry
->href
) != 0)
2735 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2736 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokInner
, pTokEnd
-pTokInner
));
2737 list_add_tail(pNsList
, &pNsEntry
->entry
);
2750 heap_free(pNsEntry
);
2751 xmlXPathFreeContext(ctx
);
2754 VariantClear(&varStr
);
2757 else if (lstrcmpiW(p
, PropertyProhibitDTDW
) == 0 ||
2758 lstrcmpiW(p
, PropertyNewParserW
) == 0)
2761 FIXME("Ignoring property %s, value %d\n", debugstr_w(p
), V_BOOL(&var
));
2765 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2769 static HRESULT WINAPI
domdoc_getProperty(
2770 IXMLDOMDocument3
* iface
,
2774 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2776 TRACE("(%p)->(%p)\n", This
, debugstr_w(p
));
2779 return E_INVALIDARG
;
2781 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2783 V_VT(var
) = VT_BSTR
;
2784 V_BSTR(var
) = This
->properties
->XPath
?
2785 SysAllocString(PropValueXPathW
) :
2786 SysAllocString(PropValueXSLPatternW
);
2787 return V_BSTR(var
) ? S_OK
: E_OUTOFMEMORY
;
2789 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2792 BSTR rebuiltStr
, cur
;
2793 const xmlChar
*nsStr
;
2794 struct list
*pNsList
;
2795 select_ns_entry
* pNsEntry
;
2797 V_VT(var
) = VT_BSTR
;
2798 nsStr
= This
->properties
->selectNsStr
;
2799 pNsList
= &This
->properties
->selectNsList
;
2800 lenA
= This
->properties
->selectNsStr_len
;
2801 lenW
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, NULL
, 0);
2802 rebuiltStr
= heap_alloc(lenW
*sizeof(WCHAR
));
2803 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, rebuiltStr
, lenW
);
2805 /* this is fine because all of the chars that end tokens are ASCII*/
2806 LIST_FOR_EACH_ENTRY(pNsEntry
, pNsList
, select_ns_entry
, entry
)
2808 while (*cur
!= 0) ++cur
;
2809 if (pNsEntry
->prefix_end
)
2811 *cur
= pNsEntry
->prefix_end
;
2812 while (*cur
!= 0) ++cur
;
2815 if (pNsEntry
->href_end
)
2817 *cur
= pNsEntry
->href_end
;
2820 V_BSTR(var
) = SysAllocString(rebuiltStr
);
2821 heap_free(rebuiltStr
);
2825 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2829 static HRESULT WINAPI
domdoc_importNode(
2830 IXMLDOMDocument3
* iface
,
2833 IXMLDOMNode
** clone
)
2835 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2836 FIXME("(%p)->(%p %d %p): stub\n", This
, node
, deep
, clone
);
2840 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl
=
2842 domdoc_QueryInterface
,
2845 domdoc_GetTypeInfoCount
,
2847 domdoc_GetIDsOfNames
,
2849 domdoc_get_nodeName
,
2850 domdoc_get_nodeValue
,
2851 domdoc_put_nodeValue
,
2852 domdoc_get_nodeType
,
2853 domdoc_get_parentNode
,
2854 domdoc_get_childNodes
,
2855 domdoc_get_firstChild
,
2856 domdoc_get_lastChild
,
2857 domdoc_get_previousSibling
,
2858 domdoc_get_nextSibling
,
2859 domdoc_get_attributes
,
2860 domdoc_insertBefore
,
2861 domdoc_replaceChild
,
2864 domdoc_hasChildNodes
,
2865 domdoc_get_ownerDocument
,
2867 domdoc_get_nodeTypeString
,
2870 domdoc_get_specified
,
2871 domdoc_get_definition
,
2872 domdoc_get_nodeTypedValue
,
2873 domdoc_put_nodeTypedValue
,
2874 domdoc_get_dataType
,
2875 domdoc_put_dataType
,
2877 domdoc_transformNode
,
2879 domdoc_selectSingleNode
,
2881 domdoc_get_namespaceURI
,
2883 domdoc_get_baseName
,
2884 domdoc_transformNodeToObject
,
2886 domdoc_get_implementation
,
2887 domdoc_get_documentElement
,
2888 domdoc_put_documentElement
,
2889 domdoc_createElement
,
2890 domdoc_createDocumentFragment
,
2891 domdoc_createTextNode
,
2892 domdoc_createComment
,
2893 domdoc_createCDATASection
,
2894 domdoc_createProcessingInstruction
,
2895 domdoc_createAttribute
,
2896 domdoc_createEntityReference
,
2897 domdoc_getElementsByTagName
,
2901 domdoc_get_readyState
,
2902 domdoc_get_parseError
,
2909 domdoc_get_validateOnParse
,
2910 domdoc_put_validateOnParse
,
2911 domdoc_get_resolveExternals
,
2912 domdoc_put_resolveExternals
,
2913 domdoc_get_preserveWhiteSpace
,
2914 domdoc_put_preserveWhiteSpace
,
2915 domdoc_put_onReadyStateChange
,
2916 domdoc_put_onDataAvailable
,
2917 domdoc_put_onTransformNode
,
2918 domdoc_get_namespaces
,
2920 domdoc_putref_schemas
,
2924 domdoc_validateNode
,
2928 /* IConnectionPointContainer */
2929 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
2930 REFIID riid
, void **ppv
)
2932 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
2933 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3
*)This
, riid
, ppv
);
2936 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
2938 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
2939 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
2942 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
2944 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
2945 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
2948 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
2949 IEnumConnectionPoints
**ppEnum
)
2951 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
2952 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
2956 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
2957 REFIID riid
, IConnectionPoint
**cp
)
2959 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
2960 ConnectionPoint
*iter
;
2962 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), cp
);
2966 for(iter
= This
->cp_list
; iter
; iter
= iter
->next
)
2968 if (IsEqualGUID(iter
->iid
, riid
))
2969 *cp
= (IConnectionPoint
*)&iter
->lpVtblConnectionPoint
;
2974 IConnectionPoint_AddRef(*cp
);
2978 FIXME("unsupported riid %s\n", debugstr_guid(riid
));
2979 return CONNECT_E_NOCONNECTION
;
2983 static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
2985 ConnectionPointContainer_QueryInterface
,
2986 ConnectionPointContainer_AddRef
,
2987 ConnectionPointContainer_Release
,
2988 ConnectionPointContainer_EnumConnectionPoints
,
2989 ConnectionPointContainer_FindConnectionPoint
2992 /* IConnectionPoint */
2993 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
2994 REFIID riid
, void **ppv
)
2996 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
2998 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
3002 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
3003 IsEqualGUID(&IID_IConnectionPoint
, riid
))
3010 IConnectionPoint_AddRef(iface
);
3014 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
3015 return E_NOINTERFACE
;
3018 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
3020 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3021 return IConnectionPointContainer_AddRef(This
->container
);
3024 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
3026 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3027 return IConnectionPointContainer_Release(This
->container
);
3030 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*iid
)
3032 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3034 TRACE("(%p)->(%p)\n", This
, iid
);
3036 if (!iid
) return E_POINTER
;
3042 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
3043 IConnectionPointContainer
**container
)
3045 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3047 TRACE("(%p)->(%p)\n", This
, container
);
3049 if (!container
) return E_POINTER
;
3051 *container
= This
->container
;
3052 IConnectionPointContainer_AddRef(*container
);
3056 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
3059 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3060 FIXME("(%p)->(%p %p): stub\n", This
, pUnkSink
, pdwCookie
);
3064 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD cookie
)
3066 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3068 TRACE("(%p)->(%d)\n", This
, cookie
);
3070 if (cookie
== 0 || cookie
> This
->sinks_size
|| !This
->sinks
[cookie
-1].unk
)
3071 return CONNECT_E_NOCONNECTION
;
3073 IUnknown_Release(This
->sinks
[cookie
-1].unk
);
3074 This
->sinks
[cookie
-1].unk
= NULL
;
3079 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
3080 IEnumConnections
**ppEnum
)
3082 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3083 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3087 static const IConnectionPointVtbl ConnectionPointVtbl
=
3089 ConnectionPoint_QueryInterface
,
3090 ConnectionPoint_AddRef
,
3091 ConnectionPoint_Release
,
3092 ConnectionPoint_GetConnectionInterface
,
3093 ConnectionPoint_GetConnectionPointContainer
,
3094 ConnectionPoint_Advise
,
3095 ConnectionPoint_Unadvise
,
3096 ConnectionPoint_EnumConnections
3099 void ConnectionPoint_Init(ConnectionPoint
*cp
, struct domdoc
*doc
, REFIID riid
)
3101 cp
->lpVtblConnectionPoint
= &ConnectionPointVtbl
;
3107 cp
->next
= doc
->cp_list
;
3110 cp
->container
= (IConnectionPointContainer
*)&doc
->lpVtblConnectionPointContainer
;
3113 /* domdoc implementation of IObjectWithSite */
3114 static HRESULT WINAPI
3115 domdoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
3117 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3118 return IXMLDOMDocument3_QueryInterface( (IXMLDOMDocument3
*)This
, riid
, ppvObject
);
3121 static ULONG WINAPI
domdoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
3123 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3124 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
3127 static ULONG WINAPI
domdoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
3129 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3130 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
3133 static HRESULT WINAPI
domdoc_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
3135 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3137 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
3142 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
3145 static HRESULT WINAPI
domdoc_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
3147 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3149 TRACE("(%p)->(%p)\n", iface
, punk
);
3155 IUnknown_Release( This
->site
);
3162 IUnknown_AddRef( punk
);
3165 IUnknown_Release( This
->site
);
3172 static const IObjectWithSiteVtbl domdocObjectSite
=
3174 domdoc_ObjectWithSite_QueryInterface
,
3175 domdoc_ObjectWithSite_AddRef
,
3176 domdoc_ObjectWithSite_Release
,
3177 domdoc_ObjectWithSite_SetSite
,
3178 domdoc_ObjectWithSite_GetSite
3181 static HRESULT WINAPI
domdoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
3183 domdoc
*This
= impl_from_IObjectSafety(iface
);
3184 return IXMLDOMDocument3_QueryInterface( (IXMLDOMDocument3
*)This
, riid
, ppv
);
3187 static ULONG WINAPI
domdoc_Safety_AddRef(IObjectSafety
*iface
)
3189 domdoc
*This
= impl_from_IObjectSafety(iface
);
3190 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
3193 static ULONG WINAPI
domdoc_Safety_Release(IObjectSafety
*iface
)
3195 domdoc
*This
= impl_from_IObjectSafety(iface
);
3196 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
3199 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
3201 static HRESULT WINAPI
domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3202 DWORD
*supported
, DWORD
*enabled
)
3204 domdoc
*This
= impl_from_IObjectSafety(iface
);
3206 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
3208 if(!supported
|| !enabled
) return E_POINTER
;
3210 *supported
= SAFETY_SUPPORTED_OPTIONS
;
3211 *enabled
= This
->safeopt
;
3216 static HRESULT WINAPI
domdoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3217 DWORD mask
, DWORD enabled
)
3219 domdoc
*This
= impl_from_IObjectSafety(iface
);
3220 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
3222 if ((mask
& ~SAFETY_SUPPORTED_OPTIONS
) != 0)
3225 This
->safeopt
= enabled
& mask
& SAFETY_SUPPORTED_OPTIONS
;
3229 #undef SAFETY_SUPPORTED_OPTIONS
3231 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
3232 domdoc_Safety_QueryInterface
,
3233 domdoc_Safety_AddRef
,
3234 domdoc_Safety_Release
,
3235 domdoc_Safety_GetInterfaceSafetyOptions
,
3236 domdoc_Safety_SetInterfaceSafetyOptions
3239 static const tid_t domdoc_iface_tids
[] = {
3241 IXMLDOMDocument_tid
,
3242 IXMLDOMDocument2_tid
,
3245 static dispex_static_data_t domdoc_dispex
= {
3247 IXMLDOMDocument2_tid
,
3252 HRESULT
DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument3
**document
)
3256 doc
= heap_alloc( sizeof (*doc
) );
3258 return E_OUTOFMEMORY
;
3260 doc
->lpVtbl
= &domdoc_vtbl
;
3261 doc
->lpvtblIPersistStreamInit
= &xmldoc_IPersistStreamInit_VTable
;
3262 doc
->lpvtblIObjectWithSite
= &domdocObjectSite
;
3263 doc
->lpvtblIObjectSafety
= &domdocObjectSafetyVtbl
;
3264 doc
->lpvtblISupportErrorInfo
= &support_error_vtbl
;
3265 doc
->lpVtblConnectionPointContainer
= &ConnectionPointContainerVtbl
;
3267 doc
->async
= VARIANT_TRUE
;
3268 doc
->validating
= 0;
3270 doc
->preserving
= 0;
3271 doc
->properties
= properties_from_xmlDocPtr(xmldoc
);
3278 doc
->cp_list
= NULL
;
3280 /* events connection points */
3281 ConnectionPoint_Init(&doc
->cp_dispatch
, doc
, &IID_IDispatch
);
3282 ConnectionPoint_Init(&doc
->cp_propnotif
, doc
, &IID_IPropertyNotifySink
);
3283 ConnectionPoint_Init(&doc
->cp_domdocevents
, doc
, &DIID_XMLDOMDocumentEvents
);
3285 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IXMLDOMNode
*)&doc
->lpVtbl
, &domdoc_dispex
);
3287 *document
= (IXMLDOMDocument3
*)&doc
->lpVtbl
;
3289 TRACE("returning iface %p\n", *document
);
3293 HRESULT
DOMDocument_create(const GUID
*clsid
, IUnknown
*pUnkOuter
, void **ppObj
)
3298 TRACE("(%s, %p, %p)\n", debugstr_guid(clsid
), pUnkOuter
, ppObj
);
3300 xmldoc
= xmlNewDoc(NULL
);
3302 return E_OUTOFMEMORY
;
3304 xmldoc
->_private
= create_priv();
3305 priv_from_xmlDocPtr(xmldoc
)->properties
= create_properties(clsid
);
3307 hr
= DOMDocument_create_from_xmldoc(xmldoc
, (IXMLDOMDocument3
**)ppObj
);
3310 free_properties(properties_from_xmlDocPtr(xmldoc
));
3311 heap_free(xmldoc
->_private
);
3319 IUnknown
* create_domdoc( xmlNodePtr document
)
3324 TRACE("(%p)\n", document
);
3326 hr
= DOMDocument_create_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument3
**)&pObj
);
3335 HRESULT
DOMDocument_create(const GUID
*clsid
, IUnknown
*pUnkOuter
, void **ppObj
)
3337 MESSAGE("This program tried to use a DOMDocument object, but\n"
3338 "libxml2 support was not present at compile time.\n");