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
42 #include "wine/debug.h"
43 #include "wine/list.h"
45 #include "msxml_private.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
51 #include <libxml/xpathInternals.h>
52 #include <libxml/xmlsave.h>
53 #include <libxml/SAX2.h>
55 /* not defined in older versions */
56 #define XML_SAVE_FORMAT 1
57 #define XML_SAVE_NO_DECL 2
58 #define XML_SAVE_NO_EMPTY 4
59 #define XML_SAVE_NO_XHTML 8
60 #define XML_SAVE_XHTML 16
61 #define XML_SAVE_AS_XML 32
62 #define XML_SAVE_AS_HTML 64
64 static const WCHAR PropertySelectionLanguageW[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
65 static const WCHAR PropertySelectionNamespacesW[] = {'S','e','l','e','c','t','i','o','n','N','a','m','e','s','p','a','c','e','s',0};
66 static const WCHAR PropertyProhibitDTDW[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
67 static const WCHAR PropValueXPathW[] = {'X','P','a','t','h',0};
68 static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r','n',0};
70 /* Data used by domdoc_getProperty()/domdoc_setProperty().
71 * We need to preserve this when reloading a document,
72 * and also need access to it from the libxml backend. */
73 typedef struct _domdoc_properties {
74 struct list selectNsList;
75 xmlChar const* selectNsStr;
80 typedef struct _domdoc
83 const struct IXMLDOMDocument3Vtbl *lpVtbl;
84 const struct IPersistStreamInitVtbl *lpvtblIPersistStreamInit;
85 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
86 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
87 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
90 VARIANT_BOOL validating;
91 VARIANT_BOOL resolving;
92 VARIANT_BOOL preserving;
93 domdoc_properties* properties;
94 IXMLDOMSchemaCollection *schema;
109 In native windows, the whole lifetime management of XMLDOMNodes is
110 managed automatically using reference counts. Wine emulates that by
111 maintaining a reference count to the document that is increased for
112 each IXMLDOMNode pointer passed out for this document. If all these
113 pointers are gone, the document is unreachable and gets freed, that
114 is, all nodes in the tree of the document get freed.
116 You are able to create nodes that are associated to a document (in
117 fact, in msxml's XMLDOM model, all nodes are associated to a document),
118 but not in the tree of that document, for example using the createFoo
119 functions from IXMLDOMDocument. These nodes do not get cleaned up
120 by libxml, so we have to do it ourselves.
122 To catch these nodes, a list of "orphan nodes" is introduced.
123 It contains pointers to all roots of node trees that are
124 associated with the document without being part of the document
125 tree. All nodes with parent==NULL (except for the document root nodes)
126 should be in the orphan node list of their document. All orphan nodes
127 get freed together with the document itself.
130 typedef struct _xmldoc_priv {
133 domdoc_properties* properties;
136 typedef struct _orphan_entry {
141 typedef struct _select_ns_entry {
143 xmlChar const* prefix;
149 static inline xmldoc_priv * priv_from_xmlDocPtr(const xmlDocPtr doc)
151 return doc->_private;
154 static inline domdoc_properties * properties_from_xmlDocPtr(xmlDocPtr doc)
156 return priv_from_xmlDocPtr(doc)->properties;
159 static inline BOOL is_xpathmode(const xmlDocPtr doc)
161 return properties_from_xmlDocPtr(doc)->XPath;
164 int registerNamespaces(xmlXPathContextPtr ctxt)
167 const select_ns_entry* ns = NULL;
168 const struct list* pNsList = &properties_from_xmlDocPtr(ctxt->doc)->selectNsList;
170 TRACE("(%p)\n", ctxt);
172 LIST_FOR_EACH_ENTRY( ns, pNsList, select_ns_entry, entry )
174 xmlXPathRegisterNs(ctxt, ns->prefix, ns->href);
181 static inline void clear_selectNsList(struct list* pNsList)
183 select_ns_entry *ns, *ns2;
184 LIST_FOR_EACH_ENTRY_SAFE( ns, ns2, pNsList, select_ns_entry, entry )
191 static xmldoc_priv * create_priv(void)
194 priv = heap_alloc( sizeof (*priv) );
199 list_init( &priv->orphans );
200 priv->properties = NULL;
206 static domdoc_properties * create_properties(const GUID *clsid)
208 domdoc_properties *properties = heap_alloc(sizeof(domdoc_properties));
210 list_init( &properties->selectNsList );
211 properties->selectNsStr = heap_alloc_zero(sizeof(xmlChar));
212 properties->selectNsStr_len = 0;
213 properties->XPath = FALSE;
215 /* properties that are dependent on object versions */
216 if (IsEqualCLSID( clsid, &CLSID_DOMDocument40 ) ||
217 IsEqualCLSID( clsid, &CLSID_DOMDocument60 ))
219 properties->XPath = TRUE;
225 static domdoc_properties* copy_properties(domdoc_properties const* properties)
227 domdoc_properties* pcopy = heap_alloc(sizeof(domdoc_properties));
228 select_ns_entry const* ns = NULL;
229 select_ns_entry* new_ns = NULL;
230 int len = (properties->selectNsStr_len+1)*sizeof(xmlChar);
235 pcopy->XPath = properties->XPath;
236 pcopy->selectNsStr_len = properties->selectNsStr_len;
237 list_init( &pcopy->selectNsList );
238 pcopy->selectNsStr = heap_alloc(len);
239 memcpy((xmlChar*)pcopy->selectNsStr, properties->selectNsStr, len);
240 offset = pcopy->selectNsStr - properties->selectNsStr;
242 LIST_FOR_EACH_ENTRY( ns, (&properties->selectNsList), select_ns_entry, entry )
244 new_ns = heap_alloc(sizeof(select_ns_entry));
245 memcpy(new_ns, ns, sizeof(select_ns_entry));
246 new_ns->href += offset;
247 new_ns->prefix += offset;
248 list_add_tail(&pcopy->selectNsList, &new_ns->entry);
256 static void free_properties(domdoc_properties* properties)
260 clear_selectNsList(&properties->selectNsList);
261 heap_free((xmlChar*)properties->selectNsStr);
262 heap_free(properties);
266 /* links a "<?xml" node as a first child */
267 void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
270 if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
273 /* unlinks a first "<?xml" child if it was created */
274 xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
280 if (doc->standalone != -1)
282 node = doc->children;
283 xmlUnlinkNode( node );
291 static inline BOOL strn_isspace(xmlChar const* str, int len)
293 for (; str && len > 0 && *str; ++str, --len)
300 static void sax_characters(void *ctx, const xmlChar *ch, int len)
302 xmlParserCtxtPtr pctx;
305 pctx = (xmlParserCtxtPtr) ctx;
306 This = (domdoc const*) pctx->_private;
308 if (!This->preserving)
310 xmlChar* ws = xmlGetNsProp(pctx->node, BAD_CAST "space", XML_XML_NAMESPACE);
311 if ((!ws || xmlStrcmp(ws, BAD_CAST "preserve") != 0) &&
312 strn_isspace(ch, len))
320 xmlSAX2Characters(ctx, ch, len);
323 static xmlDocPtr doparse(domdoc* This, char *ptr, int len)
326 static xmlSAXHandler sax_handler = {
327 xmlSAX2InternalSubset, /* internalSubset */
328 xmlSAX2IsStandalone, /* isStandalone */
329 xmlSAX2HasInternalSubset, /* hasInternalSubset */
330 xmlSAX2HasExternalSubset, /* hasExternalSubset */
331 xmlSAX2ResolveEntity, /* resolveEntity */
332 xmlSAX2GetEntity, /* getEntity */
333 xmlSAX2EntityDecl, /* entityDecl */
334 xmlSAX2NotationDecl, /* notationDecl */
335 xmlSAX2AttributeDecl, /* attributeDecl */
336 xmlSAX2ElementDecl, /* elementDecl */
337 xmlSAX2UnparsedEntityDecl, /* unparsedEntityDecl */
338 xmlSAX2SetDocumentLocator, /* setDocumentLocator */
339 xmlSAX2StartDocument, /* startDocument */
340 xmlSAX2EndDocument, /* endDocument */
341 xmlSAX2StartElement, /* startElement */
342 xmlSAX2EndElement, /* endElement */
343 xmlSAX2Reference, /* reference */
344 sax_characters, /* characters */
345 sax_characters, /* ignorableWhitespace */
346 xmlSAX2ProcessingInstruction, /* processingInstruction */
347 xmlSAX2Comment, /* comment */
348 NULL, /* TODO: warning */
349 NULL, /* TODO: error */
350 NULL, /* TODO: fatalError */
351 xmlSAX2GetParameterEntity, /* getParameterEntity */
352 xmlSAX2CDataBlock, /* cdataBlock */
353 xmlSAX2ExternalSubset, /* externalSubset */
356 xmlSAX2StartElementNs, /* startElementNs */
357 xmlSAX2EndElementNs, /* endElementNs */
358 NULL /* TODO: serror */
361 doc = xmlSAXParseMemoryWithData(&sax_handler, ptr, len, 0, This);
363 /* TODO: put this in one of the SAX callbacks */
364 /* create first child as a <?xml...?> */
365 if (doc && doc->standalone != -1)
369 xmlChar *xmlbuff = (xmlChar*)buff;
371 node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL );
373 /* version attribute can't be omitted */
374 sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0");
375 xmlNodeAddContent( node, xmlbuff );
379 sprintf(buff, " encoding=\"%s\"", doc->encoding);
380 xmlNodeAddContent( node, xmlbuff );
383 if (doc->standalone != -2)
385 sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes");
386 xmlNodeAddContent( node, xmlbuff );
389 xmldoc_link_xmldecl( doc, node );
395 LONG xmldoc_add_ref(xmlDocPtr doc)
397 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
398 TRACE("(%p)->(%d)\n", doc, ref);
402 LONG xmldoc_release(xmlDocPtr doc)
404 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
405 LONG ref = InterlockedDecrement(&priv->refs);
406 TRACE("(%p)->(%d)\n", doc, ref);
409 orphan_entry *orphan, *orphan2;
410 TRACE("freeing docptr %p\n", doc);
412 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
414 xmlFreeNode( orphan->node );
417 free_properties(priv->properties);
418 heap_free(doc->_private);
426 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
428 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
431 entry = heap_alloc( sizeof (*entry) );
433 return E_OUTOFMEMORY;
436 list_add_head( &priv->orphans, &entry->entry );
440 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
442 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
443 orphan_entry *entry, *entry2;
445 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
447 if( entry->node == node )
449 list_remove( &entry->entry );
458 static inline xmlDocPtr get_doc( domdoc *This )
460 return (xmlDocPtr)This->node.node;
463 static HRESULT attach_xmldoc(domdoc *This, xmlDocPtr xml )
467 priv_from_xmlDocPtr(get_doc(This))->properties = NULL;
468 if (xmldoc_release(get_doc(This)) != 0)
469 priv_from_xmlDocPtr(get_doc(This))->properties =
470 copy_properties(This->properties);
473 This->node.node = (xmlNodePtr) xml;
477 xmldoc_add_ref(get_doc(This));
478 priv_from_xmlDocPtr(get_doc(This))->properties = This->properties;
484 static inline domdoc *impl_from_IXMLDOMDocument3( IXMLDOMDocument3 *iface )
486 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
489 static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
491 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStreamInit));
494 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
496 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
499 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
501 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
504 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
506 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
509 /************************************************************************
510 * domdoc implementation of IPersistStream.
512 static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
513 IPersistStreamInit *iface, REFIID riid, void **ppvObj)
515 domdoc *this = impl_from_IPersistStreamInit(iface);
516 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
519 static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
520 IPersistStreamInit *iface)
522 domdoc *this = impl_from_IPersistStreamInit(iface);
523 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
526 static ULONG WINAPI domdoc_IPersistStreamInit_Release(
527 IPersistStreamInit *iface)
529 domdoc *this = impl_from_IPersistStreamInit(iface);
530 return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
533 static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
534 IPersistStreamInit *iface, CLSID *classid)
536 TRACE("(%p,%p): stub!\n", iface, classid);
541 *classid = CLSID_DOMDocument2;
546 static HRESULT WINAPI domdoc_IPersistStreamInit_IsDirty(
547 IPersistStreamInit *iface)
549 domdoc *This = impl_from_IPersistStreamInit(iface);
550 FIXME("(%p): stub!\n", This);
554 static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
555 IPersistStreamInit *iface, LPSTREAM pStm)
557 domdoc *This = impl_from_IPersistStreamInit(iface);
560 DWORD read, written, len;
563 xmlDocPtr xmldoc = NULL;
565 TRACE("(%p)->(%p)\n", This, pStm);
570 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
576 IStream_Read(pStm, buf, sizeof(buf), &read);
577 hr = IStream_Write(This->stream, buf, read, &written);
578 } while(SUCCEEDED(hr) && written != 0 && read != 0);
582 ERR("Failed to copy stream\n");
586 hr = GetHGlobalFromStream(This->stream, &hglobal);
590 len = GlobalSize(hglobal);
591 ptr = GlobalLock(hglobal);
593 xmldoc = doparse(This, ptr, len);
594 GlobalUnlock(hglobal);
598 ERR("Failed to parse xml\n");
602 xmldoc->_private = create_priv();
604 return attach_xmldoc(This, xmldoc);
607 static HRESULT WINAPI domdoc_IPersistStreamInit_Save(
608 IPersistStreamInit *iface, IStream *stream, BOOL clr_dirty)
610 domdoc *This = impl_from_IPersistStreamInit(iface);
614 TRACE("(%p)->(%p %d)\n", This, stream, clr_dirty);
616 hr = IXMLDOMDocument3_get_xml( (IXMLDOMDocument3*)&This->lpVtbl, &xmlString );
619 DWORD len = SysStringLen(xmlString) * sizeof(WCHAR);
621 hr = IStream_Write( stream, xmlString, len, NULL );
622 SysFreeString(xmlString);
625 TRACE("ret 0x%08x\n", hr);
630 static HRESULT WINAPI domdoc_IPersistStreamInit_GetSizeMax(
631 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
633 domdoc *This = impl_from_IPersistStreamInit(iface);
634 TRACE("(%p)->(%p): stub!\n", This, pcbSize);
638 static HRESULT WINAPI domdoc_IPersistStreamInit_InitNew(
639 IPersistStreamInit *iface)
641 domdoc *This = impl_from_IPersistStreamInit(iface);
642 TRACE("(%p)\n", This);
646 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
648 domdoc_IPersistStreamInit_QueryInterface,
649 domdoc_IPersistStreamInit_AddRef,
650 domdoc_IPersistStreamInit_Release,
651 domdoc_IPersistStreamInit_GetClassID,
652 domdoc_IPersistStreamInit_IsDirty,
653 domdoc_IPersistStreamInit_Load,
654 domdoc_IPersistStreamInit_Save,
655 domdoc_IPersistStreamInit_GetSizeMax,
656 domdoc_IPersistStreamInit_InitNew
659 /* ISupportErrorInfo interface */
660 static HRESULT WINAPI support_error_QueryInterface(
661 ISupportErrorInfo *iface,
662 REFIID riid, void** ppvObj )
664 domdoc *This = impl_from_ISupportErrorInfo(iface);
665 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3 *)This, riid, ppvObj);
668 static ULONG WINAPI support_error_AddRef(
669 ISupportErrorInfo *iface )
671 domdoc *This = impl_from_ISupportErrorInfo(iface);
672 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3 *)This);
675 static ULONG WINAPI support_error_Release(
676 ISupportErrorInfo *iface )
678 domdoc *This = impl_from_ISupportErrorInfo(iface);
679 return IXMLDOMDocument3_Release((IXMLDOMDocument3 *)This);
682 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
683 ISupportErrorInfo *iface,
686 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
690 static const struct ISupportErrorInfoVtbl support_error_vtbl =
692 support_error_QueryInterface,
693 support_error_AddRef,
694 support_error_Release,
695 support_error_InterfaceSupportsErrorInfo
698 /* IXMLDOMDocument2 interface */
699 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID riid, void** ppvObject )
701 domdoc *This = impl_from_IXMLDOMDocument3( iface );
703 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
707 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
708 IsEqualGUID( riid, &IID_IDispatch ) ||
709 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
710 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
711 IsEqualGUID( riid, &IID_IXMLDOMDocument2 )||
712 IsEqualGUID( riid, &IID_IXMLDOMDocument3 ))
716 else if (IsEqualGUID(&IID_IPersistStream, riid) ||
717 IsEqualGUID(&IID_IPersistStreamInit, riid))
719 *ppvObject = &(This->lpvtblIPersistStreamInit);
721 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
723 *ppvObject = &(This->lpvtblIObjectWithSite);
725 else if (IsEqualGUID(&IID_IObjectSafety, riid))
727 *ppvObject = &(This->lpvtblIObjectSafety);
729 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
731 *ppvObject = &This->lpvtblISupportErrorInfo;
733 else if(node_query_interface(&This->node, riid, ppvObject))
735 return *ppvObject ? S_OK : E_NOINTERFACE;
737 else if(IsEqualGUID(&IID_IRunnableObject, riid))
739 TRACE("IID_IRunnableObject not supported returning NULL\n");
740 return E_NOINTERFACE;
744 FIXME("interface %s not implemented\n", debugstr_guid(riid));
745 return E_NOINTERFACE;
748 IUnknown_AddRef((IUnknown*)*ppvObject);
754 static ULONG WINAPI domdoc_AddRef(
755 IXMLDOMDocument3 *iface )
757 domdoc *This = impl_from_IXMLDOMDocument3( iface );
758 TRACE("%p\n", This );
759 return InterlockedIncrement( &This->ref );
763 static ULONG WINAPI domdoc_Release(
764 IXMLDOMDocument3 *iface )
766 domdoc *This = impl_from_IXMLDOMDocument3( iface );
769 TRACE("%p\n", This );
771 ref = InterlockedDecrement( &This->ref );
775 detach_bsc(This->bsc);
778 IUnknown_Release( This->site );
779 destroy_xmlnode(&This->node);
780 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
781 if (This->stream) IStream_Release(This->stream);
782 HeapFree( GetProcessHeap(), 0, This );
788 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument3 *iface, UINT* pctinfo )
790 domdoc *This = impl_from_IXMLDOMDocument3( iface );
792 TRACE("(%p)->(%p)\n", This, pctinfo);
799 static HRESULT WINAPI domdoc_GetTypeInfo(
800 IXMLDOMDocument3 *iface,
801 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
803 domdoc *This = impl_from_IXMLDOMDocument3( iface );
806 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
808 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
813 static HRESULT WINAPI domdoc_GetIDsOfNames(
814 IXMLDOMDocument3 *iface,
821 domdoc *This = impl_from_IXMLDOMDocument3( iface );
825 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
828 if(!rgszNames || cNames == 0 || !rgDispId)
831 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
834 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
835 ITypeInfo_Release(typeinfo);
842 static HRESULT WINAPI domdoc_Invoke(
843 IXMLDOMDocument3 *iface,
848 DISPPARAMS* pDispParams,
850 EXCEPINFO* pExcepInfo,
853 domdoc *This = impl_from_IXMLDOMDocument3( iface );
857 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
858 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
860 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
863 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
864 pVarResult, pExcepInfo, puArgErr);
865 ITypeInfo_Release(typeinfo);
872 static HRESULT WINAPI domdoc_get_nodeName(
873 IXMLDOMDocument3 *iface,
876 domdoc *This = impl_from_IXMLDOMDocument3( iface );
878 static const WCHAR documentW[] = {'#','d','o','c','u','m','e','n','t',0};
880 TRACE("(%p)->(%p)\n", This, name);
882 return return_bstr(documentW, name);
886 static HRESULT WINAPI domdoc_get_nodeValue(
887 IXMLDOMDocument3 *iface,
890 domdoc *This = impl_from_IXMLDOMDocument3( iface );
892 TRACE("(%p)->(%p)\n", This, value);
897 V_VT(value) = VT_NULL;
898 V_BSTR(value) = NULL; /* tests show that we should do this */
903 static HRESULT WINAPI domdoc_put_nodeValue(
904 IXMLDOMDocument3 *iface,
907 domdoc *This = impl_from_IXMLDOMDocument3( iface );
908 FIXME("(%p)->(v%d)\n", This, V_VT(&value));
913 static HRESULT WINAPI domdoc_get_nodeType(
914 IXMLDOMDocument3 *iface,
917 domdoc *This = impl_from_IXMLDOMDocument3( iface );
919 TRACE("(%p)->(%p)\n", This, type);
921 *type = NODE_DOCUMENT;
926 static HRESULT WINAPI domdoc_get_parentNode(
927 IXMLDOMDocument3 *iface,
928 IXMLDOMNode** parent )
930 domdoc *This = impl_from_IXMLDOMDocument3( iface );
932 TRACE("(%p)->(%p)\n", This, parent);
934 return node_get_parent(&This->node, parent);
938 static HRESULT WINAPI domdoc_get_childNodes(
939 IXMLDOMDocument3 *iface,
940 IXMLDOMNodeList** childList )
942 domdoc *This = impl_from_IXMLDOMDocument3( iface );
944 TRACE("(%p)->(%p)\n", This, childList);
946 return node_get_child_nodes(&This->node, childList);
950 static HRESULT WINAPI domdoc_get_firstChild(
951 IXMLDOMDocument3 *iface,
952 IXMLDOMNode** firstChild )
954 domdoc *This = impl_from_IXMLDOMDocument3( iface );
956 TRACE("(%p)->(%p)\n", This, firstChild);
958 return node_get_first_child(&This->node, firstChild);
962 static HRESULT WINAPI domdoc_get_lastChild(
963 IXMLDOMDocument3 *iface,
964 IXMLDOMNode** lastChild )
966 domdoc *This = impl_from_IXMLDOMDocument3( iface );
968 TRACE("(%p)->(%p)\n", This, lastChild);
970 return node_get_last_child(&This->node, lastChild);
974 static HRESULT WINAPI domdoc_get_previousSibling(
975 IXMLDOMDocument3 *iface,
976 IXMLDOMNode** previousSibling )
978 domdoc *This = impl_from_IXMLDOMDocument3( iface );
980 TRACE("(%p)->(%p)\n", This, previousSibling);
982 return return_null_node(previousSibling);
986 static HRESULT WINAPI domdoc_get_nextSibling(
987 IXMLDOMDocument3 *iface,
988 IXMLDOMNode** nextSibling )
990 domdoc *This = impl_from_IXMLDOMDocument3( iface );
992 TRACE("(%p)->(%p)\n", This, nextSibling);
994 return return_null_node(nextSibling);
998 static HRESULT WINAPI domdoc_get_attributes(
999 IXMLDOMDocument3 *iface,
1000 IXMLDOMNamedNodeMap** attributeMap )
1002 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1004 TRACE("(%p)->(%p)\n", This, attributeMap);
1006 return return_null_ptr((void**)attributeMap);
1010 static HRESULT WINAPI domdoc_insertBefore(
1011 IXMLDOMDocument3 *iface,
1012 IXMLDOMNode* newChild,
1014 IXMLDOMNode** outNewChild )
1016 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1018 TRACE("(%p)->(%p x%d %p)\n", This, newChild, V_VT(&refChild), outNewChild);
1020 return node_insert_before(&This->node, newChild, &refChild, outNewChild);
1024 static HRESULT WINAPI domdoc_replaceChild(
1025 IXMLDOMDocument3 *iface,
1026 IXMLDOMNode* newChild,
1027 IXMLDOMNode* oldChild,
1028 IXMLDOMNode** outOldChild)
1030 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1031 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
1035 static HRESULT WINAPI domdoc_removeChild(
1036 IXMLDOMDocument3 *iface,
1037 IXMLDOMNode* childNode,
1038 IXMLDOMNode** oldChild)
1040 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1041 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
1045 static HRESULT WINAPI domdoc_appendChild(
1046 IXMLDOMDocument3 *iface,
1047 IXMLDOMNode* newChild,
1048 IXMLDOMNode** outNewChild)
1050 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1051 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
1055 static HRESULT WINAPI domdoc_hasChildNodes(
1056 IXMLDOMDocument3 *iface,
1057 VARIANT_BOOL* hasChild)
1059 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1060 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
1064 static HRESULT WINAPI domdoc_get_ownerDocument(
1065 IXMLDOMDocument3 *iface,
1066 IXMLDOMDocument** DOMDocument)
1068 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1069 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
1073 static HRESULT WINAPI domdoc_cloneNode(
1074 IXMLDOMDocument3 *iface,
1076 IXMLDOMNode** cloneRoot)
1078 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1079 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
1083 static HRESULT WINAPI domdoc_get_nodeTypeString(
1084 IXMLDOMDocument3 *iface,
1087 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1088 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
1092 static HRESULT WINAPI domdoc_get_text(
1093 IXMLDOMDocument3 *iface,
1096 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1097 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
1101 static HRESULT WINAPI domdoc_put_text(
1102 IXMLDOMDocument3 *iface,
1105 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1106 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
1110 static HRESULT WINAPI domdoc_get_specified(
1111 IXMLDOMDocument3 *iface,
1112 VARIANT_BOOL* isSpecified )
1114 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1115 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
1119 static HRESULT WINAPI domdoc_get_definition(
1120 IXMLDOMDocument3 *iface,
1121 IXMLDOMNode** definitionNode )
1123 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1124 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
1128 static HRESULT WINAPI domdoc_get_nodeTypedValue(
1129 IXMLDOMDocument3 *iface,
1130 VARIANT* typedValue )
1132 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1133 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
1136 static HRESULT WINAPI domdoc_put_nodeTypedValue(
1137 IXMLDOMDocument3 *iface,
1138 VARIANT typedValue )
1140 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1141 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
1145 static HRESULT WINAPI domdoc_get_dataType(
1146 IXMLDOMDocument3 *iface,
1147 VARIANT* dataTypeName )
1149 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1150 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
1154 static HRESULT WINAPI domdoc_put_dataType(
1155 IXMLDOMDocument3 *iface,
1158 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1159 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
1163 static HRESULT WINAPI domdoc_get_xml(
1164 IXMLDOMDocument3 *iface,
1167 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1168 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
1172 static HRESULT WINAPI domdoc_transformNode(
1173 IXMLDOMDocument3 *iface,
1174 IXMLDOMNode* styleSheet,
1177 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1178 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
1182 static HRESULT WINAPI domdoc_selectNodes(
1183 IXMLDOMDocument3 *iface,
1185 IXMLDOMNodeList** resultList )
1187 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1188 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
1192 static HRESULT WINAPI domdoc_selectSingleNode(
1193 IXMLDOMDocument3 *iface,
1195 IXMLDOMNode** resultNode )
1197 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1198 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
1202 static HRESULT WINAPI domdoc_get_parsed(
1203 IXMLDOMDocument3 *iface,
1204 VARIANT_BOOL* isParsed )
1206 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1207 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
1211 static HRESULT WINAPI domdoc_get_namespaceURI(
1212 IXMLDOMDocument3 *iface,
1213 BSTR* namespaceURI )
1215 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1216 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
1220 static HRESULT WINAPI domdoc_get_prefix(
1221 IXMLDOMDocument3 *iface,
1222 BSTR* prefixString )
1224 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1225 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
1229 static HRESULT WINAPI domdoc_get_baseName(
1230 IXMLDOMDocument3 *iface,
1233 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1234 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
1238 static HRESULT WINAPI domdoc_transformNodeToObject(
1239 IXMLDOMDocument3 *iface,
1240 IXMLDOMNode* stylesheet,
1241 VARIANT outputObject)
1243 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1244 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
1248 static HRESULT WINAPI domdoc_get_doctype(
1249 IXMLDOMDocument3 *iface,
1250 IXMLDOMDocumentType** documentType )
1252 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1253 FIXME("(%p)\n", This);
1258 static HRESULT WINAPI domdoc_get_implementation(
1259 IXMLDOMDocument3 *iface,
1260 IXMLDOMImplementation** impl )
1262 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1264 TRACE("(%p)->(%p)\n", This, impl);
1267 return E_INVALIDARG;
1269 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1274 static HRESULT WINAPI domdoc_get_documentElement(
1275 IXMLDOMDocument3 *iface,
1276 IXMLDOMElement** DOMElement )
1278 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1279 IXMLDOMNode *element_node;
1283 TRACE("(%p)->(%p)\n", This, DOMElement);
1286 return E_INVALIDARG;
1290 root = xmlDocGetRootElement( get_doc(This) );
1294 element_node = create_node( root );
1295 if(!element_node) return S_FALSE;
1297 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (void**)DOMElement);
1298 IXMLDOMNode_Release(element_node);
1304 static HRESULT WINAPI domdoc_put_documentElement(
1305 IXMLDOMDocument3 *iface,
1306 IXMLDOMElement* DOMElement )
1308 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1309 IXMLDOMNode *elementNode;
1314 TRACE("(%p)->(%p)\n", This, DOMElement);
1316 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1320 xmlNode = get_node_obj( elementNode );
1322 FIXME("elementNode is not our object\n");
1326 if(!xmlNode->node->parent)
1327 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1328 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1330 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1331 IXMLDOMNode_Release( elementNode );
1334 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1340 static HRESULT WINAPI domdoc_createElement(
1341 IXMLDOMDocument3 *iface,
1343 IXMLDOMElement** element )
1345 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1350 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1352 if (!element || !tagname) return E_INVALIDARG;
1354 V_VT(&type) = VT_I1;
1355 V_I1(&type) = NODE_ELEMENT;
1357 hr = IXMLDOMDocument3_createNode(iface, type, tagname, NULL, &node);
1360 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1361 IXMLDOMNode_Release(node);
1368 static HRESULT WINAPI domdoc_createDocumentFragment(
1369 IXMLDOMDocument3 *iface,
1370 IXMLDOMDocumentFragment** frag )
1372 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1377 TRACE("(%p)->(%p)\n", This, frag);
1379 if (!frag) return E_INVALIDARG;
1383 V_VT(&type) = VT_I1;
1384 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1386 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1389 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1390 IXMLDOMNode_Release(node);
1397 static HRESULT WINAPI domdoc_createTextNode(
1398 IXMLDOMDocument3 *iface,
1400 IXMLDOMText** text )
1402 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1407 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1409 if (!text) return E_INVALIDARG;
1413 V_VT(&type) = VT_I1;
1414 V_I1(&type) = NODE_TEXT;
1416 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1419 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1420 IXMLDOMNode_Release(node);
1421 hr = IXMLDOMText_put_data(*text, data);
1428 static HRESULT WINAPI domdoc_createComment(
1429 IXMLDOMDocument3 *iface,
1431 IXMLDOMComment** comment )
1433 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1438 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1440 if (!comment) return E_INVALIDARG;
1444 V_VT(&type) = VT_I1;
1445 V_I1(&type) = NODE_COMMENT;
1447 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1450 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1451 IXMLDOMNode_Release(node);
1452 hr = IXMLDOMComment_put_data(*comment, data);
1459 static HRESULT WINAPI domdoc_createCDATASection(
1460 IXMLDOMDocument3 *iface,
1462 IXMLDOMCDATASection** cdata )
1464 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1469 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1471 if (!cdata) return E_INVALIDARG;
1475 V_VT(&type) = VT_I1;
1476 V_I1(&type) = NODE_CDATA_SECTION;
1478 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1481 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1482 IXMLDOMNode_Release(node);
1483 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1490 static HRESULT WINAPI domdoc_createProcessingInstruction(
1491 IXMLDOMDocument3 *iface,
1494 IXMLDOMProcessingInstruction** pi )
1496 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1501 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1503 if (!pi) return E_INVALIDARG;
1507 V_VT(&type) = VT_I1;
1508 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1510 hr = IXMLDOMDocument3_createNode(iface, type, target, NULL, &node);
1516 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1517 node_obj = get_node_obj(node);
1518 V_VT(&v_data) = VT_BSTR;
1519 V_BSTR(&v_data) = data;
1521 hr = node_put_value(node_obj, &v_data);
1523 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1524 IXMLDOMNode_Release(node);
1531 static HRESULT WINAPI domdoc_createAttribute(
1532 IXMLDOMDocument3 *iface,
1534 IXMLDOMAttribute** attribute )
1536 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1541 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1543 if (!attribute || !name) return E_INVALIDARG;
1545 V_VT(&type) = VT_I1;
1546 V_I1(&type) = NODE_ATTRIBUTE;
1548 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1551 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1552 IXMLDOMNode_Release(node);
1559 static HRESULT WINAPI domdoc_createEntityReference(
1560 IXMLDOMDocument3 *iface,
1562 IXMLDOMEntityReference** entityref )
1564 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1569 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1571 if (!entityref) return E_INVALIDARG;
1575 V_VT(&type) = VT_I1;
1576 V_I1(&type) = NODE_ENTITY_REFERENCE;
1578 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1581 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1582 IXMLDOMNode_Release(node);
1589 static HRESULT WINAPI domdoc_getElementsByTagName(
1590 IXMLDOMDocument3 *iface,
1592 IXMLDOMNodeList** resultList )
1594 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1597 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1599 if (!tagName || !resultList) return E_INVALIDARG;
1601 if (tagName[0] == '*' && tagName[1] == 0)
1603 static const WCHAR formatallW[] = {'/','/','*',0};
1604 hr = queryresult_create((xmlNodePtr)get_doc(This), formatallW, resultList);
1608 static const WCHAR xpathformat[] =
1609 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
1610 static const WCHAR closeW[] = { '\'',']',0 };
1616 length = lstrlenW(tagName);
1618 /* without two WCHARs from format specifier */
1619 ptr = pattern = heap_alloc(sizeof(xpathformat) + length*sizeof(WCHAR) + sizeof(closeW));
1621 memcpy(ptr, xpathformat, sizeof(xpathformat));
1622 ptr += sizeof(xpathformat)/sizeof(WCHAR);
1623 memcpy(ptr, tagName, length*sizeof(WCHAR));
1625 memcpy(ptr, closeW, sizeof(closeW));
1627 hr = queryresult_create((xmlNodePtr)get_doc(This), pattern, resultList);
1634 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1640 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1642 return E_INVALIDARG;
1649 static HRESULT WINAPI domdoc_createNode(
1650 IXMLDOMDocument3 *iface,
1654 IXMLDOMNode** node )
1656 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1657 DOMNodeType node_type;
1659 xmlChar *xml_name, *href;
1662 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1664 if(!node) return E_INVALIDARG;
1666 hr = get_node_type(Type, &node_type);
1667 if(FAILED(hr)) return hr;
1669 if(namespaceURI && namespaceURI[0] && node_type != NODE_ELEMENT)
1670 FIXME("nodes with namespaces currently not supported.\n");
1672 TRACE("node_type %d\n", node_type);
1674 /* exit earlier for types that need name */
1678 case NODE_ATTRIBUTE:
1679 case NODE_ENTITY_REFERENCE:
1680 case NODE_PROCESSING_INSTRUCTION:
1681 if (!name || *name == 0) return E_FAIL;
1686 xml_name = xmlChar_from_wchar(name);
1687 /* prevent empty href to be allocated */
1688 href = namespaceURI ? xmlChar_from_wchar(namespaceURI) : NULL;
1694 xmlChar *local, *prefix;
1696 local = xmlSplitQName2(xml_name, &prefix);
1698 xmlnode = xmlNewDocNode(get_doc(This), NULL, local ? local : xml_name, NULL);
1700 /* allow to create default namespace xmlns= */
1701 if (local || (href && *href))
1703 xmlNsPtr ns = xmlNewNs(xmlnode, href, prefix);
1704 xmlSetNs(xmlnode, ns);
1712 case NODE_ATTRIBUTE:
1713 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1716 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1718 case NODE_CDATA_SECTION:
1719 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1721 case NODE_ENTITY_REFERENCE:
1722 xmlnode = xmlNewReference(get_doc(This), xml_name);
1724 case NODE_PROCESSING_INSTRUCTION:
1725 #ifdef HAVE_XMLNEWDOCPI
1726 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1728 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1733 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1735 case NODE_DOCUMENT_FRAGMENT:
1736 xmlnode = xmlNewDocFragment(get_doc(This));
1738 /* unsupported types */
1740 case NODE_DOCUMENT_TYPE:
1743 heap_free(xml_name);
1744 return E_INVALIDARG;
1746 FIXME("unhandled node type %d\n", node_type);
1751 *node = create_node(xmlnode);
1752 heap_free(xml_name);
1757 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1758 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1765 static HRESULT WINAPI domdoc_nodeFromID(
1766 IXMLDOMDocument3 *iface,
1768 IXMLDOMNode** node )
1770 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1771 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1775 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1780 xmldoc = doparse(This, ptr, len);
1782 xmldoc->_private = create_priv();
1783 return attach_xmldoc(This, xmldoc);
1789 static HRESULT doread( domdoc *This, LPWSTR filename )
1794 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1799 detach_bsc(This->bsc);
1805 static HRESULT WINAPI domdoc_load(
1806 IXMLDOMDocument3 *iface,
1808 VARIANT_BOOL* isSuccessful )
1810 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1811 LPWSTR filename = NULL;
1812 HRESULT hr = S_FALSE;
1813 IXMLDOMDocument3 *pNewDoc = NULL;
1814 IStream *pStream = NULL;
1817 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1819 *isSuccessful = VARIANT_FALSE;
1821 assert( &This->node );
1823 switch( V_VT(&xmlSource) )
1826 filename = V_BSTR(&xmlSource);
1829 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument3, (void**)&pNewDoc);
1834 domdoc *newDoc = impl_from_IXMLDOMDocument3( pNewDoc );
1835 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1836 hr = attach_xmldoc(This, xmldoc);
1839 *isSuccessful = VARIANT_TRUE;
1844 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1847 IPersistStream *pDocStream;
1848 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1851 hr = IPersistStream_Load(pDocStream, pStream);
1852 IStream_Release(pStream);
1855 *isSuccessful = VARIANT_TRUE;
1857 TRACE("Using IStream to load Document\n");
1862 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1867 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1872 /* ISequentialStream */
1873 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1877 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1880 TRACE("filename (%s)\n", debugstr_w(filename));
1884 hr = doread( This, filename );
1887 This->error = E_FAIL;
1890 hr = This->error = S_OK;
1891 *isSuccessful = VARIANT_TRUE;
1895 if(!filename || FAILED(hr)) {
1896 xmldoc = xmlNewDoc(NULL);
1897 xmldoc->_private = create_priv();
1898 hr = attach_xmldoc(This, xmldoc);
1903 TRACE("ret (%d)\n", hr);
1909 static HRESULT WINAPI domdoc_get_readyState(
1910 IXMLDOMDocument3 *iface,
1913 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1914 FIXME("stub! (%p)->(%p)\n", This, value);
1917 return E_INVALIDARG;
1919 *value = READYSTATE_COMPLETE;
1924 static HRESULT WINAPI domdoc_get_parseError(
1925 IXMLDOMDocument3 *iface,
1926 IXMLDOMParseError** errorObj )
1928 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1929 static const WCHAR err[] = {'e','r','r','o','r',0};
1930 BSTR error_string = NULL;
1932 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1935 error_string = SysAllocString(err);
1937 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1938 if(!*errorObj) return E_OUTOFMEMORY;
1943 static HRESULT WINAPI domdoc_get_url(
1944 IXMLDOMDocument3 *iface,
1947 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1948 FIXME("(%p)->(%p)\n", This, urlString);
1953 static HRESULT WINAPI domdoc_get_async(
1954 IXMLDOMDocument3 *iface,
1955 VARIANT_BOOL* isAsync )
1957 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1959 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1960 *isAsync = This->async;
1965 static HRESULT WINAPI domdoc_put_async(
1966 IXMLDOMDocument3 *iface,
1967 VARIANT_BOOL isAsync )
1969 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1971 TRACE("(%p)->(%d)\n", This, isAsync);
1972 This->async = isAsync;
1977 static HRESULT WINAPI domdoc_abort(
1978 IXMLDOMDocument3 *iface )
1980 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1981 FIXME("%p\n", This);
1986 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1991 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
1992 str = heap_alloc( len );
1995 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
2001 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2002 static HRESULT WINAPI domdoc_loadXML(
2003 IXMLDOMDocument3 *iface,
2005 VARIANT_BOOL* isSuccessful )
2007 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2008 xmlDocPtr xmldoc = NULL;
2009 HRESULT hr = S_FALSE, hr2;
2013 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
2015 assert ( &This->node );
2019 *isSuccessful = VARIANT_FALSE;
2021 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
2023 xmldoc = doparse(This, str, len);
2026 This->error = E_FAIL;
2029 hr = This->error = S_OK;
2030 *isSuccessful = VARIANT_TRUE;
2031 TRACE("parsed document %p\n", xmldoc);
2036 xmldoc = xmlNewDoc(NULL);
2038 xmldoc->_private = create_priv();
2040 hr2 = attach_xmldoc(This, xmldoc);
2047 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
2052 if(!WriteFile(ctx, buffer, len, &written, NULL))
2054 WARN("write error\n");
2061 static int XMLCALL domdoc_save_closecallback(void *ctx)
2063 return CloseHandle(ctx) ? 0 : -1;
2066 static HRESULT WINAPI domdoc_save(
2067 IXMLDOMDocument3 *iface,
2068 VARIANT destination )
2070 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2076 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
2077 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
2079 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
2081 FIXME("Unhandled vt %d\n", V_VT(&destination));
2085 if(V_VT(&destination) == VT_UNKNOWN)
2087 IUnknown *pUnk = V_UNKNOWN(&destination);
2088 IXMLDOMDocument2 *pDocument;
2090 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&pDocument);
2093 VARIANT_BOOL success;
2096 ret = IXMLDOMDocument3_get_xml(iface, &xml);
2099 ret = IXMLDOMDocument3_loadXML(pDocument, xml, &success);
2103 IXMLDOMDocument3_Release(pDocument);
2106 TRACE("ret %d\n", ret);
2111 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
2112 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
2113 if( handle == INVALID_HANDLE_VALUE )
2115 WARN("failed to create file\n");
2119 /* disable top XML declaration */
2120 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
2121 handle, NULL, XML_SAVE_NO_DECL);
2124 CloseHandle(handle);
2128 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
2129 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
2130 xmldoc_link_xmldecl(get_doc(This), xmldecl);
2132 /* will close file through close callback */
2138 static HRESULT WINAPI domdoc_get_validateOnParse(
2139 IXMLDOMDocument3 *iface,
2140 VARIANT_BOOL* isValidating )
2142 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2143 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
2144 *isValidating = This->validating;
2149 static HRESULT WINAPI domdoc_put_validateOnParse(
2150 IXMLDOMDocument3 *iface,
2151 VARIANT_BOOL isValidating )
2153 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2154 TRACE("(%p)->(%d)\n", This, isValidating);
2155 This->validating = isValidating;
2160 static HRESULT WINAPI domdoc_get_resolveExternals(
2161 IXMLDOMDocument3 *iface,
2162 VARIANT_BOOL* isResolving )
2164 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2165 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
2166 *isResolving = This->resolving;
2171 static HRESULT WINAPI domdoc_put_resolveExternals(
2172 IXMLDOMDocument3 *iface,
2173 VARIANT_BOOL isResolving )
2175 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2176 TRACE("(%p)->(%d)\n", This, isResolving);
2177 This->resolving = isResolving;
2182 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
2183 IXMLDOMDocument3 *iface,
2184 VARIANT_BOOL* isPreserving )
2186 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2187 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
2188 *isPreserving = This->preserving;
2193 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
2194 IXMLDOMDocument3 *iface,
2195 VARIANT_BOOL isPreserving )
2197 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2198 TRACE("(%p)->(%d)\n", This, isPreserving);
2199 This->preserving = isPreserving;
2204 static HRESULT WINAPI domdoc_put_onReadyStateChange(
2205 IXMLDOMDocument3 *iface,
2206 VARIANT readyStateChangeSink )
2208 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2209 FIXME("%p\n", This);
2214 static HRESULT WINAPI domdoc_put_onDataAvailable(
2215 IXMLDOMDocument3 *iface,
2216 VARIANT onDataAvailableSink )
2218 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2219 FIXME("%p\n", This);
2223 static HRESULT WINAPI domdoc_put_onTransformNode(
2224 IXMLDOMDocument3 *iface,
2225 VARIANT onTransformNodeSink )
2227 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2228 FIXME("%p\n", This);
2232 static HRESULT WINAPI domdoc_get_namespaces(
2233 IXMLDOMDocument3* iface,
2234 IXMLDOMSchemaCollection** schemaCollection )
2236 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2237 FIXME("(%p)->(%p)\n", This, schemaCollection);
2241 static HRESULT WINAPI domdoc_get_schemas(
2242 IXMLDOMDocument3* iface,
2245 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2246 HRESULT hr = S_FALSE;
2247 IXMLDOMSchemaCollection *cur_schema = This->schema;
2249 TRACE("(%p)->(%p)\n", This, var1);
2251 VariantInit(var1); /* Test shows we don't call VariantClear here */
2252 V_VT(var1) = VT_NULL;
2256 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
2258 V_VT(var1) = VT_DISPATCH;
2263 static HRESULT WINAPI domdoc_putref_schemas(
2264 IXMLDOMDocument3* iface,
2267 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2268 HRESULT hr = E_FAIL;
2269 IXMLDOMSchemaCollection *new_schema = NULL;
2271 FIXME("(%p): semi-stub\n", This);
2275 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2279 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2288 WARN("Can't get schema from vt %x\n", V_VT(&var1));
2293 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
2294 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
2300 static HRESULT WINAPI domdoc_validate(
2301 IXMLDOMDocument3* iface,
2302 IXMLDOMParseError** err)
2304 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2306 xmlValidCtxtPtr vctx;
2308 TRACE("(%p)->(%p)\n", This, err);
2309 domdoc_get_readyState(iface, &state);
2310 if (state != READYSTATE_COMPLETE)
2313 *err = create_parseError(0, NULL, NULL, NULL, 0, 0, 0);
2317 vctx = xmlNewValidCtxt();
2318 vctx->error = NULL; /* TODO: error callback */
2319 vctx->warning = NULL; /* TODO: warning callback */
2321 if (xmlValidateDocument(vctx, get_doc(This)))
2324 *err = create_parseError(0, NULL, NULL, NULL, 0, 0, 0);
2325 xmlFreeValidCtxt(vctx);
2329 FIXME("partial stub!\n");
2331 *err = create_parseError(0xC00CE223, NULL, NULL, NULL, 0, 0, 0);
2332 xmlFreeValidCtxt(vctx);
2336 static HRESULT WINAPI domdoc_setProperty(
2337 IXMLDOMDocument3* iface,
2341 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2343 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
2345 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2351 V_VT(&varStr) = VT_EMPTY;
2352 if (V_VT(&var) != VT_BSTR)
2354 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2356 bstr = V_BSTR(&varStr);
2359 bstr = V_BSTR(&var);
2362 if (lstrcmpiW(bstr, PropValueXPathW) == 0)
2363 This->properties->XPath = TRUE;
2364 else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
2365 This->properties->XPath = FALSE;
2369 VariantClear(&varStr);
2372 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2377 xmlChar *pTokBegin, *pTokEnd, *pTokInner;
2378 xmlChar *nsStr = (xmlChar*)This->properties->selectNsStr;
2379 xmlXPathContextPtr ctx;
2380 struct list *pNsList;
2381 select_ns_entry* pNsEntry = NULL;
2383 V_VT(&varStr) = VT_EMPTY;
2384 if (V_VT(&var) != VT_BSTR)
2386 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2388 bstr = V_BSTR(&varStr);
2391 bstr = V_BSTR(&var);
2395 pNsList = &(This->properties->selectNsList);
2396 clear_selectNsList(pNsList);
2398 nsStr = xmlChar_from_wchar(bstr);
2401 TRACE("Setting SelectionNamespaces property to: %s\n", nsStr);
2403 This->properties->selectNsStr = nsStr;
2404 This->properties->selectNsStr_len = xmlStrlen(nsStr);
2407 ctx = xmlXPathNewContext(This->node.node->doc);
2410 for (; *pTokBegin; pTokBegin = pTokEnd)
2412 if (pNsEntry != NULL)
2413 memset(pNsEntry, 0, sizeof(select_ns_entry));
2415 pNsEntry = heap_alloc_zero(sizeof(select_ns_entry));
2417 while (*pTokBegin == ' ')
2419 pTokEnd = pTokBegin;
2420 while (*pTokEnd != ' ' && *pTokEnd != 0)
2423 if (xmlStrncmp(pTokBegin, (xmlChar const*)"xmlns", 5) != 0)
2426 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2427 wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokBegin, pTokEnd-pTokBegin));
2432 if (*pTokBegin == '=')
2434 /*valid for XSLPattern?*/
2435 FIXME("Setting default xmlns not supported - skipping.\n");
2436 pTokBegin = pTokEnd;
2439 else if (*pTokBegin == ':')
2441 pNsEntry->prefix = ++pTokBegin;
2442 for (pTokInner = pTokBegin; pTokInner != pTokEnd && *pTokInner != '='; ++pTokInner)
2445 if (pTokInner == pTokEnd)
2448 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2449 wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokBegin, pTokEnd-pTokBegin));
2453 pNsEntry->prefix_end = *pTokInner;
2457 if (pTokEnd-pTokInner > 1 &&
2458 ((*pTokInner == '\'' && *(pTokEnd-1) == '\'') ||
2459 (*pTokInner == '"' && *(pTokEnd-1) == '"')))
2461 pNsEntry->href = ++pTokInner;
2462 pNsEntry->href_end = *(pTokEnd-1);
2464 list_add_tail(pNsList, &pNsEntry->entry);
2465 /*let libxml figure out if they're valid from here ;)*/
2466 if (xmlXPathRegisterNs(ctx, pNsEntry->prefix, pNsEntry->href) != 0)
2475 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2476 wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokInner, pTokEnd-pTokInner));
2477 list_add_tail(pNsList, &pNsEntry->entry);
2490 heap_free(pNsEntry);
2491 xmlXPathFreeContext(ctx);
2494 VariantClear(&varStr);
2497 else if (lstrcmpiW(p, PropertyProhibitDTDW) == 0)
2500 FIXME("Ignoring property ProhibitDTD, value %d\n", V_BOOL(&var));
2504 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2508 static HRESULT WINAPI domdoc_getProperty(
2509 IXMLDOMDocument3* iface,
2513 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2515 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2518 return E_INVALIDARG;
2520 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2522 V_VT(var) = VT_BSTR;
2523 V_BSTR(var) = This->properties->XPath ?
2524 SysAllocString(PropValueXPathW) :
2525 SysAllocString(PropValueXSLPatternW);
2526 return V_BSTR(var) ? S_OK : E_OUTOFMEMORY;
2528 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2531 BSTR rebuiltStr, cur;
2532 const xmlChar *nsStr;
2533 struct list *pNsList;
2534 select_ns_entry* pNsEntry;
2536 V_VT(var) = VT_BSTR;
2537 nsStr = This->properties->selectNsStr;
2538 pNsList = &This->properties->selectNsList;
2539 lenA = This->properties->selectNsStr_len;
2540 lenW = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, NULL, 0);
2541 rebuiltStr = heap_alloc(lenW*sizeof(WCHAR));
2542 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, rebuiltStr, lenW);
2544 /* this is fine because all of the chars that end tokens are ASCII*/
2545 LIST_FOR_EACH_ENTRY(pNsEntry, pNsList, select_ns_entry, entry)
2547 while (*cur != 0) ++cur;
2548 if (pNsEntry->prefix_end)
2550 *cur = pNsEntry->prefix_end;
2551 while (*cur != 0) ++cur;
2554 if (pNsEntry->href_end)
2556 *cur = pNsEntry->href_end;
2559 V_BSTR(var) = SysAllocString(rebuiltStr);
2560 heap_free(rebuiltStr);
2564 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2568 static HRESULT WINAPI domdoc_validateNode(
2569 IXMLDOMDocument3* iface,
2571 IXMLDOMParseError** error)
2573 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2574 FIXME("(%p)->(%p %p): stub\n", This, node, error);
2578 static HRESULT WINAPI domdoc_importNode(
2579 IXMLDOMDocument3* iface,
2582 IXMLDOMNode** clone)
2584 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2585 FIXME("(%p)->(%p %d %p): stub\n", This, node, deep, clone);
2589 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl =
2591 domdoc_QueryInterface,
2594 domdoc_GetTypeInfoCount,
2596 domdoc_GetIDsOfNames,
2598 domdoc_get_nodeName,
2599 domdoc_get_nodeValue,
2600 domdoc_put_nodeValue,
2601 domdoc_get_nodeType,
2602 domdoc_get_parentNode,
2603 domdoc_get_childNodes,
2604 domdoc_get_firstChild,
2605 domdoc_get_lastChild,
2606 domdoc_get_previousSibling,
2607 domdoc_get_nextSibling,
2608 domdoc_get_attributes,
2609 domdoc_insertBefore,
2610 domdoc_replaceChild,
2613 domdoc_hasChildNodes,
2614 domdoc_get_ownerDocument,
2616 domdoc_get_nodeTypeString,
2619 domdoc_get_specified,
2620 domdoc_get_definition,
2621 domdoc_get_nodeTypedValue,
2622 domdoc_put_nodeTypedValue,
2623 domdoc_get_dataType,
2624 domdoc_put_dataType,
2626 domdoc_transformNode,
2628 domdoc_selectSingleNode,
2630 domdoc_get_namespaceURI,
2632 domdoc_get_baseName,
2633 domdoc_transformNodeToObject,
2635 domdoc_get_implementation,
2636 domdoc_get_documentElement,
2637 domdoc_put_documentElement,
2638 domdoc_createElement,
2639 domdoc_createDocumentFragment,
2640 domdoc_createTextNode,
2641 domdoc_createComment,
2642 domdoc_createCDATASection,
2643 domdoc_createProcessingInstruction,
2644 domdoc_createAttribute,
2645 domdoc_createEntityReference,
2646 domdoc_getElementsByTagName,
2650 domdoc_get_readyState,
2651 domdoc_get_parseError,
2658 domdoc_get_validateOnParse,
2659 domdoc_put_validateOnParse,
2660 domdoc_get_resolveExternals,
2661 domdoc_put_resolveExternals,
2662 domdoc_get_preserveWhiteSpace,
2663 domdoc_put_preserveWhiteSpace,
2664 domdoc_put_onReadyStateChange,
2665 domdoc_put_onDataAvailable,
2666 domdoc_put_onTransformNode,
2667 domdoc_get_namespaces,
2669 domdoc_putref_schemas,
2673 domdoc_validateNode,
2677 /* xmldoc implementation of IObjectWithSite */
2678 static HRESULT WINAPI
2679 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2681 domdoc *This = impl_from_IObjectWithSite(iface);
2682 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2686 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2688 domdoc *This = impl_from_IObjectWithSite(iface);
2689 return IXMLDocument_AddRef((IXMLDocument *)This);
2693 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2695 domdoc *This = impl_from_IObjectWithSite(iface);
2696 return IXMLDocument_Release((IXMLDocument *)This);
2699 static HRESULT WINAPI
2700 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2702 domdoc *This = impl_from_IObjectWithSite(iface);
2704 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2709 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2712 static HRESULT WINAPI
2713 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2715 domdoc *This = impl_from_IObjectWithSite(iface);
2717 TRACE("(%p)->(%p)\n", iface, punk);
2723 IUnknown_Release( This->site );
2730 IUnknown_AddRef( punk );
2733 IUnknown_Release( This->site );
2740 static const IObjectWithSiteVtbl domdocObjectSite =
2742 xmldoc_ObjectWithSite_QueryInterface,
2743 xmldoc_ObjectWithSite_AddRef,
2744 xmldoc_ObjectWithSite_Release,
2749 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2751 domdoc *This = impl_from_IObjectSafety(iface);
2752 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2755 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2757 domdoc *This = impl_from_IObjectSafety(iface);
2758 return IXMLDocument_AddRef((IXMLDocument *)This);
2761 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2763 domdoc *This = impl_from_IObjectSafety(iface);
2764 return IXMLDocument_Release((IXMLDocument *)This);
2767 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2769 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2770 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2772 domdoc *This = impl_from_IObjectSafety(iface);
2774 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2776 if(!pdwSupportedOptions || !pdwEnabledOptions)
2779 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2780 *pdwEnabledOptions = This->safeopt;
2785 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2786 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2788 domdoc *This = impl_from_IObjectSafety(iface);
2789 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2791 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2794 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2798 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2799 xmldoc_Safety_QueryInterface,
2800 xmldoc_Safety_AddRef,
2801 xmldoc_Safety_Release,
2802 xmldoc_Safety_GetInterfaceSafetyOptions,
2803 xmldoc_Safety_SetInterfaceSafetyOptions
2807 static const tid_t domdoc_iface_tids[] = {
2809 IXMLDOMDocument_tid,
2810 IXMLDOMDocument2_tid,
2813 static dispex_static_data_t domdoc_dispex = {
2815 IXMLDOMDocument2_tid,
2820 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
2824 doc = heap_alloc( sizeof (*doc) );
2826 return E_OUTOFMEMORY;
2828 doc->lpVtbl = &domdoc_vtbl;
2829 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
2830 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2831 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2832 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2834 doc->async = VARIANT_TRUE;
2835 doc->validating = 0;
2837 doc->preserving = 0;
2838 doc->properties = properties_from_xmlDocPtr(xmldoc);
2846 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IXMLDOMNode*)&doc->lpVtbl, &domdoc_dispex);
2848 *document = (IXMLDOMDocument3*)&doc->lpVtbl;
2850 TRACE("returning iface %p\n", *document);
2854 HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
2859 TRACE("(%s, %p, %p)\n", debugstr_guid(clsid), pUnkOuter, ppObj);
2861 xmldoc = xmlNewDoc(NULL);
2863 return E_OUTOFMEMORY;
2865 xmldoc->_private = create_priv();
2866 priv_from_xmlDocPtr(xmldoc)->properties = create_properties(clsid);
2868 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument3**)ppObj);
2878 IUnknown* create_domdoc( xmlNodePtr document )
2883 TRACE("(%p)\n", document);
2885 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj);
2894 HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
2896 MESSAGE("This program tried to use a DOMDocument object, but\n"
2897 "libxml2 support was not present at compile time.\n");