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 /* Anything that passes the test_get_ownerDocument()
74 * tests can go here (data shared between all instances).
75 * We need to preserve this when reloading a document,
76 * and also need access to it from the libxml backend. */
77 typedef struct _domdoc_properties
{
78 VARIANT_BOOL preserving
;
79 IXMLDOMSchemaCollection2
* schemaCache
;
80 struct list selectNsList
;
81 xmlChar
const* selectNsStr
;
86 typedef struct ConnectionPoint ConnectionPoint
;
87 typedef struct domdoc domdoc
;
89 struct ConnectionPoint
91 const IConnectionPointVtbl
*lpVtblConnectionPoint
;
94 ConnectionPoint
*next
;
95 IConnectionPointContainer
*container
;
102 IPropertyNotifySink
*propnotif
;
110 const struct IXMLDOMDocument3Vtbl
*lpVtbl
;
111 const struct IPersistStreamInitVtbl
*lpvtblIPersistStreamInit
;
112 const struct IObjectWithSiteVtbl
*lpvtblIObjectWithSite
;
113 const struct IObjectSafetyVtbl
*lpvtblIObjectSafety
;
114 const struct ISupportErrorInfoVtbl
*lpvtblISupportErrorInfo
;
115 const struct IConnectionPointContainerVtbl
*lpVtblConnectionPointContainer
;
118 VARIANT_BOOL validating
;
119 VARIANT_BOOL resolving
;
120 domdoc_properties
* properties
;
133 /* connection list */
134 ConnectionPoint
*cp_list
;
135 ConnectionPoint cp_domdocevents
;
136 ConnectionPoint cp_propnotif
;
137 ConnectionPoint cp_dispatch
;
140 static inline ConnectionPoint
*impl_from_IConnectionPoint(IConnectionPoint
*iface
)
142 return (ConnectionPoint
*)((char*)iface
- FIELD_OFFSET(ConnectionPoint
, lpVtblConnectionPoint
));
146 In native windows, the whole lifetime management of XMLDOMNodes is
147 managed automatically using reference counts. Wine emulates that by
148 maintaining a reference count to the document that is increased for
149 each IXMLDOMNode pointer passed out for this document. If all these
150 pointers are gone, the document is unreachable and gets freed, that
151 is, all nodes in the tree of the document get freed.
153 You are able to create nodes that are associated to a document (in
154 fact, in msxml's XMLDOM model, all nodes are associated to a document),
155 but not in the tree of that document, for example using the createFoo
156 functions from IXMLDOMDocument. These nodes do not get cleaned up
157 by libxml, so we have to do it ourselves.
159 To catch these nodes, a list of "orphan nodes" is introduced.
160 It contains pointers to all roots of node trees that are
161 associated with the document without being part of the document
162 tree. All nodes with parent==NULL (except for the document root nodes)
163 should be in the orphan node list of their document. All orphan nodes
164 get freed together with the document itself.
167 typedef struct _xmldoc_priv
{
170 domdoc_properties
* properties
;
173 typedef struct _orphan_entry
{
178 typedef struct _select_ns_entry
{
180 xmlChar
const* prefix
;
186 static inline xmldoc_priv
* priv_from_xmlDocPtr(const xmlDocPtr doc
)
188 return doc
->_private
;
191 static inline domdoc_properties
* properties_from_xmlDocPtr(xmlDocPtr doc
)
193 return priv_from_xmlDocPtr(doc
)->properties
;
196 BOOL
is_xpathmode(const xmlDocPtr doc
)
198 return properties_from_xmlDocPtr(doc
)->XPath
;
201 void set_xpathmode(xmlDocPtr doc
, BOOL xpath
)
203 properties_from_xmlDocPtr(doc
)->XPath
= xpath
;
206 int registerNamespaces(xmlXPathContextPtr ctxt
)
209 const select_ns_entry
* ns
= NULL
;
210 const struct list
* pNsList
= &properties_from_xmlDocPtr(ctxt
->doc
)->selectNsList
;
212 TRACE("(%p)\n", ctxt
);
214 LIST_FOR_EACH_ENTRY( ns
, pNsList
, select_ns_entry
, entry
)
216 xmlXPathRegisterNs(ctxt
, ns
->prefix
, ns
->href
);
223 static inline void clear_selectNsList(struct list
* pNsList
)
225 select_ns_entry
*ns
, *ns2
;
226 LIST_FOR_EACH_ENTRY_SAFE( ns
, ns2
, pNsList
, select_ns_entry
, entry
)
233 static xmldoc_priv
* create_priv(void)
236 priv
= heap_alloc( sizeof (*priv
) );
241 list_init( &priv
->orphans
);
242 priv
->properties
= NULL
;
248 static domdoc_properties
* create_properties(const GUID
*clsid
)
250 domdoc_properties
*properties
= heap_alloc(sizeof(domdoc_properties
));
252 list_init( &properties
->selectNsList
);
253 properties
->preserving
= VARIANT_FALSE
;
254 properties
->schemaCache
= NULL
;
255 properties
->selectNsStr
= heap_alloc_zero(sizeof(xmlChar
));
256 properties
->selectNsStr_len
= 0;
258 /* properties that are dependent on object versions */
259 if (IsEqualCLSID( clsid
, &CLSID_DOMDocument40
) ||
260 IsEqualCLSID( clsid
, &CLSID_DOMDocument60
))
262 properties
->XPath
= TRUE
;
266 properties
->XPath
= FALSE
;
272 static domdoc_properties
* copy_properties(domdoc_properties
const* properties
)
274 domdoc_properties
* pcopy
= heap_alloc(sizeof(domdoc_properties
));
275 select_ns_entry
const* ns
= NULL
;
276 select_ns_entry
* new_ns
= NULL
;
277 int len
= (properties
->selectNsStr_len
+1)*sizeof(xmlChar
);
282 pcopy
->preserving
= properties
->preserving
;
283 pcopy
->schemaCache
= properties
->schemaCache
;
284 pcopy
->XPath
= properties
->XPath
;
285 pcopy
->selectNsStr_len
= properties
->selectNsStr_len
;
286 list_init( &pcopy
->selectNsList
);
287 pcopy
->selectNsStr
= heap_alloc(len
);
288 memcpy((xmlChar
*)pcopy
->selectNsStr
, properties
->selectNsStr
, len
);
289 offset
= pcopy
->selectNsStr
- properties
->selectNsStr
;
291 LIST_FOR_EACH_ENTRY( ns
, (&properties
->selectNsList
), select_ns_entry
, entry
)
293 new_ns
= heap_alloc(sizeof(select_ns_entry
));
294 memcpy(new_ns
, ns
, sizeof(select_ns_entry
));
295 new_ns
->href
+= offset
;
296 new_ns
->prefix
+= offset
;
297 list_add_tail(&pcopy
->selectNsList
, &new_ns
->entry
);
305 static void free_properties(domdoc_properties
* properties
)
309 if (properties
->schemaCache
)
310 IXMLDOMSchemaCollection2_Release(properties
->schemaCache
);
311 clear_selectNsList(&properties
->selectNsList
);
312 heap_free((xmlChar
*)properties
->selectNsStr
);
313 heap_free(properties
);
317 static BOOL
xmldoc_has_decl(xmlDocPtr doc
)
319 return doc
->children
&& (xmlStrEqual(doc
->children
->name
, (xmlChar
*)"xml") == 1);
322 /* links a "<?xml" node as a first child */
323 void xmldoc_link_xmldecl(xmlDocPtr doc
, xmlNodePtr node
)
326 if (doc
->standalone
!= -1) xmlAddPrevSibling( doc
->children
, node
);
329 /* unlinks a first "<?xml" child if it was created */
330 xmlNodePtr
xmldoc_unlink_xmldecl(xmlDocPtr doc
)
336 if (doc
->standalone
!= -1)
338 node
= doc
->children
;
339 xmlUnlinkNode( node
);
347 BOOL
is_preserving_whitespace(xmlNodePtr node
)
349 domdoc_properties
* properties
= NULL
;
350 /* during parsing the xmlDoc._private stuff is not there */
351 if (priv_from_xmlDocPtr(node
->doc
))
352 properties
= properties_from_xmlDocPtr(node
->doc
);
353 return ((properties
&& properties
->preserving
== VARIANT_TRUE
) ||
354 xmlNodeGetSpacePreserve(node
) == 1);
357 static inline BOOL
strn_isspace(xmlChar
const* str
, int len
)
359 for (; str
&& len
> 0 && *str
; ++str
, --len
)
366 static void sax_characters(void *ctx
, const xmlChar
*ch
, int len
)
368 xmlParserCtxtPtr pctx
;
371 pctx
= (xmlParserCtxtPtr
) ctx
;
372 This
= (domdoc
const*) pctx
->_private
;
374 /* during domdoc_loadXML() the xmlDocPtr->_private data is not available */
375 if (!This
->properties
->preserving
&&
376 !is_preserving_whitespace(pctx
->node
) &&
377 strn_isspace(ch
, len
))
380 xmlSAX2Characters(ctx
, ch
, len
);
383 static void LIBXML2_LOG_CALLBACK
sax_error(void* ctx
, char const* msg
, ...)
387 LIBXML2_CALLBACK_ERR(doparse
, msg
, ap
);
391 static void LIBXML2_LOG_CALLBACK
sax_warning(void* ctx
, char const* msg
, ...)
395 LIBXML2_CALLBACK_WARN(doparse
, msg
, ap
);
399 static void sax_serror(void* ctx
, xmlErrorPtr err
)
401 LIBXML2_CALLBACK_SERROR(doparse
, err
);
404 static xmlDocPtr
doparse(domdoc
* This
, char *ptr
, int len
, xmlChar
const* encoding
)
406 xmlDocPtr doc
= NULL
;
407 xmlParserCtxtPtr pctx
;
408 static xmlSAXHandler sax_handler
= {
409 xmlSAX2InternalSubset
, /* internalSubset */
410 xmlSAX2IsStandalone
, /* isStandalone */
411 xmlSAX2HasInternalSubset
, /* hasInternalSubset */
412 xmlSAX2HasExternalSubset
, /* hasExternalSubset */
413 xmlSAX2ResolveEntity
, /* resolveEntity */
414 xmlSAX2GetEntity
, /* getEntity */
415 xmlSAX2EntityDecl
, /* entityDecl */
416 xmlSAX2NotationDecl
, /* notationDecl */
417 xmlSAX2AttributeDecl
, /* attributeDecl */
418 xmlSAX2ElementDecl
, /* elementDecl */
419 xmlSAX2UnparsedEntityDecl
, /* unparsedEntityDecl */
420 xmlSAX2SetDocumentLocator
, /* setDocumentLocator */
421 xmlSAX2StartDocument
, /* startDocument */
422 xmlSAX2EndDocument
, /* endDocument */
423 xmlSAX2StartElement
, /* startElement */
424 xmlSAX2EndElement
, /* endElement */
425 xmlSAX2Reference
, /* reference */
426 sax_characters
, /* characters */
427 sax_characters
, /* ignorableWhitespace */
428 xmlSAX2ProcessingInstruction
, /* processingInstruction */
429 xmlSAX2Comment
, /* comment */
430 sax_warning
, /* warning */
431 sax_error
, /* error */
432 sax_error
, /* fatalError */
433 xmlSAX2GetParameterEntity
, /* getParameterEntity */
434 xmlSAX2CDataBlock
, /* cdataBlock */
435 xmlSAX2ExternalSubset
, /* externalSubset */
438 xmlSAX2StartElementNs
, /* startElementNs */
439 xmlSAX2EndElementNs
, /* endElementNs */
440 sax_serror
/* serror */
444 pctx
= xmlCreateMemoryParserCtxt(ptr
, len
);
447 ERR("Failed to create parser context\n");
451 if (pctx
->sax
) xmlFree(pctx
->sax
);
452 pctx
->sax
= &sax_handler
;
453 pctx
->_private
= This
;
455 pctx
->encoding
= xmlStrdup(encoding
);
456 xmlParseDocument(pctx
);
458 if (pctx
->wellFormed
)
464 xmlFreeDoc(pctx
->myDoc
);
468 xmlFreeParserCtxt(pctx
);
470 /* TODO: put this in one of the SAX callbacks */
471 /* create first child as a <?xml...?> */
472 if (doc
&& doc
->standalone
!= -1)
476 xmlChar
*xmlbuff
= (xmlChar
*)buff
;
478 node
= xmlNewDocPI( doc
, (xmlChar
*)"xml", NULL
);
480 /* version attribute can't be omitted */
481 sprintf(buff
, "version=\"%s\"", doc
->version
? (char*)doc
->version
: "1.0");
482 xmlNodeAddContent( node
, xmlbuff
);
486 sprintf(buff
, " encoding=\"%s\"", doc
->encoding
);
487 xmlNodeAddContent( node
, xmlbuff
);
490 if (doc
->standalone
!= -2)
492 sprintf(buff
, " standalone=\"%s\"", doc
->standalone
== 0 ? "no" : "yes");
493 xmlNodeAddContent( node
, xmlbuff
);
496 xmldoc_link_xmldecl( doc
, node
);
502 void xmldoc_init(xmlDocPtr doc
, const GUID
*clsid
)
504 doc
->_private
= create_priv();
505 priv_from_xmlDocPtr(doc
)->properties
= create_properties(clsid
);
508 LONG
xmldoc_add_ref(xmlDocPtr doc
)
510 LONG ref
= InterlockedIncrement(&priv_from_xmlDocPtr(doc
)->refs
);
511 TRACE("(%p)->(%d)\n", doc
, ref
);
515 LONG
xmldoc_release(xmlDocPtr doc
)
517 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
518 LONG ref
= InterlockedDecrement(&priv
->refs
);
519 TRACE("(%p)->(%d)\n", doc
, ref
);
522 orphan_entry
*orphan
, *orphan2
;
523 TRACE("freeing docptr %p\n", doc
);
525 LIST_FOR_EACH_ENTRY_SAFE( orphan
, orphan2
, &priv
->orphans
, orphan_entry
, entry
)
527 xmlFreeNode( orphan
->node
);
530 free_properties(priv
->properties
);
531 heap_free(doc
->_private
);
539 HRESULT
xmldoc_add_orphan(xmlDocPtr doc
, xmlNodePtr node
)
541 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
544 entry
= heap_alloc( sizeof (*entry
) );
546 return E_OUTOFMEMORY
;
549 list_add_head( &priv
->orphans
, &entry
->entry
);
553 HRESULT
xmldoc_remove_orphan(xmlDocPtr doc
, xmlNodePtr node
)
555 xmldoc_priv
*priv
= priv_from_xmlDocPtr(doc
);
556 orphan_entry
*entry
, *entry2
;
558 LIST_FOR_EACH_ENTRY_SAFE( entry
, entry2
, &priv
->orphans
, orphan_entry
, entry
)
560 if( entry
->node
== node
)
562 list_remove( &entry
->entry
);
571 static inline xmlDocPtr
get_doc( domdoc
*This
)
573 return (xmlDocPtr
)This
->node
.node
;
576 static HRESULT
attach_xmldoc(domdoc
*This
, xmlDocPtr xml
)
580 priv_from_xmlDocPtr(get_doc(This
))->properties
= NULL
;
581 if (xmldoc_release(get_doc(This
)) != 0)
582 priv_from_xmlDocPtr(get_doc(This
))->properties
=
583 copy_properties(This
->properties
);
586 This
->node
.node
= (xmlNodePtr
) xml
;
590 xmldoc_add_ref(get_doc(This
));
591 priv_from_xmlDocPtr(get_doc(This
))->properties
= This
->properties
;
597 static inline domdoc
*impl_from_IXMLDOMDocument3( IXMLDOMDocument3
*iface
)
599 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpVtbl
));
602 static inline domdoc
*impl_from_IPersistStreamInit(IPersistStreamInit
*iface
)
604 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIPersistStreamInit
));
607 static inline domdoc
*impl_from_IObjectWithSite(IObjectWithSite
*iface
)
609 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectWithSite
));
612 static inline domdoc
*impl_from_IObjectSafety(IObjectSafety
*iface
)
614 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblIObjectSafety
));
617 static inline domdoc
*impl_from_ISupportErrorInfo(ISupportErrorInfo
*iface
)
619 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpvtblISupportErrorInfo
));
622 static inline domdoc
*impl_from_IConnectionPointContainer(IConnectionPointContainer
*iface
)
624 return (domdoc
*)((char*)iface
- FIELD_OFFSET(domdoc
, lpVtblConnectionPointContainer
));
627 /************************************************************************
628 * domdoc implementation of IPersistStream.
630 static HRESULT WINAPI
domdoc_IPersistStreamInit_QueryInterface(
631 IPersistStreamInit
*iface
, REFIID riid
, void **ppvObj
)
633 domdoc
*this = impl_from_IPersistStreamInit(iface
);
634 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2
*)this, riid
, ppvObj
);
637 static ULONG WINAPI
domdoc_IPersistStreamInit_AddRef(
638 IPersistStreamInit
*iface
)
640 domdoc
*this = impl_from_IPersistStreamInit(iface
);
641 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2
*)this);
644 static ULONG WINAPI
domdoc_IPersistStreamInit_Release(
645 IPersistStreamInit
*iface
)
647 domdoc
*this = impl_from_IPersistStreamInit(iface
);
648 return IXMLDOMDocument2_Release((IXMLDOMDocument2
*)this);
651 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetClassID(
652 IPersistStreamInit
*iface
, CLSID
*classid
)
654 TRACE("(%p,%p): stub!\n", iface
, classid
);
659 *classid
= CLSID_DOMDocument2
;
664 static HRESULT WINAPI
domdoc_IPersistStreamInit_IsDirty(
665 IPersistStreamInit
*iface
)
667 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
668 FIXME("(%p): stub!\n", This
);
672 static HRESULT WINAPI
domdoc_IPersistStreamInit_Load(
673 IPersistStreamInit
*iface
, LPSTREAM pStm
)
675 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
678 DWORD read
, written
, len
;
681 xmlDocPtr xmldoc
= NULL
;
683 TRACE("(%p)->(%p)\n", This
, pStm
);
688 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &This
->stream
);
694 IStream_Read(pStm
, buf
, sizeof(buf
), &read
);
695 hr
= IStream_Write(This
->stream
, buf
, read
, &written
);
696 } while(SUCCEEDED(hr
) && written
!= 0 && read
!= 0);
700 ERR("Failed to copy stream\n");
704 hr
= GetHGlobalFromStream(This
->stream
, &hglobal
);
708 len
= GlobalSize(hglobal
);
709 ptr
= GlobalLock(hglobal
);
711 xmldoc
= doparse(This
, ptr
, len
, NULL
);
712 GlobalUnlock(hglobal
);
716 ERR("Failed to parse xml\n");
720 xmldoc
->_private
= create_priv();
722 return attach_xmldoc(This
, xmldoc
);
725 static HRESULT WINAPI
domdoc_IPersistStreamInit_Save(
726 IPersistStreamInit
*iface
, IStream
*stream
, BOOL clr_dirty
)
728 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
732 TRACE("(%p)->(%p %d)\n", This
, stream
, clr_dirty
);
734 hr
= IXMLDOMDocument3_get_xml( (IXMLDOMDocument3
*)&This
->lpVtbl
, &xmlString
);
737 DWORD len
= SysStringLen(xmlString
) * sizeof(WCHAR
);
739 hr
= IStream_Write( stream
, xmlString
, len
, NULL
);
740 SysFreeString(xmlString
);
743 TRACE("ret 0x%08x\n", hr
);
748 static HRESULT WINAPI
domdoc_IPersistStreamInit_GetSizeMax(
749 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
)
751 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
752 TRACE("(%p)->(%p): stub!\n", This
, pcbSize
);
756 static HRESULT WINAPI
domdoc_IPersistStreamInit_InitNew(
757 IPersistStreamInit
*iface
)
759 domdoc
*This
= impl_from_IPersistStreamInit(iface
);
760 TRACE("(%p)\n", This
);
764 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable
=
766 domdoc_IPersistStreamInit_QueryInterface
,
767 domdoc_IPersistStreamInit_AddRef
,
768 domdoc_IPersistStreamInit_Release
,
769 domdoc_IPersistStreamInit_GetClassID
,
770 domdoc_IPersistStreamInit_IsDirty
,
771 domdoc_IPersistStreamInit_Load
,
772 domdoc_IPersistStreamInit_Save
,
773 domdoc_IPersistStreamInit_GetSizeMax
,
774 domdoc_IPersistStreamInit_InitNew
777 /* ISupportErrorInfo interface */
778 static HRESULT WINAPI
support_error_QueryInterface(
779 ISupportErrorInfo
*iface
,
780 REFIID riid
, void** ppvObj
)
782 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
783 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3
*)This
, riid
, ppvObj
);
786 static ULONG WINAPI
support_error_AddRef(
787 ISupportErrorInfo
*iface
)
789 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
790 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
793 static ULONG WINAPI
support_error_Release(
794 ISupportErrorInfo
*iface
)
796 domdoc
*This
= impl_from_ISupportErrorInfo(iface
);
797 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
800 static HRESULT WINAPI
support_error_InterfaceSupportsErrorInfo(
801 ISupportErrorInfo
*iface
,
804 FIXME("(%p)->(%s)\n", iface
, debugstr_guid(riid
));
808 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
810 support_error_QueryInterface
,
811 support_error_AddRef
,
812 support_error_Release
,
813 support_error_InterfaceSupportsErrorInfo
816 /* IXMLDOMDocument2 interface */
817 static HRESULT WINAPI
domdoc_QueryInterface( IXMLDOMDocument3
*iface
, REFIID riid
, void** ppvObject
)
819 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
821 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( riid
), ppvObject
);
825 if ( IsEqualGUID( riid
, &IID_IUnknown
) ||
826 IsEqualGUID( riid
, &IID_IDispatch
) ||
827 IsEqualGUID( riid
, &IID_IXMLDOMNode
) ||
828 IsEqualGUID( riid
, &IID_IXMLDOMDocument
) ||
829 IsEqualGUID( riid
, &IID_IXMLDOMDocument2
)||
830 IsEqualGUID( riid
, &IID_IXMLDOMDocument3
))
834 else if (IsEqualGUID(&IID_IPersistStream
, riid
) ||
835 IsEqualGUID(&IID_IPersistStreamInit
, riid
))
837 *ppvObject
= &(This
->lpvtblIPersistStreamInit
);
839 else if (IsEqualGUID(&IID_IObjectWithSite
, riid
))
841 *ppvObject
= &(This
->lpvtblIObjectWithSite
);
843 else if (IsEqualGUID(&IID_IObjectSafety
, riid
))
845 *ppvObject
= &(This
->lpvtblIObjectSafety
);
847 else if( IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
849 *ppvObject
= &This
->lpvtblISupportErrorInfo
;
851 else if(node_query_interface(&This
->node
, riid
, ppvObject
))
853 return *ppvObject
? S_OK
: E_NOINTERFACE
;
855 else if (IsEqualGUID( riid
, &IID_IConnectionPointContainer
))
857 *ppvObject
= &This
->lpVtblConnectionPointContainer
;
859 else if(IsEqualGUID(&IID_IRunnableObject
, riid
))
861 TRACE("IID_IRunnableObject not supported returning NULL\n");
862 return E_NOINTERFACE
;
866 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
867 return E_NOINTERFACE
;
870 IUnknown_AddRef((IUnknown
*)*ppvObject
);
876 static ULONG WINAPI
domdoc_AddRef(
877 IXMLDOMDocument3
*iface
)
879 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
880 ULONG ref
= InterlockedIncrement( &This
->ref
);
881 TRACE("(%p)->(%d)\n", This
, ref
);
886 static ULONG WINAPI
domdoc_Release(
887 IXMLDOMDocument3
*iface
)
889 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
890 LONG ref
= InterlockedDecrement( &This
->ref
);
892 TRACE("(%p)->(%d)\n", This
, ref
);
897 detach_bsc(This
->bsc
);
900 IUnknown_Release( This
->site
);
901 destroy_xmlnode(&This
->node
);
903 IStream_Release(This
->stream
);
910 static HRESULT WINAPI
domdoc_GetTypeInfoCount( IXMLDOMDocument3
*iface
, UINT
* pctinfo
)
912 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
914 TRACE("(%p)->(%p)\n", This
, pctinfo
);
921 static HRESULT WINAPI
domdoc_GetTypeInfo(
922 IXMLDOMDocument3
*iface
,
923 UINT iTInfo
, LCID lcid
, ITypeInfo
** ppTInfo
)
925 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
928 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
930 hr
= get_typeinfo(IXMLDOMDocument2_tid
, ppTInfo
);
935 static HRESULT WINAPI
domdoc_GetIDsOfNames(
936 IXMLDOMDocument3
*iface
,
943 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
947 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
950 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
953 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
956 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
957 ITypeInfo_Release(typeinfo
);
964 static HRESULT WINAPI
domdoc_Invoke(
965 IXMLDOMDocument3
*iface
,
970 DISPPARAMS
* pDispParams
,
972 EXCEPINFO
* pExcepInfo
,
975 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
979 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
980 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
982 hr
= get_typeinfo(IXMLDOMDocument2_tid
, &typeinfo
);
985 hr
= ITypeInfo_Invoke(typeinfo
, &(This
->lpVtbl
), dispIdMember
, wFlags
, pDispParams
,
986 pVarResult
, pExcepInfo
, puArgErr
);
987 ITypeInfo_Release(typeinfo
);
994 static HRESULT WINAPI
domdoc_get_nodeName(
995 IXMLDOMDocument3
*iface
,
998 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1000 static const WCHAR documentW
[] = {'#','d','o','c','u','m','e','n','t',0};
1002 TRACE("(%p)->(%p)\n", This
, name
);
1004 return return_bstr(documentW
, name
);
1008 static HRESULT WINAPI
domdoc_get_nodeValue(
1009 IXMLDOMDocument3
*iface
,
1012 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1014 TRACE("(%p)->(%p)\n", This
, value
);
1017 return E_INVALIDARG
;
1019 V_VT(value
) = VT_NULL
;
1020 V_BSTR(value
) = NULL
; /* tests show that we should do this */
1025 static HRESULT WINAPI
domdoc_put_nodeValue(
1026 IXMLDOMDocument3
*iface
,
1029 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1030 TRACE("(%p)->(v%d)\n", This
, V_VT(&value
));
1035 static HRESULT WINAPI
domdoc_get_nodeType(
1036 IXMLDOMDocument3
*iface
,
1039 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1041 TRACE("(%p)->(%p)\n", This
, type
);
1043 *type
= NODE_DOCUMENT
;
1048 static HRESULT WINAPI
domdoc_get_parentNode(
1049 IXMLDOMDocument3
*iface
,
1050 IXMLDOMNode
** parent
)
1052 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1054 TRACE("(%p)->(%p)\n", This
, parent
);
1056 return node_get_parent(&This
->node
, parent
);
1060 static HRESULT WINAPI
domdoc_get_childNodes(
1061 IXMLDOMDocument3
*iface
,
1062 IXMLDOMNodeList
** childList
)
1064 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1066 TRACE("(%p)->(%p)\n", This
, childList
);
1068 return node_get_child_nodes(&This
->node
, childList
);
1072 static HRESULT WINAPI
domdoc_get_firstChild(
1073 IXMLDOMDocument3
*iface
,
1074 IXMLDOMNode
** firstChild
)
1076 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1078 TRACE("(%p)->(%p)\n", This
, firstChild
);
1080 return node_get_first_child(&This
->node
, firstChild
);
1084 static HRESULT WINAPI
domdoc_get_lastChild(
1085 IXMLDOMDocument3
*iface
,
1086 IXMLDOMNode
** lastChild
)
1088 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1090 TRACE("(%p)->(%p)\n", This
, lastChild
);
1092 return node_get_last_child(&This
->node
, lastChild
);
1096 static HRESULT WINAPI
domdoc_get_previousSibling(
1097 IXMLDOMDocument3
*iface
,
1098 IXMLDOMNode
** previousSibling
)
1100 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1102 TRACE("(%p)->(%p)\n", This
, previousSibling
);
1104 return return_null_node(previousSibling
);
1108 static HRESULT WINAPI
domdoc_get_nextSibling(
1109 IXMLDOMDocument3
*iface
,
1110 IXMLDOMNode
** nextSibling
)
1112 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1114 TRACE("(%p)->(%p)\n", This
, nextSibling
);
1116 return return_null_node(nextSibling
);
1120 static HRESULT WINAPI
domdoc_get_attributes(
1121 IXMLDOMDocument3
*iface
,
1122 IXMLDOMNamedNodeMap
** attributeMap
)
1124 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1126 TRACE("(%p)->(%p)\n", This
, attributeMap
);
1128 return return_null_ptr((void**)attributeMap
);
1132 static HRESULT WINAPI
domdoc_insertBefore(
1133 IXMLDOMDocument3
*iface
,
1134 IXMLDOMNode
* newChild
,
1136 IXMLDOMNode
** outNewChild
)
1138 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1140 TRACE("(%p)->(%p x%d %p)\n", This
, newChild
, V_VT(&refChild
), outNewChild
);
1142 return node_insert_before(&This
->node
, newChild
, &refChild
, outNewChild
);
1146 static HRESULT WINAPI
domdoc_replaceChild(
1147 IXMLDOMDocument3
*iface
,
1148 IXMLDOMNode
* newChild
,
1149 IXMLDOMNode
* oldChild
,
1150 IXMLDOMNode
** outOldChild
)
1152 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1154 TRACE("(%p)->(%p %p %p)\n", This
, newChild
, oldChild
, outOldChild
);
1156 return node_replace_child(&This
->node
, newChild
, oldChild
, outOldChild
);
1160 static HRESULT WINAPI
domdoc_removeChild(
1161 IXMLDOMDocument3
*iface
,
1162 IXMLDOMNode
* childNode
,
1163 IXMLDOMNode
** oldChild
)
1165 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1166 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This
->node
), childNode
, oldChild
);
1170 static HRESULT WINAPI
domdoc_appendChild(
1171 IXMLDOMDocument3
*iface
,
1172 IXMLDOMNode
* newChild
,
1173 IXMLDOMNode
** outNewChild
)
1175 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1176 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This
->node
), newChild
, outNewChild
);
1180 static HRESULT WINAPI
domdoc_hasChildNodes(
1181 IXMLDOMDocument3
*iface
,
1182 VARIANT_BOOL
* hasChild
)
1184 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1185 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This
->node
), hasChild
);
1189 static HRESULT WINAPI
domdoc_get_ownerDocument(
1190 IXMLDOMDocument3
*iface
,
1191 IXMLDOMDocument
** DOMDocument
)
1193 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1194 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This
->node
), DOMDocument
);
1198 static HRESULT WINAPI
domdoc_cloneNode(
1199 IXMLDOMDocument3
*iface
,
1201 IXMLDOMNode
** outNode
)
1203 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1204 TRACE("(%p)->(%d %p)\n", This
, deep
, outNode
);
1205 return node_clone( &This
->node
, deep
, outNode
);
1209 static HRESULT WINAPI
domdoc_get_nodeTypeString(
1210 IXMLDOMDocument3
*iface
,
1213 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1214 static const WCHAR documentW
[] = {'d','o','c','u','m','e','n','t',0};
1216 TRACE("(%p)->(%p)\n", This
, p
);
1218 return return_bstr(documentW
, p
);
1222 static HRESULT WINAPI
domdoc_get_text(
1223 IXMLDOMDocument3
*iface
,
1226 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1227 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This
->node
), text
);
1231 static HRESULT WINAPI
domdoc_put_text(
1232 IXMLDOMDocument3
*iface
,
1235 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1236 TRACE("(%p)->(%s)\n", This
, debugstr_w(text
));
1241 static HRESULT WINAPI
domdoc_get_specified(
1242 IXMLDOMDocument3
*iface
,
1243 VARIANT_BOOL
* isSpecified
)
1245 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1246 FIXME("(%p)->(%p) stub!\n", This
, isSpecified
);
1247 *isSpecified
= VARIANT_TRUE
;
1252 static HRESULT WINAPI
domdoc_get_definition(
1253 IXMLDOMDocument3
*iface
,
1254 IXMLDOMNode
** definitionNode
)
1256 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1257 FIXME("(%p)->(%p)\n", This
, definitionNode
);
1262 static HRESULT WINAPI
domdoc_get_nodeTypedValue(
1263 IXMLDOMDocument3
*iface
,
1264 VARIANT
* typedValue
)
1266 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1267 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
1270 static HRESULT WINAPI
domdoc_put_nodeTypedValue(
1271 IXMLDOMDocument3
*iface
,
1272 VARIANT typedValue
)
1274 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1275 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This
->node
), typedValue
);
1279 static HRESULT WINAPI
domdoc_get_dataType(
1280 IXMLDOMDocument3
*iface
,
1283 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1284 TRACE("(%p)->(%p)\n", This
, typename
);
1285 return return_null_var( typename
);
1289 static HRESULT WINAPI
domdoc_put_dataType(
1290 IXMLDOMDocument3
*iface
,
1293 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1294 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This
->node
), dataTypeName
);
1297 static int XMLCALL
domdoc_get_xml_writecallback(void *ctx
, const char *data
, int len
)
1299 return xmlBufferAdd((xmlBufferPtr
)ctx
, (xmlChar
*)data
, len
) == 0 ? len
: 0;
1302 static HRESULT WINAPI
domdoc_get_xml(
1303 IXMLDOMDocument3
*iface
,
1306 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1307 xmlSaveCtxtPtr ctxt
;
1312 TRACE("(%p)->(%p)\n", This
, p
);
1315 return E_INVALIDARG
;
1319 buf
= xmlBufferCreate();
1321 return E_OUTOFMEMORY
;
1323 options
= xmldoc_has_decl(get_doc(This
)) ? XML_SAVE_NO_DECL
: 0;
1324 options
|= XML_SAVE_FORMAT
;
1325 ctxt
= xmlSaveToIO(domdoc_get_xml_writecallback
, NULL
, buf
, "UTF-8", options
);
1330 return E_OUTOFMEMORY
;
1333 ret
= xmlSaveDoc(ctxt
, get_doc(This
));
1334 /* flushes on close */
1337 TRACE("%ld, len=%d\n", ret
, xmlBufferLength(buf
));
1338 if(ret
!= -1 && xmlBufferLength(buf
) > 0)
1342 content
= bstr_from_xmlChar(xmlBufferContent(buf
));
1343 content
= EnsureCorrectEOL(content
);
1349 *p
= SysAllocStringLen(NULL
, 0);
1354 return *p
? S_OK
: E_OUTOFMEMORY
;
1358 static HRESULT WINAPI
domdoc_transformNode(
1359 IXMLDOMDocument3
*iface
,
1360 IXMLDOMNode
* styleSheet
,
1363 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1364 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This
->node
), styleSheet
, xmlString
);
1368 static HRESULT WINAPI
domdoc_selectNodes(
1369 IXMLDOMDocument3
*iface
,
1371 IXMLDOMNodeList
** resultList
)
1373 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1374 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultList
);
1378 static HRESULT WINAPI
domdoc_selectSingleNode(
1379 IXMLDOMDocument3
*iface
,
1381 IXMLDOMNode
** resultNode
)
1383 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1384 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This
->node
), queryString
, resultNode
);
1388 static HRESULT WINAPI
domdoc_get_parsed(
1389 IXMLDOMDocument3
*iface
,
1390 VARIANT_BOOL
* isParsed
)
1392 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1393 FIXME("(%p)->(%p) stub!\n", This
, isParsed
);
1394 *isParsed
= VARIANT_TRUE
;
1399 static HRESULT WINAPI
domdoc_get_namespaceURI(
1400 IXMLDOMDocument3
*iface
,
1401 BSTR
* namespaceURI
)
1403 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1404 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This
->node
), namespaceURI
);
1408 static HRESULT WINAPI
domdoc_get_prefix(
1409 IXMLDOMDocument3
*iface
,
1412 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1413 TRACE("(%p)->(%p)\n", This
, prefix
);
1414 return return_null_bstr( prefix
);
1418 static HRESULT WINAPI
domdoc_get_baseName(
1419 IXMLDOMDocument3
*iface
,
1422 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1423 TRACE("(%p)->(%p)\n", This
, name
);
1424 return return_null_bstr( name
);
1428 static HRESULT WINAPI
domdoc_transformNodeToObject(
1429 IXMLDOMDocument3
*iface
,
1430 IXMLDOMNode
* stylesheet
,
1431 VARIANT outputObject
)
1433 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1434 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This
->node
), stylesheet
, outputObject
);
1438 static HRESULT WINAPI
domdoc_get_doctype(
1439 IXMLDOMDocument3
*iface
,
1440 IXMLDOMDocumentType
** documentType
)
1442 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1443 FIXME("(%p)\n", This
);
1448 static HRESULT WINAPI
domdoc_get_implementation(
1449 IXMLDOMDocument3
*iface
,
1450 IXMLDOMImplementation
** impl
)
1452 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1454 TRACE("(%p)->(%p)\n", This
, impl
);
1457 return E_INVALIDARG
;
1459 *impl
= (IXMLDOMImplementation
*)create_doc_Implementation();
1464 static HRESULT WINAPI
domdoc_get_documentElement(
1465 IXMLDOMDocument3
*iface
,
1466 IXMLDOMElement
** DOMElement
)
1468 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1469 IXMLDOMNode
*element_node
;
1473 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1476 return E_INVALIDARG
;
1480 root
= xmlDocGetRootElement( get_doc(This
) );
1484 element_node
= create_node( root
);
1485 if(!element_node
) return S_FALSE
;
1487 hr
= IXMLDOMNode_QueryInterface(element_node
, &IID_IXMLDOMElement
, (void**)DOMElement
);
1488 IXMLDOMNode_Release(element_node
);
1494 static HRESULT WINAPI
domdoc_put_documentElement(
1495 IXMLDOMDocument3
*iface
,
1496 IXMLDOMElement
* DOMElement
)
1498 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1499 IXMLDOMNode
*elementNode
;
1504 TRACE("(%p)->(%p)\n", This
, DOMElement
);
1506 hr
= IXMLDOMElement_QueryInterface( DOMElement
, &IID_IXMLDOMNode
, (void**)&elementNode
);
1510 xmlNode
= get_node_obj( elementNode
);
1512 FIXME("elementNode is not our object\n");
1516 if(!xmlNode
->node
->parent
)
1517 if(xmldoc_remove_orphan(xmlNode
->node
->doc
, xmlNode
->node
) != S_OK
)
1518 WARN("%p is not an orphan of %p\n", xmlNode
->node
->doc
, xmlNode
->node
);
1520 oldRoot
= xmlDocSetRootElement( get_doc(This
), xmlNode
->node
);
1521 IXMLDOMNode_Release( elementNode
);
1524 xmldoc_add_orphan(oldRoot
->doc
, oldRoot
);
1530 static HRESULT WINAPI
domdoc_createElement(
1531 IXMLDOMDocument3
*iface
,
1533 IXMLDOMElement
** element
)
1535 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1540 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(tagname
), element
);
1542 if (!element
|| !tagname
) return E_INVALIDARG
;
1544 V_VT(&type
) = VT_I1
;
1545 V_I1(&type
) = NODE_ELEMENT
;
1547 hr
= IXMLDOMDocument3_createNode(iface
, type
, tagname
, NULL
, &node
);
1550 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMElement
, (void**)element
);
1551 IXMLDOMNode_Release(node
);
1558 static HRESULT WINAPI
domdoc_createDocumentFragment(
1559 IXMLDOMDocument3
*iface
,
1560 IXMLDOMDocumentFragment
** frag
)
1562 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1567 TRACE("(%p)->(%p)\n", This
, frag
);
1569 if (!frag
) return E_INVALIDARG
;
1573 V_VT(&type
) = VT_I1
;
1574 V_I1(&type
) = NODE_DOCUMENT_FRAGMENT
;
1576 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1579 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMDocumentFragment
, (void**)frag
);
1580 IXMLDOMNode_Release(node
);
1587 static HRESULT WINAPI
domdoc_createTextNode(
1588 IXMLDOMDocument3
*iface
,
1590 IXMLDOMText
** text
)
1592 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1597 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), text
);
1599 if (!text
) return E_INVALIDARG
;
1603 V_VT(&type
) = VT_I1
;
1604 V_I1(&type
) = NODE_TEXT
;
1606 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1609 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMText
, (void**)text
);
1610 IXMLDOMNode_Release(node
);
1611 hr
= IXMLDOMText_put_data(*text
, data
);
1618 static HRESULT WINAPI
domdoc_createComment(
1619 IXMLDOMDocument3
*iface
,
1621 IXMLDOMComment
** comment
)
1623 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1628 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), comment
);
1630 if (!comment
) return E_INVALIDARG
;
1634 V_VT(&type
) = VT_I1
;
1635 V_I1(&type
) = NODE_COMMENT
;
1637 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1640 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMComment
, (void**)comment
);
1641 IXMLDOMNode_Release(node
);
1642 hr
= IXMLDOMComment_put_data(*comment
, data
);
1649 static HRESULT WINAPI
domdoc_createCDATASection(
1650 IXMLDOMDocument3
*iface
,
1652 IXMLDOMCDATASection
** cdata
)
1654 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1659 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(data
), cdata
);
1661 if (!cdata
) return E_INVALIDARG
;
1665 V_VT(&type
) = VT_I1
;
1666 V_I1(&type
) = NODE_CDATA_SECTION
;
1668 hr
= IXMLDOMDocument3_createNode(iface
, type
, NULL
, NULL
, &node
);
1671 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMCDATASection
, (void**)cdata
);
1672 IXMLDOMNode_Release(node
);
1673 hr
= IXMLDOMCDATASection_put_data(*cdata
, data
);
1680 static HRESULT WINAPI
domdoc_createProcessingInstruction(
1681 IXMLDOMDocument3
*iface
,
1684 IXMLDOMProcessingInstruction
** pi
)
1686 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1691 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(target
), debugstr_w(data
), pi
);
1693 if (!pi
) return E_INVALIDARG
;
1697 V_VT(&type
) = VT_I1
;
1698 V_I1(&type
) = NODE_PROCESSING_INSTRUCTION
;
1700 hr
= IXMLDOMDocument3_createNode(iface
, type
, target
, NULL
, &node
);
1705 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1706 node_obj
= get_node_obj(node
);
1707 hr
= node_set_content(node_obj
, data
);
1709 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMProcessingInstruction
, (void**)pi
);
1710 IXMLDOMNode_Release(node
);
1717 static HRESULT WINAPI
domdoc_createAttribute(
1718 IXMLDOMDocument3
*iface
,
1720 IXMLDOMAttribute
** attribute
)
1722 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1727 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), attribute
);
1729 if (!attribute
|| !name
) return E_INVALIDARG
;
1731 V_VT(&type
) = VT_I1
;
1732 V_I1(&type
) = NODE_ATTRIBUTE
;
1734 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1737 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMAttribute
, (void**)attribute
);
1738 IXMLDOMNode_Release(node
);
1745 static HRESULT WINAPI
domdoc_createEntityReference(
1746 IXMLDOMDocument3
*iface
,
1748 IXMLDOMEntityReference
** entityref
)
1750 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1755 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(name
), entityref
);
1757 if (!entityref
) return E_INVALIDARG
;
1761 V_VT(&type
) = VT_I1
;
1762 V_I1(&type
) = NODE_ENTITY_REFERENCE
;
1764 hr
= IXMLDOMDocument3_createNode(iface
, type
, name
, NULL
, &node
);
1767 IXMLDOMNode_QueryInterface(node
, &IID_IXMLDOMEntityReference
, (void**)entityref
);
1768 IXMLDOMNode_Release(node
);
1774 xmlChar
* tagName_to_XPath(const BSTR tagName
)
1776 xmlChar
*query
, *tmp
;
1777 static const xmlChar mod_pre
[] = "*[local-name()='";
1778 static const xmlChar mod_post
[] = "']";
1779 static const xmlChar prefix
[] = "descendant::";
1780 const WCHAR
*tokBegin
, *tokEnd
;
1783 query
= xmlStrdup(prefix
);
1786 while (tokBegin
&& *tokBegin
)
1791 query
= xmlStrcat(query
, BAD_CAST
"/");
1795 query
= xmlStrcat(query
, BAD_CAST
"*");
1799 query
= xmlStrcat(query
, mod_pre
);
1801 while (*tokEnd
&& *tokEnd
!= '/')
1803 len
= WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, NULL
, 0, NULL
, NULL
);
1804 tmp
= xmlMalloc(len
);
1805 WideCharToMultiByte(CP_UTF8
, 0, tokBegin
, tokEnd
-tokBegin
, (char*)tmp
, len
, NULL
, NULL
);
1806 query
= xmlStrncat(query
, tmp
, len
);
1809 query
= xmlStrcat(query
, mod_post
);
1816 static HRESULT WINAPI
domdoc_getElementsByTagName(
1817 IXMLDOMDocument3
*iface
,
1819 IXMLDOMNodeList
** resultList
)
1821 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1826 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(tagName
), resultList
);
1828 if (!tagName
|| !resultList
) return E_INVALIDARG
;
1830 XPath
= This
->properties
->XPath
;
1831 This
->properties
->XPath
= TRUE
;
1832 query
= tagName_to_XPath(tagName
);
1833 hr
= queryresult_create((xmlNodePtr
)get_doc(This
), query
, resultList
);
1835 This
->properties
->XPath
= XPath
;
1840 static HRESULT
get_node_type(VARIANT Type
, DOMNodeType
* type
)
1846 hr
= VariantChangeType(&tmp
, &Type
, 0, VT_I4
);
1848 return E_INVALIDARG
;
1855 static HRESULT WINAPI
domdoc_createNode(
1856 IXMLDOMDocument3
*iface
,
1860 IXMLDOMNode
** node
)
1862 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
1863 DOMNodeType node_type
;
1865 xmlChar
*xml_name
, *href
;
1868 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_w(name
), debugstr_w(namespaceURI
), node
);
1870 if(!node
) return E_INVALIDARG
;
1872 hr
= get_node_type(Type
, &node_type
);
1873 if(FAILED(hr
)) return hr
;
1875 if(namespaceURI
&& namespaceURI
[0] && node_type
!= NODE_ELEMENT
)
1876 FIXME("nodes with namespaces currently not supported.\n");
1878 TRACE("node_type %d\n", node_type
);
1880 /* exit earlier for types that need name */
1884 case NODE_ATTRIBUTE
:
1885 case NODE_ENTITY_REFERENCE
:
1886 case NODE_PROCESSING_INSTRUCTION
:
1887 if (!name
|| *name
== 0) return E_FAIL
;
1892 xml_name
= xmlChar_from_wchar(name
);
1893 /* prevent empty href to be allocated */
1894 href
= namespaceURI
? xmlChar_from_wchar(namespaceURI
) : NULL
;
1900 xmlChar
*local
, *prefix
;
1902 local
= xmlSplitQName2(xml_name
, &prefix
);
1904 xmlnode
= xmlNewDocNode(get_doc(This
), NULL
, local
? local
: xml_name
, NULL
);
1906 /* allow to create default namespace xmlns= */
1907 if (local
|| (href
&& *href
))
1909 xmlNsPtr ns
= xmlNewNs(xmlnode
, href
, prefix
);
1910 xmlSetNs(xmlnode
, ns
);
1918 case NODE_ATTRIBUTE
:
1919 xmlnode
= (xmlNodePtr
)xmlNewDocProp(get_doc(This
), xml_name
, NULL
);
1922 xmlnode
= (xmlNodePtr
)xmlNewDocText(get_doc(This
), NULL
);
1924 case NODE_CDATA_SECTION
:
1925 xmlnode
= xmlNewCDataBlock(get_doc(This
), NULL
, 0);
1927 case NODE_ENTITY_REFERENCE
:
1928 xmlnode
= xmlNewReference(get_doc(This
), xml_name
);
1930 case NODE_PROCESSING_INSTRUCTION
:
1931 #ifdef HAVE_XMLNEWDOCPI
1932 xmlnode
= xmlNewDocPI(get_doc(This
), xml_name
, NULL
);
1934 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1939 xmlnode
= xmlNewDocComment(get_doc(This
), NULL
);
1941 case NODE_DOCUMENT_FRAGMENT
:
1942 xmlnode
= xmlNewDocFragment(get_doc(This
));
1944 /* unsupported types */
1946 case NODE_DOCUMENT_TYPE
:
1949 heap_free(xml_name
);
1950 return E_INVALIDARG
;
1952 FIXME("unhandled node type %d\n", node_type
);
1957 *node
= create_node(xmlnode
);
1958 heap_free(xml_name
);
1963 TRACE("created node (%d, %p, %p)\n", node_type
, *node
, xmlnode
);
1964 xmldoc_add_orphan(xmlnode
->doc
, xmlnode
);
1971 static HRESULT WINAPI
domdoc_nodeFromID(
1972 IXMLDOMDocument3
*iface
,
1974 IXMLDOMNode
** node
)
1976 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
1977 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(idString
), node
);
1981 static HRESULT
domdoc_onDataAvailable(void *obj
, char *ptr
, DWORD len
)
1986 xmldoc
= doparse(This
, ptr
, len
, NULL
);
1988 xmldoc
->_private
= create_priv();
1989 return attach_xmldoc(This
, xmldoc
);
1995 static HRESULT
doread( domdoc
*This
, LPWSTR filename
)
2000 hr
= bind_url(filename
, domdoc_onDataAvailable
, This
, &bsc
);
2005 detach_bsc(This
->bsc
);
2011 static HRESULT WINAPI
domdoc_load(
2012 IXMLDOMDocument3
*iface
,
2014 VARIANT_BOOL
* isSuccessful
)
2016 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2017 LPWSTR filename
= NULL
;
2018 HRESULT hr
= S_FALSE
;
2019 IXMLDOMDocument3
*pNewDoc
= NULL
;
2020 IStream
*pStream
= NULL
;
2023 TRACE("(%p)->type %d\n", This
, V_VT(&xmlSource
) );
2025 *isSuccessful
= VARIANT_FALSE
;
2027 assert( &This
->node
);
2029 switch( V_VT(&xmlSource
) )
2032 filename
= V_BSTR(&xmlSource
);
2035 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IXMLDOMDocument3
, (void**)&pNewDoc
);
2040 domdoc
*newDoc
= impl_from_IXMLDOMDocument3( pNewDoc
);
2041 xmldoc
= xmlCopyDoc(get_doc(newDoc
), 1);
2042 hr
= attach_xmldoc(This
, xmldoc
);
2045 *isSuccessful
= VARIANT_TRUE
;
2050 hr
= IUnknown_QueryInterface(V_UNKNOWN(&xmlSource
), &IID_IStream
, (void**)&pStream
);
2053 IPersistStream
*pDocStream
;
2054 hr
= IUnknown_QueryInterface(iface
, &IID_IPersistStream
, (void**)&pDocStream
);
2057 hr
= IPersistStream_Load(pDocStream
, pStream
);
2058 IStream_Release(pStream
);
2061 *isSuccessful
= VARIANT_TRUE
;
2063 TRACE("Using IStream to load Document\n");
2068 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr
);
2073 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr
);
2078 /* ISequentialStream */
2079 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr
, pNewDoc
, V_UNKNOWN(&xmlSource
)->lpVtbl
);
2083 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource
));
2086 TRACE("filename (%s)\n", debugstr_w(filename
));
2090 hr
= doread( This
, filename
);
2093 This
->error
= E_FAIL
;
2096 hr
= This
->error
= S_OK
;
2097 *isSuccessful
= VARIANT_TRUE
;
2101 if(!filename
|| FAILED(hr
)) {
2102 xmldoc
= xmlNewDoc(NULL
);
2103 xmldoc
->_private
= create_priv();
2104 hr
= attach_xmldoc(This
, xmldoc
);
2109 TRACE("ret (%d)\n", hr
);
2115 static HRESULT WINAPI
domdoc_get_readyState(
2116 IXMLDOMDocument3
*iface
,
2119 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2120 FIXME("stub! (%p)->(%p)\n", This
, value
);
2123 return E_INVALIDARG
;
2125 *value
= READYSTATE_COMPLETE
;
2130 static HRESULT WINAPI
domdoc_get_parseError(
2131 IXMLDOMDocument3
*iface
,
2132 IXMLDOMParseError
** errorObj
)
2134 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2135 static const WCHAR err
[] = {'e','r','r','o','r',0};
2136 BSTR error_string
= NULL
;
2138 FIXME("(%p)->(%p): creating a dummy parseError\n", iface
, errorObj
);
2141 error_string
= SysAllocString(err
);
2143 *errorObj
= create_parseError(This
->error
, NULL
, error_string
, NULL
, 0, 0, 0);
2144 if(!*errorObj
) return E_OUTOFMEMORY
;
2149 static HRESULT WINAPI
domdoc_get_url(
2150 IXMLDOMDocument3
*iface
,
2153 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2154 FIXME("(%p)->(%p)\n", This
, urlString
);
2159 static HRESULT WINAPI
domdoc_get_async(
2160 IXMLDOMDocument3
*iface
,
2161 VARIANT_BOOL
* isAsync
)
2163 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2165 TRACE("(%p)->(%p: %d)\n", This
, isAsync
, This
->async
);
2166 *isAsync
= This
->async
;
2171 static HRESULT WINAPI
domdoc_put_async(
2172 IXMLDOMDocument3
*iface
,
2173 VARIANT_BOOL isAsync
)
2175 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2177 TRACE("(%p)->(%d)\n", This
, isAsync
);
2178 This
->async
= isAsync
;
2183 static HRESULT WINAPI
domdoc_abort(
2184 IXMLDOMDocument3
*iface
)
2186 domdoc
*This
= impl_from_IXMLDOMDocument3(iface
);
2187 FIXME("%p\n", This
);
2192 static BOOL
bstr_to_utf8( BSTR bstr
, char **pstr
, int *plen
)
2197 len
= WideCharToMultiByte( CP_UTF8
, 0, bstr
, -1, NULL
, 0, NULL
, NULL
);
2198 str
= heap_alloc( len
);
2201 WideCharToMultiByte( CP_UTF8
, 0, bstr
, -1, str
, len
, NULL
, NULL
);
2207 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2208 static HRESULT WINAPI
domdoc_loadXML(
2209 IXMLDOMDocument3
*iface
,
2211 VARIANT_BOOL
* isSuccessful
)
2213 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2214 static const xmlChar encoding
[] = "UTF-8";
2215 xmlDocPtr xmldoc
= NULL
;
2216 HRESULT hr
= S_FALSE
, hr2
;
2220 TRACE("(%p)->(%s %p)\n", This
, debugstr_w( bstrXML
), isSuccessful
);
2222 assert ( &This
->node
);
2226 *isSuccessful
= VARIANT_FALSE
;
2228 if ( bstrXML
&& bstr_to_utf8( bstrXML
, &str
, &len
) )
2230 xmldoc
= doparse(This
, str
, len
, encoding
);
2234 This
->error
= E_FAIL
;
2235 TRACE("failed to parse document\n");
2239 hr
= This
->error
= S_OK
;
2240 *isSuccessful
= VARIANT_TRUE
;
2241 TRACE("parsed document %p\n", xmldoc
);
2246 xmldoc
= xmlNewDoc(NULL
);
2248 xmldoc
->_private
= create_priv();
2250 hr2
= attach_xmldoc(This
, xmldoc
);
2257 static int XMLCALL
domdoc_save_writecallback(void *ctx
, const char *buffer
, int len
)
2261 if(!WriteFile(ctx
, buffer
, len
, &written
, NULL
))
2263 WARN("write error\n");
2270 static int XMLCALL
domdoc_save_closecallback(void *ctx
)
2272 return CloseHandle(ctx
) ? 0 : -1;
2275 static int XMLCALL
domdoc_stream_save_writecallback(void *ctx
, const char *buffer
, int len
)
2280 hr
= IStream_Write((IStream
*)ctx
, buffer
, len
, &written
);
2283 WARN("stream write error: 0x%08x\n", hr
);
2290 static int XMLCALL
domdoc_stream_save_closecallback(void *ctx
)
2292 IStream_Release((IStream
*)ctx
);
2296 static HRESULT WINAPI
domdoc_save(
2297 IXMLDOMDocument3
*iface
,
2298 VARIANT destination
)
2300 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2301 xmlSaveCtxtPtr ctx
= NULL
;
2305 TRACE("(%p)->(var(vt %d, %s))\n", This
, V_VT(&destination
),
2306 V_VT(&destination
) == VT_BSTR
? debugstr_w(V_BSTR(&destination
)) : NULL
);
2308 if(V_VT(&destination
) != VT_BSTR
&& V_VT(&destination
) != VT_UNKNOWN
)
2310 FIXME("Unhandled vt %d\n", V_VT(&destination
));
2314 if(V_VT(&destination
) == VT_UNKNOWN
)
2316 IUnknown
*pUnk
= V_UNKNOWN(&destination
);
2317 IXMLDOMDocument2
*document
;
2320 ret
= IUnknown_QueryInterface(pUnk
, &IID_IXMLDOMDocument3
, (void**)&document
);
2323 VARIANT_BOOL success
;
2326 ret
= IXMLDOMDocument3_get_xml(iface
, &xml
);
2329 ret
= IXMLDOMDocument3_loadXML(document
, xml
, &success
);
2333 IXMLDOMDocument3_Release(document
);
2337 ret
= IUnknown_QueryInterface(pUnk
, &IID_IStream
, (void**)&stream
);
2340 ctx
= xmlSaveToIO(domdoc_stream_save_writecallback
,
2341 domdoc_stream_save_closecallback
, stream
, NULL
, XML_SAVE_NO_DECL
);
2345 IStream_Release(stream
);
2352 /* save with file path */
2353 HANDLE handle
= CreateFileW( V_BSTR(&destination
), GENERIC_WRITE
, 0,
2354 NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
2355 if( handle
== INVALID_HANDLE_VALUE
)
2357 WARN("failed to create file\n");
2361 /* disable top XML declaration */
2362 ctx
= xmlSaveToIO(domdoc_save_writecallback
, domdoc_save_closecallback
,
2363 handle
, NULL
, XML_SAVE_NO_DECL
);
2366 CloseHandle(handle
);
2371 xmldecl
= xmldoc_unlink_xmldecl(get_doc(This
));
2372 if (xmlSaveDoc(ctx
, get_doc(This
)) == -1) ret
= S_FALSE
;
2373 xmldoc_link_xmldecl(get_doc(This
), xmldecl
);
2375 /* will release resources through close callback */
2381 static HRESULT WINAPI
domdoc_get_validateOnParse(
2382 IXMLDOMDocument3
*iface
,
2383 VARIANT_BOOL
* isValidating
)
2385 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2386 TRACE("(%p)->(%p: %d)\n", This
, isValidating
, This
->validating
);
2387 *isValidating
= This
->validating
;
2392 static HRESULT WINAPI
domdoc_put_validateOnParse(
2393 IXMLDOMDocument3
*iface
,
2394 VARIANT_BOOL isValidating
)
2396 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2397 TRACE("(%p)->(%d)\n", This
, isValidating
);
2398 This
->validating
= isValidating
;
2403 static HRESULT WINAPI
domdoc_get_resolveExternals(
2404 IXMLDOMDocument3
*iface
,
2405 VARIANT_BOOL
* isResolving
)
2407 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2408 TRACE("(%p)->(%p: %d)\n", This
, isResolving
, This
->resolving
);
2409 *isResolving
= This
->resolving
;
2414 static HRESULT WINAPI
domdoc_put_resolveExternals(
2415 IXMLDOMDocument3
*iface
,
2416 VARIANT_BOOL isResolving
)
2418 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2419 TRACE("(%p)->(%d)\n", This
, isResolving
);
2420 This
->resolving
= isResolving
;
2425 static HRESULT WINAPI
domdoc_get_preserveWhiteSpace(
2426 IXMLDOMDocument3
*iface
,
2427 VARIANT_BOOL
* isPreserving
)
2429 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2430 TRACE("(%p)->(%p: %d)\n", This
, isPreserving
, This
->properties
->preserving
);
2431 *isPreserving
= This
->properties
->preserving
;
2436 static HRESULT WINAPI
domdoc_put_preserveWhiteSpace(
2437 IXMLDOMDocument3
*iface
,
2438 VARIANT_BOOL isPreserving
)
2440 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2441 TRACE("(%p)->(%d)\n", This
, isPreserving
);
2442 This
->properties
->preserving
= isPreserving
;
2447 static HRESULT WINAPI
domdoc_put_onReadyStateChange(
2448 IXMLDOMDocument3
*iface
,
2449 VARIANT readyStateChangeSink
)
2451 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2452 FIXME("%p\n", This
);
2457 static HRESULT WINAPI
domdoc_put_onDataAvailable(
2458 IXMLDOMDocument3
*iface
,
2459 VARIANT onDataAvailableSink
)
2461 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2462 FIXME("%p\n", This
);
2466 static HRESULT WINAPI
domdoc_put_onTransformNode(
2467 IXMLDOMDocument3
*iface
,
2468 VARIANT onTransformNodeSink
)
2470 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2471 FIXME("%p\n", This
);
2475 static HRESULT WINAPI
domdoc_get_namespaces(
2476 IXMLDOMDocument3
* iface
,
2477 IXMLDOMSchemaCollection
** schemaCollection
)
2479 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2480 FIXME("(%p)->(%p)\n", This
, schemaCollection
);
2484 static HRESULT WINAPI
domdoc_get_schemas(
2485 IXMLDOMDocument3
* iface
,
2488 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2489 HRESULT hr
= S_FALSE
;
2490 IXMLDOMSchemaCollection2
* cur_schema
= This
->properties
->schemaCache
;
2492 TRACE("(%p)->(%p)\n", This
, var1
);
2494 VariantInit(var1
); /* Test shows we don't call VariantClear here */
2495 V_VT(var1
) = VT_NULL
;
2499 hr
= IXMLDOMSchemaCollection2_QueryInterface(cur_schema
, &IID_IDispatch
, (void**)&V_DISPATCH(var1
));
2501 V_VT(var1
) = VT_DISPATCH
;
2506 static HRESULT WINAPI
domdoc_putref_schemas(
2507 IXMLDOMDocument3
* iface
,
2510 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2511 HRESULT hr
= E_FAIL
;
2512 IXMLDOMSchemaCollection2
* new_schema
= NULL
;
2514 FIXME("(%p): semi-stub\n", This
);
2518 hr
= IUnknown_QueryInterface(V_UNKNOWN(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2522 hr
= IDispatch_QueryInterface(V_DISPATCH(&var1
), &IID_IXMLDOMSchemaCollection
, (void**)&new_schema
);
2531 WARN("Can't get schema from vt %x\n", V_VT(&var1
));
2536 IXMLDOMSchemaCollection2
* old_schema
= InterlockedExchangePointer((void**)&This
->properties
->schemaCache
, new_schema
);
2537 if(old_schema
) IXMLDOMSchemaCollection2_Release(old_schema
);
2543 static inline BOOL
is_wellformed(xmlDocPtr doc
)
2545 #ifdef HAVE_XMLDOC_PROPERTIES
2546 return doc
->properties
& XML_DOC_WELLFORMED
;
2548 /* Not a full check, but catches the worst violations */
2552 for (child
= doc
->children
; child
!= NULL
; child
= child
->next
)
2554 switch (child
->type
)
2556 case XML_ELEMENT_NODE
:
2561 case XML_CDATA_SECTION_NODE
:
2573 static void LIBXML2_LOG_CALLBACK
validate_error(void* ctx
, char const* msg
, ...)
2577 LIBXML2_CALLBACK_ERR(domdoc_validateNode
, msg
, ap
);
2581 static void LIBXML2_LOG_CALLBACK
validate_warning(void* ctx
, char const* msg
, ...)
2585 LIBXML2_CALLBACK_WARN(domdoc_validateNode
, msg
, ap
);
2589 static HRESULT WINAPI
domdoc_validateNode(
2590 IXMLDOMDocument3
* iface
,
2592 IXMLDOMParseError
** err
)
2594 domdoc
* This
= impl_from_IXMLDOMDocument3(iface
);
2595 LONG state
, err_code
= 0;
2599 TRACE("(%p)->(%p, %p)\n", This
, node
, err
);
2600 domdoc_get_readyState(iface
, &state
);
2601 if (state
!= READYSTATE_COMPLETE
)
2604 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2611 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2615 if (!get_node_obj(node
)->node
|| get_node_obj(node
)->node
->doc
!= get_doc(This
))
2618 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2622 if (!is_wellformed(get_doc(This
)))
2624 ERR("doc not well-formed");
2626 *err
= create_parseError(E_XML_NOTWF
, NULL
, NULL
, NULL
, 0, 0, 0);
2630 /* DTD validation */
2631 if (get_doc(This
)->intSubset
|| get_doc(This
)->extSubset
)
2633 xmlValidCtxtPtr vctx
= xmlNewValidCtxt();
2634 vctx
->error
= validate_error
;
2635 vctx
->warning
= validate_warning
;
2638 if (!((node
== (IXMLDOMNode
*)iface
)?
2639 xmlValidateDocument(vctx
, get_doc(This
)) :
2640 xmlValidateElement(vctx
, get_doc(This
), get_node_obj(node
)->node
)))
2642 /* TODO: get a real error code here */
2643 TRACE("DTD validation failed\n");
2644 err_code
= E_XML_INVALID
;
2647 xmlFreeValidCtxt(vctx
);
2650 /* Schema validation */
2651 if (hr
== S_OK
&& This
->properties
->schemaCache
!= NULL
)
2654 hr
= SchemaCache_validate_tree(This
->properties
->schemaCache
, get_node_obj(node
)->node
);
2658 /* TODO: get a real error code here */
2661 TRACE("schema validation succeeded\n");
2665 ERR("schema validation failed\n");
2666 err_code
= E_XML_INVALID
;
2671 /* not really OK, just didn't find a schema for the ns */
2678 ERR("no DTD or schema found\n");
2679 err_code
= E_XML_NODTD
;
2684 *err
= create_parseError(err_code
, NULL
, NULL
, NULL
, 0, 0, 0);
2689 static HRESULT WINAPI
domdoc_validate(
2690 IXMLDOMDocument3
* iface
,
2691 IXMLDOMParseError
** err
)
2693 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2694 TRACE("(%p)->(%p)\n", This
, err
);
2695 return domdoc_validateNode(iface
, (IXMLDOMNode
*)iface
, err
);
2698 static HRESULT WINAPI
domdoc_setProperty(
2699 IXMLDOMDocument3
* iface
,
2703 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2705 TRACE("(%p)->(%s)\n", This
, debugstr_w(p
));
2707 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2713 V_VT(&varStr
) = VT_EMPTY
;
2714 if (V_VT(&var
) != VT_BSTR
)
2716 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2718 bstr
= V_BSTR(&varStr
);
2721 bstr
= V_BSTR(&var
);
2724 if (lstrcmpiW(bstr
, PropValueXPathW
) == 0)
2725 This
->properties
->XPath
= TRUE
;
2726 else if (lstrcmpiW(bstr
, PropValueXSLPatternW
) == 0)
2727 This
->properties
->XPath
= FALSE
;
2731 VariantClear(&varStr
);
2734 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2739 xmlChar
*pTokBegin
, *pTokEnd
, *pTokInner
;
2740 xmlChar
*nsStr
= (xmlChar
*)This
->properties
->selectNsStr
;
2741 xmlXPathContextPtr ctx
;
2742 struct list
*pNsList
;
2743 select_ns_entry
* pNsEntry
= NULL
;
2745 V_VT(&varStr
) = VT_EMPTY
;
2746 if (V_VT(&var
) != VT_BSTR
)
2748 if (FAILED(hr
= VariantChangeType(&varStr
, &var
, 0, VT_BSTR
)))
2750 bstr
= V_BSTR(&varStr
);
2753 bstr
= V_BSTR(&var
);
2757 pNsList
= &(This
->properties
->selectNsList
);
2758 clear_selectNsList(pNsList
);
2760 nsStr
= xmlChar_from_wchar(bstr
);
2763 TRACE("Setting SelectionNamespaces property to: %s\n", nsStr
);
2765 This
->properties
->selectNsStr
= nsStr
;
2766 This
->properties
->selectNsStr_len
= xmlStrlen(nsStr
);
2769 ctx
= xmlXPathNewContext(This
->node
.node
->doc
);
2772 for (; *pTokBegin
; pTokBegin
= pTokEnd
)
2774 if (pNsEntry
!= NULL
)
2775 memset(pNsEntry
, 0, sizeof(select_ns_entry
));
2777 pNsEntry
= heap_alloc_zero(sizeof(select_ns_entry
));
2779 while (*pTokBegin
== ' ')
2781 pTokEnd
= pTokBegin
;
2782 while (*pTokEnd
!= ' ' && *pTokEnd
!= 0)
2785 if (xmlStrncmp(pTokBegin
, (xmlChar
const*)"xmlns", 5) != 0)
2788 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2789 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2794 if (*pTokBegin
== '=')
2796 /*valid for XSLPattern?*/
2797 FIXME("Setting default xmlns not supported - skipping.\n");
2798 pTokBegin
= pTokEnd
;
2801 else if (*pTokBegin
== ':')
2803 pNsEntry
->prefix
= ++pTokBegin
;
2804 for (pTokInner
= pTokBegin
; pTokInner
!= pTokEnd
&& *pTokInner
!= '='; ++pTokInner
)
2807 if (pTokInner
== pTokEnd
)
2810 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2811 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokBegin
, pTokEnd
-pTokBegin
));
2815 pNsEntry
->prefix_end
= *pTokInner
;
2819 if (pTokEnd
-pTokInner
> 1 &&
2820 ((*pTokInner
== '\'' && *(pTokEnd
-1) == '\'') ||
2821 (*pTokInner
== '"' && *(pTokEnd
-1) == '"')))
2823 pNsEntry
->href
= ++pTokInner
;
2824 pNsEntry
->href_end
= *(pTokEnd
-1);
2826 list_add_tail(pNsList
, &pNsEntry
->entry
);
2827 /*let libxml figure out if they're valid from here ;)*/
2828 if (xmlXPathRegisterNs(ctx
, pNsEntry
->prefix
, pNsEntry
->href
) != 0)
2837 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2838 wine_dbgstr_w(bstr
), wine_dbgstr_an((const char*)pTokInner
, pTokEnd
-pTokInner
));
2839 list_add_tail(pNsList
, &pNsEntry
->entry
);
2852 heap_free(pNsEntry
);
2853 xmlXPathFreeContext(ctx
);
2856 VariantClear(&varStr
);
2859 else if (lstrcmpiW(p
, PropertyProhibitDTDW
) == 0 ||
2860 lstrcmpiW(p
, PropertyNewParserW
) == 0)
2863 FIXME("Ignoring property %s, value %d\n", debugstr_w(p
), V_BOOL(&var
));
2867 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2871 static HRESULT WINAPI
domdoc_getProperty(
2872 IXMLDOMDocument3
* iface
,
2876 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2878 TRACE("(%p)->(%p)\n", This
, debugstr_w(p
));
2881 return E_INVALIDARG
;
2883 if (lstrcmpiW(p
, PropertySelectionLanguageW
) == 0)
2885 V_VT(var
) = VT_BSTR
;
2886 V_BSTR(var
) = This
->properties
->XPath
?
2887 SysAllocString(PropValueXPathW
) :
2888 SysAllocString(PropValueXSLPatternW
);
2889 return V_BSTR(var
) ? S_OK
: E_OUTOFMEMORY
;
2891 else if (lstrcmpiW(p
, PropertySelectionNamespacesW
) == 0)
2894 BSTR rebuiltStr
, cur
;
2895 const xmlChar
*nsStr
;
2896 struct list
*pNsList
;
2897 select_ns_entry
* pNsEntry
;
2899 V_VT(var
) = VT_BSTR
;
2900 nsStr
= This
->properties
->selectNsStr
;
2901 pNsList
= &This
->properties
->selectNsList
;
2902 lenA
= This
->properties
->selectNsStr_len
;
2903 lenW
= MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, NULL
, 0);
2904 rebuiltStr
= heap_alloc(lenW
*sizeof(WCHAR
));
2905 MultiByteToWideChar(CP_UTF8
, 0, (LPCSTR
)nsStr
, lenA
+1, rebuiltStr
, lenW
);
2907 /* this is fine because all of the chars that end tokens are ASCII*/
2908 LIST_FOR_EACH_ENTRY(pNsEntry
, pNsList
, select_ns_entry
, entry
)
2910 while (*cur
!= 0) ++cur
;
2911 if (pNsEntry
->prefix_end
)
2913 *cur
= pNsEntry
->prefix_end
;
2914 while (*cur
!= 0) ++cur
;
2917 if (pNsEntry
->href_end
)
2919 *cur
= pNsEntry
->href_end
;
2922 V_BSTR(var
) = SysAllocString(rebuiltStr
);
2923 heap_free(rebuiltStr
);
2927 FIXME("Unknown property %s\n", wine_dbgstr_w(p
));
2931 static HRESULT WINAPI
domdoc_importNode(
2932 IXMLDOMDocument3
* iface
,
2935 IXMLDOMNode
** clone
)
2937 domdoc
*This
= impl_from_IXMLDOMDocument3( iface
);
2938 FIXME("(%p)->(%p %d %p): stub\n", This
, node
, deep
, clone
);
2942 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl
=
2944 domdoc_QueryInterface
,
2947 domdoc_GetTypeInfoCount
,
2949 domdoc_GetIDsOfNames
,
2951 domdoc_get_nodeName
,
2952 domdoc_get_nodeValue
,
2953 domdoc_put_nodeValue
,
2954 domdoc_get_nodeType
,
2955 domdoc_get_parentNode
,
2956 domdoc_get_childNodes
,
2957 domdoc_get_firstChild
,
2958 domdoc_get_lastChild
,
2959 domdoc_get_previousSibling
,
2960 domdoc_get_nextSibling
,
2961 domdoc_get_attributes
,
2962 domdoc_insertBefore
,
2963 domdoc_replaceChild
,
2966 domdoc_hasChildNodes
,
2967 domdoc_get_ownerDocument
,
2969 domdoc_get_nodeTypeString
,
2972 domdoc_get_specified
,
2973 domdoc_get_definition
,
2974 domdoc_get_nodeTypedValue
,
2975 domdoc_put_nodeTypedValue
,
2976 domdoc_get_dataType
,
2977 domdoc_put_dataType
,
2979 domdoc_transformNode
,
2981 domdoc_selectSingleNode
,
2983 domdoc_get_namespaceURI
,
2985 domdoc_get_baseName
,
2986 domdoc_transformNodeToObject
,
2988 domdoc_get_implementation
,
2989 domdoc_get_documentElement
,
2990 domdoc_put_documentElement
,
2991 domdoc_createElement
,
2992 domdoc_createDocumentFragment
,
2993 domdoc_createTextNode
,
2994 domdoc_createComment
,
2995 domdoc_createCDATASection
,
2996 domdoc_createProcessingInstruction
,
2997 domdoc_createAttribute
,
2998 domdoc_createEntityReference
,
2999 domdoc_getElementsByTagName
,
3003 domdoc_get_readyState
,
3004 domdoc_get_parseError
,
3011 domdoc_get_validateOnParse
,
3012 domdoc_put_validateOnParse
,
3013 domdoc_get_resolveExternals
,
3014 domdoc_put_resolveExternals
,
3015 domdoc_get_preserveWhiteSpace
,
3016 domdoc_put_preserveWhiteSpace
,
3017 domdoc_put_onReadyStateChange
,
3018 domdoc_put_onDataAvailable
,
3019 domdoc_put_onTransformNode
,
3020 domdoc_get_namespaces
,
3022 domdoc_putref_schemas
,
3026 domdoc_validateNode
,
3030 /* IConnectionPointContainer */
3031 static HRESULT WINAPI
ConnectionPointContainer_QueryInterface(IConnectionPointContainer
*iface
,
3032 REFIID riid
, void **ppv
)
3034 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3035 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3
*)This
, riid
, ppv
);
3038 static ULONG WINAPI
ConnectionPointContainer_AddRef(IConnectionPointContainer
*iface
)
3040 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3041 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
3044 static ULONG WINAPI
ConnectionPointContainer_Release(IConnectionPointContainer
*iface
)
3046 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3047 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
3050 static HRESULT WINAPI
ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer
*iface
,
3051 IEnumConnectionPoints
**ppEnum
)
3053 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3054 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3058 static HRESULT WINAPI
ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer
*iface
,
3059 REFIID riid
, IConnectionPoint
**cp
)
3061 domdoc
*This
= impl_from_IConnectionPointContainer(iface
);
3062 ConnectionPoint
*iter
;
3064 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), cp
);
3068 for(iter
= This
->cp_list
; iter
; iter
= iter
->next
)
3070 if (IsEqualGUID(iter
->iid
, riid
))
3071 *cp
= (IConnectionPoint
*)&iter
->lpVtblConnectionPoint
;
3076 IConnectionPoint_AddRef(*cp
);
3080 FIXME("unsupported riid %s\n", debugstr_guid(riid
));
3081 return CONNECT_E_NOCONNECTION
;
3085 static const struct IConnectionPointContainerVtbl ConnectionPointContainerVtbl
=
3087 ConnectionPointContainer_QueryInterface
,
3088 ConnectionPointContainer_AddRef
,
3089 ConnectionPointContainer_Release
,
3090 ConnectionPointContainer_EnumConnectionPoints
,
3091 ConnectionPointContainer_FindConnectionPoint
3094 /* IConnectionPoint */
3095 static HRESULT WINAPI
ConnectionPoint_QueryInterface(IConnectionPoint
*iface
,
3096 REFIID riid
, void **ppv
)
3098 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3100 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
3104 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
3105 IsEqualGUID(&IID_IConnectionPoint
, riid
))
3112 IConnectionPoint_AddRef(iface
);
3116 WARN("Unsupported interface %s\n", debugstr_guid(riid
));
3117 return E_NOINTERFACE
;
3120 static ULONG WINAPI
ConnectionPoint_AddRef(IConnectionPoint
*iface
)
3122 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3123 return IConnectionPointContainer_AddRef(This
->container
);
3126 static ULONG WINAPI
ConnectionPoint_Release(IConnectionPoint
*iface
)
3128 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3129 return IConnectionPointContainer_Release(This
->container
);
3132 static HRESULT WINAPI
ConnectionPoint_GetConnectionInterface(IConnectionPoint
*iface
, IID
*iid
)
3134 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3136 TRACE("(%p)->(%p)\n", This
, iid
);
3138 if (!iid
) return E_POINTER
;
3144 static HRESULT WINAPI
ConnectionPoint_GetConnectionPointContainer(IConnectionPoint
*iface
,
3145 IConnectionPointContainer
**container
)
3147 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3149 TRACE("(%p)->(%p)\n", This
, container
);
3151 if (!container
) return E_POINTER
;
3153 *container
= This
->container
;
3154 IConnectionPointContainer_AddRef(*container
);
3158 static HRESULT WINAPI
ConnectionPoint_Advise(IConnectionPoint
*iface
, IUnknown
*pUnkSink
,
3161 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3162 FIXME("(%p)->(%p %p): stub\n", This
, pUnkSink
, pdwCookie
);
3166 static HRESULT WINAPI
ConnectionPoint_Unadvise(IConnectionPoint
*iface
, DWORD cookie
)
3168 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3170 TRACE("(%p)->(%d)\n", This
, cookie
);
3172 if (cookie
== 0 || cookie
> This
->sinks_size
|| !This
->sinks
[cookie
-1].unk
)
3173 return CONNECT_E_NOCONNECTION
;
3175 IUnknown_Release(This
->sinks
[cookie
-1].unk
);
3176 This
->sinks
[cookie
-1].unk
= NULL
;
3181 static HRESULT WINAPI
ConnectionPoint_EnumConnections(IConnectionPoint
*iface
,
3182 IEnumConnections
**ppEnum
)
3184 ConnectionPoint
*This
= impl_from_IConnectionPoint(iface
);
3185 FIXME("(%p)->(%p): stub\n", This
, ppEnum
);
3189 static const IConnectionPointVtbl ConnectionPointVtbl
=
3191 ConnectionPoint_QueryInterface
,
3192 ConnectionPoint_AddRef
,
3193 ConnectionPoint_Release
,
3194 ConnectionPoint_GetConnectionInterface
,
3195 ConnectionPoint_GetConnectionPointContainer
,
3196 ConnectionPoint_Advise
,
3197 ConnectionPoint_Unadvise
,
3198 ConnectionPoint_EnumConnections
3201 void ConnectionPoint_Init(ConnectionPoint
*cp
, struct domdoc
*doc
, REFIID riid
)
3203 cp
->lpVtblConnectionPoint
= &ConnectionPointVtbl
;
3209 cp
->next
= doc
->cp_list
;
3212 cp
->container
= (IConnectionPointContainer
*)&doc
->lpVtblConnectionPointContainer
;
3215 /* domdoc implementation of IObjectWithSite */
3216 static HRESULT WINAPI
3217 domdoc_ObjectWithSite_QueryInterface( IObjectWithSite
* iface
, REFIID riid
, void** ppvObject
)
3219 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3220 return IXMLDOMDocument3_QueryInterface( (IXMLDOMDocument3
*)This
, riid
, ppvObject
);
3223 static ULONG WINAPI
domdoc_ObjectWithSite_AddRef( IObjectWithSite
* iface
)
3225 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3226 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
3229 static ULONG WINAPI
domdoc_ObjectWithSite_Release( IObjectWithSite
* iface
)
3231 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3232 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
3235 static HRESULT WINAPI
domdoc_ObjectWithSite_GetSite( IObjectWithSite
*iface
, REFIID iid
, void **ppvSite
)
3237 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3239 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid( iid
), ppvSite
);
3244 return IUnknown_QueryInterface( This
->site
, iid
, ppvSite
);
3247 static HRESULT WINAPI
domdoc_ObjectWithSite_SetSite( IObjectWithSite
*iface
, IUnknown
*punk
)
3249 domdoc
*This
= impl_from_IObjectWithSite(iface
);
3251 TRACE("(%p)->(%p)\n", iface
, punk
);
3257 IUnknown_Release( This
->site
);
3264 IUnknown_AddRef( punk
);
3267 IUnknown_Release( This
->site
);
3274 static const IObjectWithSiteVtbl domdocObjectSite
=
3276 domdoc_ObjectWithSite_QueryInterface
,
3277 domdoc_ObjectWithSite_AddRef
,
3278 domdoc_ObjectWithSite_Release
,
3279 domdoc_ObjectWithSite_SetSite
,
3280 domdoc_ObjectWithSite_GetSite
3283 static HRESULT WINAPI
domdoc_Safety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
3285 domdoc
*This
= impl_from_IObjectSafety(iface
);
3286 return IXMLDOMDocument3_QueryInterface( (IXMLDOMDocument3
*)This
, riid
, ppv
);
3289 static ULONG WINAPI
domdoc_Safety_AddRef(IObjectSafety
*iface
)
3291 domdoc
*This
= impl_from_IObjectSafety(iface
);
3292 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3
*)This
);
3295 static ULONG WINAPI
domdoc_Safety_Release(IObjectSafety
*iface
)
3297 domdoc
*This
= impl_from_IObjectSafety(iface
);
3298 return IXMLDOMDocument3_Release((IXMLDOMDocument3
*)This
);
3301 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
3303 static HRESULT WINAPI
domdoc_Safety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3304 DWORD
*supported
, DWORD
*enabled
)
3306 domdoc
*This
= impl_from_IObjectSafety(iface
);
3308 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), supported
, enabled
);
3310 if(!supported
|| !enabled
) return E_POINTER
;
3312 *supported
= SAFETY_SUPPORTED_OPTIONS
;
3313 *enabled
= This
->safeopt
;
3318 static HRESULT WINAPI
domdoc_Safety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
3319 DWORD mask
, DWORD enabled
)
3321 domdoc
*This
= impl_from_IObjectSafety(iface
);
3322 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_guid(riid
), mask
, enabled
);
3324 if ((mask
& ~SAFETY_SUPPORTED_OPTIONS
) != 0)
3327 This
->safeopt
= enabled
& mask
& SAFETY_SUPPORTED_OPTIONS
;
3331 #undef SAFETY_SUPPORTED_OPTIONS
3333 static const IObjectSafetyVtbl domdocObjectSafetyVtbl
= {
3334 domdoc_Safety_QueryInterface
,
3335 domdoc_Safety_AddRef
,
3336 domdoc_Safety_Release
,
3337 domdoc_Safety_GetInterfaceSafetyOptions
,
3338 domdoc_Safety_SetInterfaceSafetyOptions
3341 static const tid_t domdoc_iface_tids
[] = {
3343 IXMLDOMDocument_tid
,
3344 IXMLDOMDocument2_tid
,
3347 static dispex_static_data_t domdoc_dispex
= {
3349 IXMLDOMDocument2_tid
,
3354 HRESULT
DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc
, IXMLDOMDocument3
**document
)
3358 doc
= heap_alloc( sizeof (*doc
) );
3360 return E_OUTOFMEMORY
;
3362 doc
->lpVtbl
= &domdoc_vtbl
;
3363 doc
->lpvtblIPersistStreamInit
= &xmldoc_IPersistStreamInit_VTable
;
3364 doc
->lpvtblIObjectWithSite
= &domdocObjectSite
;
3365 doc
->lpvtblIObjectSafety
= &domdocObjectSafetyVtbl
;
3366 doc
->lpvtblISupportErrorInfo
= &support_error_vtbl
;
3367 doc
->lpVtblConnectionPointContainer
= &ConnectionPointContainerVtbl
;
3369 doc
->async
= VARIANT_TRUE
;
3370 doc
->validating
= 0;
3372 doc
->properties
= properties_from_xmlDocPtr(xmldoc
);
3378 doc
->cp_list
= NULL
;
3380 /* events connection points */
3381 ConnectionPoint_Init(&doc
->cp_dispatch
, doc
, &IID_IDispatch
);
3382 ConnectionPoint_Init(&doc
->cp_propnotif
, doc
, &IID_IPropertyNotifySink
);
3383 ConnectionPoint_Init(&doc
->cp_domdocevents
, doc
, &DIID_XMLDOMDocumentEvents
);
3385 init_xmlnode(&doc
->node
, (xmlNodePtr
)xmldoc
, (IXMLDOMNode
*)&doc
->lpVtbl
, &domdoc_dispex
);
3387 *document
= (IXMLDOMDocument3
*)&doc
->lpVtbl
;
3389 TRACE("returning iface %p\n", *document
);
3393 HRESULT
DOMDocument_create(const GUID
*clsid
, IUnknown
*pUnkOuter
, void **ppObj
)
3398 TRACE("(%s, %p, %p)\n", debugstr_guid(clsid
), pUnkOuter
, ppObj
);
3400 xmldoc
= xmlNewDoc(NULL
);
3402 return E_OUTOFMEMORY
;
3404 xmldoc
->_private
= create_priv();
3405 priv_from_xmlDocPtr(xmldoc
)->properties
= create_properties(clsid
);
3407 hr
= DOMDocument_create_from_xmldoc(xmldoc
, (IXMLDOMDocument3
**)ppObj
);
3410 free_properties(properties_from_xmlDocPtr(xmldoc
));
3411 heap_free(xmldoc
->_private
);
3419 IUnknown
* create_domdoc( xmlNodePtr document
)
3424 TRACE("(%p)\n", document
);
3426 hr
= DOMDocument_create_from_xmldoc((xmlDocPtr
)document
, (IXMLDOMDocument3
**)&pObj
);
3435 HRESULT
DOMDocument_create(const GUID
*clsid
, IUnknown
*pUnkOuter
, void **ppObj
)
3437 MESSAGE("This program tried to use a DOMDocument object, but\n"
3438 "libxml2 support was not present at compile time.\n");