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 PropertyNewParserW[] = {'N','e','w','P','a','r','s','e','r',0};
68 static const WCHAR PropValueXPathW[] = {'X','P','a','t','h',0};
69 static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r','n',0};
71 /* Data used by domdoc_getProperty()/domdoc_setProperty().
72 * We need to preserve this when reloading a document,
73 * and also need access to it from the libxml backend. */
74 typedef struct _domdoc_properties {
75 struct list selectNsList;
76 xmlChar const* selectNsStr;
81 typedef struct _domdoc
84 const struct IXMLDOMDocument3Vtbl *lpVtbl;
85 const struct IPersistStreamInitVtbl *lpvtblIPersistStreamInit;
86 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
87 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
88 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
91 VARIANT_BOOL validating;
92 VARIANT_BOOL resolving;
93 VARIANT_BOOL preserving;
94 domdoc_properties* properties;
95 IXMLDOMSchemaCollection *schema;
110 In native windows, the whole lifetime management of XMLDOMNodes is
111 managed automatically using reference counts. Wine emulates that by
112 maintaining a reference count to the document that is increased for
113 each IXMLDOMNode pointer passed out for this document. If all these
114 pointers are gone, the document is unreachable and gets freed, that
115 is, all nodes in the tree of the document get freed.
117 You are able to create nodes that are associated to a document (in
118 fact, in msxml's XMLDOM model, all nodes are associated to a document),
119 but not in the tree of that document, for example using the createFoo
120 functions from IXMLDOMDocument. These nodes do not get cleaned up
121 by libxml, so we have to do it ourselves.
123 To catch these nodes, a list of "orphan nodes" is introduced.
124 It contains pointers to all roots of node trees that are
125 associated with the document without being part of the document
126 tree. All nodes with parent==NULL (except for the document root nodes)
127 should be in the orphan node list of their document. All orphan nodes
128 get freed together with the document itself.
131 typedef struct _xmldoc_priv {
134 domdoc_properties* properties;
137 typedef struct _orphan_entry {
142 typedef struct _select_ns_entry {
144 xmlChar const* prefix;
150 static inline xmldoc_priv * priv_from_xmlDocPtr(const xmlDocPtr doc)
152 return doc->_private;
155 static inline domdoc_properties * properties_from_xmlDocPtr(xmlDocPtr doc)
157 return priv_from_xmlDocPtr(doc)->properties;
160 BOOL is_xpathmode(const xmlDocPtr doc)
162 return properties_from_xmlDocPtr(doc)->XPath;
165 int registerNamespaces(xmlXPathContextPtr ctxt)
168 const select_ns_entry* ns = NULL;
169 const struct list* pNsList = &properties_from_xmlDocPtr(ctxt->doc)->selectNsList;
171 TRACE("(%p)\n", ctxt);
173 LIST_FOR_EACH_ENTRY( ns, pNsList, select_ns_entry, entry )
175 xmlXPathRegisterNs(ctxt, ns->prefix, ns->href);
182 static inline void clear_selectNsList(struct list* pNsList)
184 select_ns_entry *ns, *ns2;
185 LIST_FOR_EACH_ENTRY_SAFE( ns, ns2, pNsList, select_ns_entry, entry )
192 static xmldoc_priv * create_priv(void)
195 priv = heap_alloc( sizeof (*priv) );
200 list_init( &priv->orphans );
201 priv->properties = NULL;
207 static domdoc_properties * create_properties(const GUID *clsid)
209 domdoc_properties *properties = heap_alloc(sizeof(domdoc_properties));
211 list_init( &properties->selectNsList );
212 properties->selectNsStr = heap_alloc_zero(sizeof(xmlChar));
213 properties->selectNsStr_len = 0;
214 properties->XPath = FALSE;
216 /* properties that are dependent on object versions */
217 if (IsEqualCLSID( clsid, &CLSID_DOMDocument40 ) ||
218 IsEqualCLSID( clsid, &CLSID_DOMDocument60 ))
220 properties->XPath = TRUE;
226 static domdoc_properties* copy_properties(domdoc_properties const* properties)
228 domdoc_properties* pcopy = heap_alloc(sizeof(domdoc_properties));
229 select_ns_entry const* ns = NULL;
230 select_ns_entry* new_ns = NULL;
231 int len = (properties->selectNsStr_len+1)*sizeof(xmlChar);
236 pcopy->XPath = properties->XPath;
237 pcopy->selectNsStr_len = properties->selectNsStr_len;
238 list_init( &pcopy->selectNsList );
239 pcopy->selectNsStr = heap_alloc(len);
240 memcpy((xmlChar*)pcopy->selectNsStr, properties->selectNsStr, len);
241 offset = pcopy->selectNsStr - properties->selectNsStr;
243 LIST_FOR_EACH_ENTRY( ns, (&properties->selectNsList), select_ns_entry, entry )
245 new_ns = heap_alloc(sizeof(select_ns_entry));
246 memcpy(new_ns, ns, sizeof(select_ns_entry));
247 new_ns->href += offset;
248 new_ns->prefix += offset;
249 list_add_tail(&pcopy->selectNsList, &new_ns->entry);
257 static void free_properties(domdoc_properties* properties)
261 clear_selectNsList(&properties->selectNsList);
262 heap_free((xmlChar*)properties->selectNsStr);
263 heap_free(properties);
267 /* links a "<?xml" node as a first child */
268 void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
271 if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
274 /* unlinks a first "<?xml" child if it was created */
275 xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
281 if (doc->standalone != -1)
283 node = doc->children;
284 xmlUnlinkNode( node );
292 static inline BOOL strn_isspace(xmlChar const* str, int len)
294 for (; str && len > 0 && *str; ++str, --len)
301 static void sax_characters(void *ctx, const xmlChar *ch, int len)
303 xmlParserCtxtPtr pctx;
306 pctx = (xmlParserCtxtPtr) ctx;
307 This = (domdoc const*) pctx->_private;
309 if (!This->preserving)
311 xmlChar* ws = xmlGetNsProp(pctx->node, BAD_CAST "space", XML_XML_NAMESPACE);
312 if ((!ws || xmlStrcmp(ws, BAD_CAST "preserve") != 0) &&
313 strn_isspace(ch, len))
321 xmlSAX2Characters(ctx, ch, len);
324 static xmlDocPtr doparse(domdoc* This, char *ptr, int len)
327 static xmlSAXHandler sax_handler = {
328 xmlSAX2InternalSubset, /* internalSubset */
329 xmlSAX2IsStandalone, /* isStandalone */
330 xmlSAX2HasInternalSubset, /* hasInternalSubset */
331 xmlSAX2HasExternalSubset, /* hasExternalSubset */
332 xmlSAX2ResolveEntity, /* resolveEntity */
333 xmlSAX2GetEntity, /* getEntity */
334 xmlSAX2EntityDecl, /* entityDecl */
335 xmlSAX2NotationDecl, /* notationDecl */
336 xmlSAX2AttributeDecl, /* attributeDecl */
337 xmlSAX2ElementDecl, /* elementDecl */
338 xmlSAX2UnparsedEntityDecl, /* unparsedEntityDecl */
339 xmlSAX2SetDocumentLocator, /* setDocumentLocator */
340 xmlSAX2StartDocument, /* startDocument */
341 xmlSAX2EndDocument, /* endDocument */
342 xmlSAX2StartElement, /* startElement */
343 xmlSAX2EndElement, /* endElement */
344 xmlSAX2Reference, /* reference */
345 sax_characters, /* characters */
346 sax_characters, /* ignorableWhitespace */
347 xmlSAX2ProcessingInstruction, /* processingInstruction */
348 xmlSAX2Comment, /* comment */
349 NULL, /* TODO: warning */
350 NULL, /* TODO: error */
351 NULL, /* TODO: fatalError */
352 xmlSAX2GetParameterEntity, /* getParameterEntity */
353 xmlSAX2CDataBlock, /* cdataBlock */
354 xmlSAX2ExternalSubset, /* externalSubset */
357 xmlSAX2StartElementNs, /* startElementNs */
358 xmlSAX2EndElementNs, /* endElementNs */
359 NULL /* TODO: serror */
362 doc = xmlSAXParseMemoryWithData(&sax_handler, ptr, len, 0, This);
364 /* TODO: put this in one of the SAX callbacks */
365 /* create first child as a <?xml...?> */
366 if (doc && doc->standalone != -1)
370 xmlChar *xmlbuff = (xmlChar*)buff;
372 node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL );
374 /* version attribute can't be omitted */
375 sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0");
376 xmlNodeAddContent( node, xmlbuff );
380 sprintf(buff, " encoding=\"%s\"", doc->encoding);
381 xmlNodeAddContent( node, xmlbuff );
384 if (doc->standalone != -2)
386 sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes");
387 xmlNodeAddContent( node, xmlbuff );
390 xmldoc_link_xmldecl( doc, node );
396 LONG xmldoc_add_ref(xmlDocPtr doc)
398 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
399 TRACE("(%p)->(%d)\n", doc, ref);
403 LONG xmldoc_release(xmlDocPtr doc)
405 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
406 LONG ref = InterlockedDecrement(&priv->refs);
407 TRACE("(%p)->(%d)\n", doc, ref);
410 orphan_entry *orphan, *orphan2;
411 TRACE("freeing docptr %p\n", doc);
413 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
415 xmlFreeNode( orphan->node );
418 free_properties(priv->properties);
419 heap_free(doc->_private);
427 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
429 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
432 entry = heap_alloc( sizeof (*entry) );
434 return E_OUTOFMEMORY;
437 list_add_head( &priv->orphans, &entry->entry );
441 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
443 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
444 orphan_entry *entry, *entry2;
446 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
448 if( entry->node == node )
450 list_remove( &entry->entry );
459 static inline xmlDocPtr get_doc( domdoc *This )
461 return (xmlDocPtr)This->node.node;
464 static HRESULT attach_xmldoc(domdoc *This, xmlDocPtr xml )
468 priv_from_xmlDocPtr(get_doc(This))->properties = NULL;
469 if (xmldoc_release(get_doc(This)) != 0)
470 priv_from_xmlDocPtr(get_doc(This))->properties =
471 copy_properties(This->properties);
474 This->node.node = (xmlNodePtr) xml;
478 xmldoc_add_ref(get_doc(This));
479 priv_from_xmlDocPtr(get_doc(This))->properties = This->properties;
485 static inline domdoc *impl_from_IXMLDOMDocument3( IXMLDOMDocument3 *iface )
487 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
490 static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
492 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStreamInit));
495 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
497 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
500 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
502 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
505 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
507 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
510 /************************************************************************
511 * domdoc implementation of IPersistStream.
513 static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
514 IPersistStreamInit *iface, REFIID riid, void **ppvObj)
516 domdoc *this = impl_from_IPersistStreamInit(iface);
517 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
520 static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
521 IPersistStreamInit *iface)
523 domdoc *this = impl_from_IPersistStreamInit(iface);
524 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
527 static ULONG WINAPI domdoc_IPersistStreamInit_Release(
528 IPersistStreamInit *iface)
530 domdoc *this = impl_from_IPersistStreamInit(iface);
531 return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
534 static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
535 IPersistStreamInit *iface, CLSID *classid)
537 TRACE("(%p,%p): stub!\n", iface, classid);
542 *classid = CLSID_DOMDocument2;
547 static HRESULT WINAPI domdoc_IPersistStreamInit_IsDirty(
548 IPersistStreamInit *iface)
550 domdoc *This = impl_from_IPersistStreamInit(iface);
551 FIXME("(%p): stub!\n", This);
555 static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
556 IPersistStreamInit *iface, LPSTREAM pStm)
558 domdoc *This = impl_from_IPersistStreamInit(iface);
561 DWORD read, written, len;
564 xmlDocPtr xmldoc = NULL;
566 TRACE("(%p)->(%p)\n", This, pStm);
571 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
577 IStream_Read(pStm, buf, sizeof(buf), &read);
578 hr = IStream_Write(This->stream, buf, read, &written);
579 } while(SUCCEEDED(hr) && written != 0 && read != 0);
583 ERR("Failed to copy stream\n");
587 hr = GetHGlobalFromStream(This->stream, &hglobal);
591 len = GlobalSize(hglobal);
592 ptr = GlobalLock(hglobal);
594 xmldoc = doparse(This, ptr, len);
595 GlobalUnlock(hglobal);
599 ERR("Failed to parse xml\n");
603 xmldoc->_private = create_priv();
605 return attach_xmldoc(This, xmldoc);
608 static HRESULT WINAPI domdoc_IPersistStreamInit_Save(
609 IPersistStreamInit *iface, IStream *stream, BOOL clr_dirty)
611 domdoc *This = impl_from_IPersistStreamInit(iface);
615 TRACE("(%p)->(%p %d)\n", This, stream, clr_dirty);
617 hr = IXMLDOMDocument3_get_xml( (IXMLDOMDocument3*)&This->lpVtbl, &xmlString );
620 DWORD len = SysStringLen(xmlString) * sizeof(WCHAR);
622 hr = IStream_Write( stream, xmlString, len, NULL );
623 SysFreeString(xmlString);
626 TRACE("ret 0x%08x\n", hr);
631 static HRESULT WINAPI domdoc_IPersistStreamInit_GetSizeMax(
632 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
634 domdoc *This = impl_from_IPersistStreamInit(iface);
635 TRACE("(%p)->(%p): stub!\n", This, pcbSize);
639 static HRESULT WINAPI domdoc_IPersistStreamInit_InitNew(
640 IPersistStreamInit *iface)
642 domdoc *This = impl_from_IPersistStreamInit(iface);
643 TRACE("(%p)\n", This);
647 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
649 domdoc_IPersistStreamInit_QueryInterface,
650 domdoc_IPersistStreamInit_AddRef,
651 domdoc_IPersistStreamInit_Release,
652 domdoc_IPersistStreamInit_GetClassID,
653 domdoc_IPersistStreamInit_IsDirty,
654 domdoc_IPersistStreamInit_Load,
655 domdoc_IPersistStreamInit_Save,
656 domdoc_IPersistStreamInit_GetSizeMax,
657 domdoc_IPersistStreamInit_InitNew
660 /* ISupportErrorInfo interface */
661 static HRESULT WINAPI support_error_QueryInterface(
662 ISupportErrorInfo *iface,
663 REFIID riid, void** ppvObj )
665 domdoc *This = impl_from_ISupportErrorInfo(iface);
666 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3 *)This, riid, ppvObj);
669 static ULONG WINAPI support_error_AddRef(
670 ISupportErrorInfo *iface )
672 domdoc *This = impl_from_ISupportErrorInfo(iface);
673 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3 *)This);
676 static ULONG WINAPI support_error_Release(
677 ISupportErrorInfo *iface )
679 domdoc *This = impl_from_ISupportErrorInfo(iface);
680 return IXMLDOMDocument3_Release((IXMLDOMDocument3 *)This);
683 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
684 ISupportErrorInfo *iface,
687 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
691 static const struct ISupportErrorInfoVtbl support_error_vtbl =
693 support_error_QueryInterface,
694 support_error_AddRef,
695 support_error_Release,
696 support_error_InterfaceSupportsErrorInfo
699 /* IXMLDOMDocument2 interface */
700 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID riid, void** ppvObject )
702 domdoc *This = impl_from_IXMLDOMDocument3( iface );
704 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
708 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
709 IsEqualGUID( riid, &IID_IDispatch ) ||
710 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
711 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
712 IsEqualGUID( riid, &IID_IXMLDOMDocument2 )||
713 IsEqualGUID( riid, &IID_IXMLDOMDocument3 ))
717 else if (IsEqualGUID(&IID_IPersistStream, riid) ||
718 IsEqualGUID(&IID_IPersistStreamInit, riid))
720 *ppvObject = &(This->lpvtblIPersistStreamInit);
722 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
724 *ppvObject = &(This->lpvtblIObjectWithSite);
726 else if (IsEqualGUID(&IID_IObjectSafety, riid))
728 *ppvObject = &(This->lpvtblIObjectSafety);
730 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
732 *ppvObject = &This->lpvtblISupportErrorInfo;
734 else if(node_query_interface(&This->node, riid, ppvObject))
736 return *ppvObject ? S_OK : E_NOINTERFACE;
738 else if(IsEqualGUID(&IID_IRunnableObject, riid))
740 TRACE("IID_IRunnableObject not supported returning NULL\n");
741 return E_NOINTERFACE;
745 FIXME("interface %s not implemented\n", debugstr_guid(riid));
746 return E_NOINTERFACE;
749 IUnknown_AddRef((IUnknown*)*ppvObject);
755 static ULONG WINAPI domdoc_AddRef(
756 IXMLDOMDocument3 *iface )
758 domdoc *This = impl_from_IXMLDOMDocument3( iface );
759 TRACE("%p\n", This );
760 return InterlockedIncrement( &This->ref );
764 static ULONG WINAPI domdoc_Release(
765 IXMLDOMDocument3 *iface )
767 domdoc *This = impl_from_IXMLDOMDocument3( iface );
770 TRACE("%p\n", This );
772 ref = InterlockedDecrement( &This->ref );
776 detach_bsc(This->bsc);
779 IUnknown_Release( This->site );
780 destroy_xmlnode(&This->node);
781 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
782 if (This->stream) IStream_Release(This->stream);
783 HeapFree( GetProcessHeap(), 0, This );
789 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument3 *iface, UINT* pctinfo )
791 domdoc *This = impl_from_IXMLDOMDocument3( iface );
793 TRACE("(%p)->(%p)\n", This, pctinfo);
800 static HRESULT WINAPI domdoc_GetTypeInfo(
801 IXMLDOMDocument3 *iface,
802 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
804 domdoc *This = impl_from_IXMLDOMDocument3( iface );
807 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
809 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
814 static HRESULT WINAPI domdoc_GetIDsOfNames(
815 IXMLDOMDocument3 *iface,
822 domdoc *This = impl_from_IXMLDOMDocument3( iface );
826 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
829 if(!rgszNames || cNames == 0 || !rgDispId)
832 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
835 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
836 ITypeInfo_Release(typeinfo);
843 static HRESULT WINAPI domdoc_Invoke(
844 IXMLDOMDocument3 *iface,
849 DISPPARAMS* pDispParams,
851 EXCEPINFO* pExcepInfo,
854 domdoc *This = impl_from_IXMLDOMDocument3( iface );
858 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
859 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
861 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
864 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
865 pVarResult, pExcepInfo, puArgErr);
866 ITypeInfo_Release(typeinfo);
873 static HRESULT WINAPI domdoc_get_nodeName(
874 IXMLDOMDocument3 *iface,
877 domdoc *This = impl_from_IXMLDOMDocument3( iface );
879 static const WCHAR documentW[] = {'#','d','o','c','u','m','e','n','t',0};
881 TRACE("(%p)->(%p)\n", This, name);
883 return return_bstr(documentW, name);
887 static HRESULT WINAPI domdoc_get_nodeValue(
888 IXMLDOMDocument3 *iface,
891 domdoc *This = impl_from_IXMLDOMDocument3( iface );
893 TRACE("(%p)->(%p)\n", This, value);
898 V_VT(value) = VT_NULL;
899 V_BSTR(value) = NULL; /* tests show that we should do this */
904 static HRESULT WINAPI domdoc_put_nodeValue(
905 IXMLDOMDocument3 *iface,
908 domdoc *This = impl_from_IXMLDOMDocument3( iface );
909 FIXME("(%p)->(v%d)\n", This, V_VT(&value));
914 static HRESULT WINAPI domdoc_get_nodeType(
915 IXMLDOMDocument3 *iface,
918 domdoc *This = impl_from_IXMLDOMDocument3( iface );
920 TRACE("(%p)->(%p)\n", This, type);
922 *type = NODE_DOCUMENT;
927 static HRESULT WINAPI domdoc_get_parentNode(
928 IXMLDOMDocument3 *iface,
929 IXMLDOMNode** parent )
931 domdoc *This = impl_from_IXMLDOMDocument3( iface );
933 TRACE("(%p)->(%p)\n", This, parent);
935 return node_get_parent(&This->node, parent);
939 static HRESULT WINAPI domdoc_get_childNodes(
940 IXMLDOMDocument3 *iface,
941 IXMLDOMNodeList** childList )
943 domdoc *This = impl_from_IXMLDOMDocument3( iface );
945 TRACE("(%p)->(%p)\n", This, childList);
947 return node_get_child_nodes(&This->node, childList);
951 static HRESULT WINAPI domdoc_get_firstChild(
952 IXMLDOMDocument3 *iface,
953 IXMLDOMNode** firstChild )
955 domdoc *This = impl_from_IXMLDOMDocument3( iface );
957 TRACE("(%p)->(%p)\n", This, firstChild);
959 return node_get_first_child(&This->node, firstChild);
963 static HRESULT WINAPI domdoc_get_lastChild(
964 IXMLDOMDocument3 *iface,
965 IXMLDOMNode** lastChild )
967 domdoc *This = impl_from_IXMLDOMDocument3( iface );
969 TRACE("(%p)->(%p)\n", This, lastChild);
971 return node_get_last_child(&This->node, lastChild);
975 static HRESULT WINAPI domdoc_get_previousSibling(
976 IXMLDOMDocument3 *iface,
977 IXMLDOMNode** previousSibling )
979 domdoc *This = impl_from_IXMLDOMDocument3( iface );
981 TRACE("(%p)->(%p)\n", This, previousSibling);
983 return return_null_node(previousSibling);
987 static HRESULT WINAPI domdoc_get_nextSibling(
988 IXMLDOMDocument3 *iface,
989 IXMLDOMNode** nextSibling )
991 domdoc *This = impl_from_IXMLDOMDocument3( iface );
993 TRACE("(%p)->(%p)\n", This, nextSibling);
995 return return_null_node(nextSibling);
999 static HRESULT WINAPI domdoc_get_attributes(
1000 IXMLDOMDocument3 *iface,
1001 IXMLDOMNamedNodeMap** attributeMap )
1003 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1005 TRACE("(%p)->(%p)\n", This, attributeMap);
1007 return return_null_ptr((void**)attributeMap);
1011 static HRESULT WINAPI domdoc_insertBefore(
1012 IXMLDOMDocument3 *iface,
1013 IXMLDOMNode* newChild,
1015 IXMLDOMNode** outNewChild )
1017 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1019 TRACE("(%p)->(%p x%d %p)\n", This, newChild, V_VT(&refChild), outNewChild);
1021 return node_insert_before(&This->node, newChild, &refChild, outNewChild);
1025 static HRESULT WINAPI domdoc_replaceChild(
1026 IXMLDOMDocument3 *iface,
1027 IXMLDOMNode* newChild,
1028 IXMLDOMNode* oldChild,
1029 IXMLDOMNode** outOldChild)
1031 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1032 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
1036 static HRESULT WINAPI domdoc_removeChild(
1037 IXMLDOMDocument3 *iface,
1038 IXMLDOMNode* childNode,
1039 IXMLDOMNode** oldChild)
1041 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1042 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
1046 static HRESULT WINAPI domdoc_appendChild(
1047 IXMLDOMDocument3 *iface,
1048 IXMLDOMNode* newChild,
1049 IXMLDOMNode** outNewChild)
1051 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1052 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
1056 static HRESULT WINAPI domdoc_hasChildNodes(
1057 IXMLDOMDocument3 *iface,
1058 VARIANT_BOOL* hasChild)
1060 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1061 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
1065 static HRESULT WINAPI domdoc_get_ownerDocument(
1066 IXMLDOMDocument3 *iface,
1067 IXMLDOMDocument** DOMDocument)
1069 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1070 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
1074 static HRESULT WINAPI domdoc_cloneNode(
1075 IXMLDOMDocument3 *iface,
1077 IXMLDOMNode** cloneRoot)
1079 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1080 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
1084 static HRESULT WINAPI domdoc_get_nodeTypeString(
1085 IXMLDOMDocument3 *iface,
1088 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1089 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
1093 static HRESULT WINAPI domdoc_get_text(
1094 IXMLDOMDocument3 *iface,
1097 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1098 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
1102 static HRESULT WINAPI domdoc_put_text(
1103 IXMLDOMDocument3 *iface,
1106 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1107 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
1111 static HRESULT WINAPI domdoc_get_specified(
1112 IXMLDOMDocument3 *iface,
1113 VARIANT_BOOL* isSpecified )
1115 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1116 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
1120 static HRESULT WINAPI domdoc_get_definition(
1121 IXMLDOMDocument3 *iface,
1122 IXMLDOMNode** definitionNode )
1124 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1125 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
1129 static HRESULT WINAPI domdoc_get_nodeTypedValue(
1130 IXMLDOMDocument3 *iface,
1131 VARIANT* typedValue )
1133 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1134 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
1137 static HRESULT WINAPI domdoc_put_nodeTypedValue(
1138 IXMLDOMDocument3 *iface,
1139 VARIANT typedValue )
1141 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1142 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
1146 static HRESULT WINAPI domdoc_get_dataType(
1147 IXMLDOMDocument3 *iface,
1148 VARIANT* dataTypeName )
1150 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1151 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
1155 static HRESULT WINAPI domdoc_put_dataType(
1156 IXMLDOMDocument3 *iface,
1159 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1160 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
1164 static HRESULT WINAPI domdoc_get_xml(
1165 IXMLDOMDocument3 *iface,
1168 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1169 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
1173 static HRESULT WINAPI domdoc_transformNode(
1174 IXMLDOMDocument3 *iface,
1175 IXMLDOMNode* styleSheet,
1178 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1179 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
1183 static HRESULT WINAPI domdoc_selectNodes(
1184 IXMLDOMDocument3 *iface,
1186 IXMLDOMNodeList** resultList )
1188 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1189 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
1193 static HRESULT WINAPI domdoc_selectSingleNode(
1194 IXMLDOMDocument3 *iface,
1196 IXMLDOMNode** resultNode )
1198 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1199 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
1203 static HRESULT WINAPI domdoc_get_parsed(
1204 IXMLDOMDocument3 *iface,
1205 VARIANT_BOOL* isParsed )
1207 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1208 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
1212 static HRESULT WINAPI domdoc_get_namespaceURI(
1213 IXMLDOMDocument3 *iface,
1214 BSTR* namespaceURI )
1216 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1217 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
1221 static HRESULT WINAPI domdoc_get_prefix(
1222 IXMLDOMDocument3 *iface,
1223 BSTR* prefixString )
1225 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1226 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
1230 static HRESULT WINAPI domdoc_get_baseName(
1231 IXMLDOMDocument3 *iface,
1234 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1235 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
1239 static HRESULT WINAPI domdoc_transformNodeToObject(
1240 IXMLDOMDocument3 *iface,
1241 IXMLDOMNode* stylesheet,
1242 VARIANT outputObject)
1244 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1245 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
1249 static HRESULT WINAPI domdoc_get_doctype(
1250 IXMLDOMDocument3 *iface,
1251 IXMLDOMDocumentType** documentType )
1253 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1254 FIXME("(%p)\n", This);
1259 static HRESULT WINAPI domdoc_get_implementation(
1260 IXMLDOMDocument3 *iface,
1261 IXMLDOMImplementation** impl )
1263 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1265 TRACE("(%p)->(%p)\n", This, impl);
1268 return E_INVALIDARG;
1270 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1275 static HRESULT WINAPI domdoc_get_documentElement(
1276 IXMLDOMDocument3 *iface,
1277 IXMLDOMElement** DOMElement )
1279 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1280 IXMLDOMNode *element_node;
1284 TRACE("(%p)->(%p)\n", This, DOMElement);
1287 return E_INVALIDARG;
1291 root = xmlDocGetRootElement( get_doc(This) );
1295 element_node = create_node( root );
1296 if(!element_node) return S_FALSE;
1298 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (void**)DOMElement);
1299 IXMLDOMNode_Release(element_node);
1305 static HRESULT WINAPI domdoc_put_documentElement(
1306 IXMLDOMDocument3 *iface,
1307 IXMLDOMElement* DOMElement )
1309 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1310 IXMLDOMNode *elementNode;
1315 TRACE("(%p)->(%p)\n", This, DOMElement);
1317 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1321 xmlNode = get_node_obj( elementNode );
1323 FIXME("elementNode is not our object\n");
1327 if(!xmlNode->node->parent)
1328 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1329 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1331 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1332 IXMLDOMNode_Release( elementNode );
1335 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1341 static HRESULT WINAPI domdoc_createElement(
1342 IXMLDOMDocument3 *iface,
1344 IXMLDOMElement** element )
1346 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1351 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1353 if (!element || !tagname) return E_INVALIDARG;
1355 V_VT(&type) = VT_I1;
1356 V_I1(&type) = NODE_ELEMENT;
1358 hr = IXMLDOMDocument3_createNode(iface, type, tagname, NULL, &node);
1361 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1362 IXMLDOMNode_Release(node);
1369 static HRESULT WINAPI domdoc_createDocumentFragment(
1370 IXMLDOMDocument3 *iface,
1371 IXMLDOMDocumentFragment** frag )
1373 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1378 TRACE("(%p)->(%p)\n", This, frag);
1380 if (!frag) return E_INVALIDARG;
1384 V_VT(&type) = VT_I1;
1385 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1387 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1390 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1391 IXMLDOMNode_Release(node);
1398 static HRESULT WINAPI domdoc_createTextNode(
1399 IXMLDOMDocument3 *iface,
1401 IXMLDOMText** text )
1403 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1408 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1410 if (!text) return E_INVALIDARG;
1414 V_VT(&type) = VT_I1;
1415 V_I1(&type) = NODE_TEXT;
1417 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1420 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1421 IXMLDOMNode_Release(node);
1422 hr = IXMLDOMText_put_data(*text, data);
1429 static HRESULT WINAPI domdoc_createComment(
1430 IXMLDOMDocument3 *iface,
1432 IXMLDOMComment** comment )
1434 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1439 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1441 if (!comment) return E_INVALIDARG;
1445 V_VT(&type) = VT_I1;
1446 V_I1(&type) = NODE_COMMENT;
1448 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1451 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1452 IXMLDOMNode_Release(node);
1453 hr = IXMLDOMComment_put_data(*comment, data);
1460 static HRESULT WINAPI domdoc_createCDATASection(
1461 IXMLDOMDocument3 *iface,
1463 IXMLDOMCDATASection** cdata )
1465 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1470 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1472 if (!cdata) return E_INVALIDARG;
1476 V_VT(&type) = VT_I1;
1477 V_I1(&type) = NODE_CDATA_SECTION;
1479 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1482 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1483 IXMLDOMNode_Release(node);
1484 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1491 static HRESULT WINAPI domdoc_createProcessingInstruction(
1492 IXMLDOMDocument3 *iface,
1495 IXMLDOMProcessingInstruction** pi )
1497 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1502 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1504 if (!pi) return E_INVALIDARG;
1508 V_VT(&type) = VT_I1;
1509 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1511 hr = IXMLDOMDocument3_createNode(iface, type, target, NULL, &node);
1517 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1518 node_obj = get_node_obj(node);
1519 V_VT(&v_data) = VT_BSTR;
1520 V_BSTR(&v_data) = data;
1522 hr = node_put_value(node_obj, &v_data);
1524 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1525 IXMLDOMNode_Release(node);
1532 static HRESULT WINAPI domdoc_createAttribute(
1533 IXMLDOMDocument3 *iface,
1535 IXMLDOMAttribute** attribute )
1537 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1542 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1544 if (!attribute || !name) return E_INVALIDARG;
1546 V_VT(&type) = VT_I1;
1547 V_I1(&type) = NODE_ATTRIBUTE;
1549 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1552 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1553 IXMLDOMNode_Release(node);
1560 static HRESULT WINAPI domdoc_createEntityReference(
1561 IXMLDOMDocument3 *iface,
1563 IXMLDOMEntityReference** entityref )
1565 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1570 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1572 if (!entityref) return E_INVALIDARG;
1576 V_VT(&type) = VT_I1;
1577 V_I1(&type) = NODE_ENTITY_REFERENCE;
1579 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1582 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1583 IXMLDOMNode_Release(node);
1590 static HRESULT WINAPI domdoc_getElementsByTagName(
1591 IXMLDOMDocument3 *iface,
1593 IXMLDOMNodeList** resultList )
1595 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1598 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1600 if (!tagName || !resultList) return E_INVALIDARG;
1602 if (tagName[0] == '*' && tagName[1] == 0)
1604 static const WCHAR formatallW[] = {'/','/','*',0};
1605 hr = queryresult_create((xmlNodePtr)get_doc(This), formatallW, resultList);
1609 static const WCHAR xpathformat[] =
1610 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
1611 static const WCHAR closeW[] = { '\'',']',0 };
1617 length = lstrlenW(tagName);
1619 /* without two WCHARs from format specifier */
1620 ptr = pattern = heap_alloc(sizeof(xpathformat) + length*sizeof(WCHAR) + sizeof(closeW));
1622 memcpy(ptr, xpathformat, sizeof(xpathformat));
1623 ptr += sizeof(xpathformat)/sizeof(WCHAR);
1624 memcpy(ptr, tagName, length*sizeof(WCHAR));
1626 memcpy(ptr, closeW, sizeof(closeW));
1628 hr = queryresult_create((xmlNodePtr)get_doc(This), pattern, resultList);
1635 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1641 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1643 return E_INVALIDARG;
1650 static HRESULT WINAPI domdoc_createNode(
1651 IXMLDOMDocument3 *iface,
1655 IXMLDOMNode** node )
1657 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1658 DOMNodeType node_type;
1660 xmlChar *xml_name, *href;
1663 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1665 if(!node) return E_INVALIDARG;
1667 hr = get_node_type(Type, &node_type);
1668 if(FAILED(hr)) return hr;
1670 if(namespaceURI && namespaceURI[0] && node_type != NODE_ELEMENT)
1671 FIXME("nodes with namespaces currently not supported.\n");
1673 TRACE("node_type %d\n", node_type);
1675 /* exit earlier for types that need name */
1679 case NODE_ATTRIBUTE:
1680 case NODE_ENTITY_REFERENCE:
1681 case NODE_PROCESSING_INSTRUCTION:
1682 if (!name || *name == 0) return E_FAIL;
1687 xml_name = xmlChar_from_wchar(name);
1688 /* prevent empty href to be allocated */
1689 href = namespaceURI ? xmlChar_from_wchar(namespaceURI) : NULL;
1695 xmlChar *local, *prefix;
1697 local = xmlSplitQName2(xml_name, &prefix);
1699 xmlnode = xmlNewDocNode(get_doc(This), NULL, local ? local : xml_name, NULL);
1701 /* allow to create default namespace xmlns= */
1702 if (local || (href && *href))
1704 xmlNsPtr ns = xmlNewNs(xmlnode, href, prefix);
1705 xmlSetNs(xmlnode, ns);
1713 case NODE_ATTRIBUTE:
1714 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1717 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1719 case NODE_CDATA_SECTION:
1720 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1722 case NODE_ENTITY_REFERENCE:
1723 xmlnode = xmlNewReference(get_doc(This), xml_name);
1725 case NODE_PROCESSING_INSTRUCTION:
1726 #ifdef HAVE_XMLNEWDOCPI
1727 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1729 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1734 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1736 case NODE_DOCUMENT_FRAGMENT:
1737 xmlnode = xmlNewDocFragment(get_doc(This));
1739 /* unsupported types */
1741 case NODE_DOCUMENT_TYPE:
1744 heap_free(xml_name);
1745 return E_INVALIDARG;
1747 FIXME("unhandled node type %d\n", node_type);
1752 *node = create_node(xmlnode);
1753 heap_free(xml_name);
1758 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1759 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1766 static HRESULT WINAPI domdoc_nodeFromID(
1767 IXMLDOMDocument3 *iface,
1769 IXMLDOMNode** node )
1771 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1772 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1776 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1781 xmldoc = doparse(This, ptr, len);
1783 xmldoc->_private = create_priv();
1784 return attach_xmldoc(This, xmldoc);
1790 static HRESULT doread( domdoc *This, LPWSTR filename )
1795 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1800 detach_bsc(This->bsc);
1806 static HRESULT WINAPI domdoc_load(
1807 IXMLDOMDocument3 *iface,
1809 VARIANT_BOOL* isSuccessful )
1811 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1812 LPWSTR filename = NULL;
1813 HRESULT hr = S_FALSE;
1814 IXMLDOMDocument3 *pNewDoc = NULL;
1815 IStream *pStream = NULL;
1818 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1820 *isSuccessful = VARIANT_FALSE;
1822 assert( &This->node );
1824 switch( V_VT(&xmlSource) )
1827 filename = V_BSTR(&xmlSource);
1830 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument3, (void**)&pNewDoc);
1835 domdoc *newDoc = impl_from_IXMLDOMDocument3( pNewDoc );
1836 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1837 hr = attach_xmldoc(This, xmldoc);
1840 *isSuccessful = VARIANT_TRUE;
1845 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1848 IPersistStream *pDocStream;
1849 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1852 hr = IPersistStream_Load(pDocStream, pStream);
1853 IStream_Release(pStream);
1856 *isSuccessful = VARIANT_TRUE;
1858 TRACE("Using IStream to load Document\n");
1863 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1868 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1873 /* ISequentialStream */
1874 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1878 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1881 TRACE("filename (%s)\n", debugstr_w(filename));
1885 hr = doread( This, filename );
1888 This->error = E_FAIL;
1891 hr = This->error = S_OK;
1892 *isSuccessful = VARIANT_TRUE;
1896 if(!filename || FAILED(hr)) {
1897 xmldoc = xmlNewDoc(NULL);
1898 xmldoc->_private = create_priv();
1899 hr = attach_xmldoc(This, xmldoc);
1904 TRACE("ret (%d)\n", hr);
1910 static HRESULT WINAPI domdoc_get_readyState(
1911 IXMLDOMDocument3 *iface,
1914 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1915 FIXME("stub! (%p)->(%p)\n", This, value);
1918 return E_INVALIDARG;
1920 *value = READYSTATE_COMPLETE;
1925 static HRESULT WINAPI domdoc_get_parseError(
1926 IXMLDOMDocument3 *iface,
1927 IXMLDOMParseError** errorObj )
1929 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1930 static const WCHAR err[] = {'e','r','r','o','r',0};
1931 BSTR error_string = NULL;
1933 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1936 error_string = SysAllocString(err);
1938 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1939 if(!*errorObj) return E_OUTOFMEMORY;
1944 static HRESULT WINAPI domdoc_get_url(
1945 IXMLDOMDocument3 *iface,
1948 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1949 FIXME("(%p)->(%p)\n", This, urlString);
1954 static HRESULT WINAPI domdoc_get_async(
1955 IXMLDOMDocument3 *iface,
1956 VARIANT_BOOL* isAsync )
1958 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1960 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1961 *isAsync = This->async;
1966 static HRESULT WINAPI domdoc_put_async(
1967 IXMLDOMDocument3 *iface,
1968 VARIANT_BOOL isAsync )
1970 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1972 TRACE("(%p)->(%d)\n", This, isAsync);
1973 This->async = isAsync;
1978 static HRESULT WINAPI domdoc_abort(
1979 IXMLDOMDocument3 *iface )
1981 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1982 FIXME("%p\n", This);
1987 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1992 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
1993 str = heap_alloc( len );
1996 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
2002 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2003 static HRESULT WINAPI domdoc_loadXML(
2004 IXMLDOMDocument3 *iface,
2006 VARIANT_BOOL* isSuccessful )
2008 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2009 xmlDocPtr xmldoc = NULL;
2010 HRESULT hr = S_FALSE, hr2;
2014 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
2016 assert ( &This->node );
2020 *isSuccessful = VARIANT_FALSE;
2022 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
2024 xmldoc = doparse(This, str, len);
2027 This->error = E_FAIL;
2030 hr = This->error = S_OK;
2031 *isSuccessful = VARIANT_TRUE;
2032 TRACE("parsed document %p\n", xmldoc);
2037 xmldoc = xmlNewDoc(NULL);
2039 xmldoc->_private = create_priv();
2041 hr2 = attach_xmldoc(This, xmldoc);
2048 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
2053 if(!WriteFile(ctx, buffer, len, &written, NULL))
2055 WARN("write error\n");
2062 static int XMLCALL domdoc_save_closecallback(void *ctx)
2064 return CloseHandle(ctx) ? 0 : -1;
2067 static HRESULT WINAPI domdoc_save(
2068 IXMLDOMDocument3 *iface,
2069 VARIANT destination )
2071 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2077 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
2078 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
2080 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
2082 FIXME("Unhandled vt %d\n", V_VT(&destination));
2086 if(V_VT(&destination) == VT_UNKNOWN)
2088 IUnknown *pUnk = V_UNKNOWN(&destination);
2089 IXMLDOMDocument2 *pDocument;
2091 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&pDocument);
2094 VARIANT_BOOL success;
2097 ret = IXMLDOMDocument3_get_xml(iface, &xml);
2100 ret = IXMLDOMDocument3_loadXML(pDocument, xml, &success);
2104 IXMLDOMDocument3_Release(pDocument);
2107 TRACE("ret %d\n", ret);
2112 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
2113 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
2114 if( handle == INVALID_HANDLE_VALUE )
2116 WARN("failed to create file\n");
2120 /* disable top XML declaration */
2121 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
2122 handle, NULL, XML_SAVE_NO_DECL);
2125 CloseHandle(handle);
2129 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
2130 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
2131 xmldoc_link_xmldecl(get_doc(This), xmldecl);
2133 /* will close file through close callback */
2139 static HRESULT WINAPI domdoc_get_validateOnParse(
2140 IXMLDOMDocument3 *iface,
2141 VARIANT_BOOL* isValidating )
2143 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2144 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
2145 *isValidating = This->validating;
2150 static HRESULT WINAPI domdoc_put_validateOnParse(
2151 IXMLDOMDocument3 *iface,
2152 VARIANT_BOOL isValidating )
2154 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2155 TRACE("(%p)->(%d)\n", This, isValidating);
2156 This->validating = isValidating;
2161 static HRESULT WINAPI domdoc_get_resolveExternals(
2162 IXMLDOMDocument3 *iface,
2163 VARIANT_BOOL* isResolving )
2165 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2166 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
2167 *isResolving = This->resolving;
2172 static HRESULT WINAPI domdoc_put_resolveExternals(
2173 IXMLDOMDocument3 *iface,
2174 VARIANT_BOOL isResolving )
2176 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2177 TRACE("(%p)->(%d)\n", This, isResolving);
2178 This->resolving = isResolving;
2183 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
2184 IXMLDOMDocument3 *iface,
2185 VARIANT_BOOL* isPreserving )
2187 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2188 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
2189 *isPreserving = This->preserving;
2194 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
2195 IXMLDOMDocument3 *iface,
2196 VARIANT_BOOL isPreserving )
2198 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2199 TRACE("(%p)->(%d)\n", This, isPreserving);
2200 This->preserving = isPreserving;
2205 static HRESULT WINAPI domdoc_put_onReadyStateChange(
2206 IXMLDOMDocument3 *iface,
2207 VARIANT readyStateChangeSink )
2209 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2210 FIXME("%p\n", This);
2215 static HRESULT WINAPI domdoc_put_onDataAvailable(
2216 IXMLDOMDocument3 *iface,
2217 VARIANT onDataAvailableSink )
2219 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2220 FIXME("%p\n", This);
2224 static HRESULT WINAPI domdoc_put_onTransformNode(
2225 IXMLDOMDocument3 *iface,
2226 VARIANT onTransformNodeSink )
2228 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2229 FIXME("%p\n", This);
2233 static HRESULT WINAPI domdoc_get_namespaces(
2234 IXMLDOMDocument3* iface,
2235 IXMLDOMSchemaCollection** schemaCollection )
2237 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2238 FIXME("(%p)->(%p)\n", This, schemaCollection);
2242 static HRESULT WINAPI domdoc_get_schemas(
2243 IXMLDOMDocument3* iface,
2246 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2247 HRESULT hr = S_FALSE;
2248 IXMLDOMSchemaCollection *cur_schema = This->schema;
2250 TRACE("(%p)->(%p)\n", This, var1);
2252 VariantInit(var1); /* Test shows we don't call VariantClear here */
2253 V_VT(var1) = VT_NULL;
2257 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
2259 V_VT(var1) = VT_DISPATCH;
2264 static HRESULT WINAPI domdoc_putref_schemas(
2265 IXMLDOMDocument3* iface,
2268 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2269 HRESULT hr = E_FAIL;
2270 IXMLDOMSchemaCollection *new_schema = NULL;
2272 FIXME("(%p): semi-stub\n", This);
2276 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2280 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2289 WARN("Can't get schema from vt %x\n", V_VT(&var1));
2294 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
2295 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
2301 static HRESULT WINAPI domdoc_validate(
2302 IXMLDOMDocument3* iface,
2303 IXMLDOMParseError** err)
2305 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2307 xmlValidCtxtPtr vctx;
2309 TRACE("(%p)->(%p)\n", This, err);
2310 domdoc_get_readyState(iface, &state);
2311 if (state != READYSTATE_COMPLETE)
2314 *err = create_parseError(0, NULL, NULL, NULL, 0, 0, 0);
2318 vctx = xmlNewValidCtxt();
2319 vctx->error = NULL; /* TODO: error callback */
2320 vctx->warning = NULL; /* TODO: warning callback */
2322 if (xmlValidateDocument(vctx, get_doc(This)))
2325 *err = create_parseError(0, NULL, NULL, NULL, 0, 0, 0);
2326 xmlFreeValidCtxt(vctx);
2330 FIXME("partial stub!\n");
2332 *err = create_parseError(0xC00CE223, NULL, NULL, NULL, 0, 0, 0);
2333 xmlFreeValidCtxt(vctx);
2337 static HRESULT WINAPI domdoc_setProperty(
2338 IXMLDOMDocument3* iface,
2342 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2344 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
2346 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2352 V_VT(&varStr) = VT_EMPTY;
2353 if (V_VT(&var) != VT_BSTR)
2355 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2357 bstr = V_BSTR(&varStr);
2360 bstr = V_BSTR(&var);
2363 if (lstrcmpiW(bstr, PropValueXPathW) == 0)
2364 This->properties->XPath = TRUE;
2365 else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
2366 This->properties->XPath = FALSE;
2370 VariantClear(&varStr);
2373 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2378 xmlChar *pTokBegin, *pTokEnd, *pTokInner;
2379 xmlChar *nsStr = (xmlChar*)This->properties->selectNsStr;
2380 xmlXPathContextPtr ctx;
2381 struct list *pNsList;
2382 select_ns_entry* pNsEntry = NULL;
2384 V_VT(&varStr) = VT_EMPTY;
2385 if (V_VT(&var) != VT_BSTR)
2387 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2389 bstr = V_BSTR(&varStr);
2392 bstr = V_BSTR(&var);
2396 pNsList = &(This->properties->selectNsList);
2397 clear_selectNsList(pNsList);
2399 nsStr = xmlChar_from_wchar(bstr);
2402 TRACE("Setting SelectionNamespaces property to: %s\n", nsStr);
2404 This->properties->selectNsStr = nsStr;
2405 This->properties->selectNsStr_len = xmlStrlen(nsStr);
2408 ctx = xmlXPathNewContext(This->node.node->doc);
2411 for (; *pTokBegin; pTokBegin = pTokEnd)
2413 if (pNsEntry != NULL)
2414 memset(pNsEntry, 0, sizeof(select_ns_entry));
2416 pNsEntry = heap_alloc_zero(sizeof(select_ns_entry));
2418 while (*pTokBegin == ' ')
2420 pTokEnd = pTokBegin;
2421 while (*pTokEnd != ' ' && *pTokEnd != 0)
2424 if (xmlStrncmp(pTokBegin, (xmlChar const*)"xmlns", 5) != 0)
2427 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2428 wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokBegin, pTokEnd-pTokBegin));
2433 if (*pTokBegin == '=')
2435 /*valid for XSLPattern?*/
2436 FIXME("Setting default xmlns not supported - skipping.\n");
2437 pTokBegin = pTokEnd;
2440 else if (*pTokBegin == ':')
2442 pNsEntry->prefix = ++pTokBegin;
2443 for (pTokInner = pTokBegin; pTokInner != pTokEnd && *pTokInner != '='; ++pTokInner)
2446 if (pTokInner == pTokEnd)
2449 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2450 wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokBegin, pTokEnd-pTokBegin));
2454 pNsEntry->prefix_end = *pTokInner;
2458 if (pTokEnd-pTokInner > 1 &&
2459 ((*pTokInner == '\'' && *(pTokEnd-1) == '\'') ||
2460 (*pTokInner == '"' && *(pTokEnd-1) == '"')))
2462 pNsEntry->href = ++pTokInner;
2463 pNsEntry->href_end = *(pTokEnd-1);
2465 list_add_tail(pNsList, &pNsEntry->entry);
2466 /*let libxml figure out if they're valid from here ;)*/
2467 if (xmlXPathRegisterNs(ctx, pNsEntry->prefix, pNsEntry->href) != 0)
2476 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2477 wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokInner, pTokEnd-pTokInner));
2478 list_add_tail(pNsList, &pNsEntry->entry);
2491 heap_free(pNsEntry);
2492 xmlXPathFreeContext(ctx);
2495 VariantClear(&varStr);
2498 else if (lstrcmpiW(p, PropertyProhibitDTDW) == 0 ||
2499 lstrcmpiW(p, PropertyNewParserW) == 0)
2502 FIXME("Ignoring property %s, value %d\n", debugstr_w(p), V_BOOL(&var));
2506 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2510 static HRESULT WINAPI domdoc_getProperty(
2511 IXMLDOMDocument3* iface,
2515 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2517 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2520 return E_INVALIDARG;
2522 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2524 V_VT(var) = VT_BSTR;
2525 V_BSTR(var) = This->properties->XPath ?
2526 SysAllocString(PropValueXPathW) :
2527 SysAllocString(PropValueXSLPatternW);
2528 return V_BSTR(var) ? S_OK : E_OUTOFMEMORY;
2530 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2533 BSTR rebuiltStr, cur;
2534 const xmlChar *nsStr;
2535 struct list *pNsList;
2536 select_ns_entry* pNsEntry;
2538 V_VT(var) = VT_BSTR;
2539 nsStr = This->properties->selectNsStr;
2540 pNsList = &This->properties->selectNsList;
2541 lenA = This->properties->selectNsStr_len;
2542 lenW = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, NULL, 0);
2543 rebuiltStr = heap_alloc(lenW*sizeof(WCHAR));
2544 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, rebuiltStr, lenW);
2546 /* this is fine because all of the chars that end tokens are ASCII*/
2547 LIST_FOR_EACH_ENTRY(pNsEntry, pNsList, select_ns_entry, entry)
2549 while (*cur != 0) ++cur;
2550 if (pNsEntry->prefix_end)
2552 *cur = pNsEntry->prefix_end;
2553 while (*cur != 0) ++cur;
2556 if (pNsEntry->href_end)
2558 *cur = pNsEntry->href_end;
2561 V_BSTR(var) = SysAllocString(rebuiltStr);
2562 heap_free(rebuiltStr);
2566 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2570 static HRESULT WINAPI domdoc_validateNode(
2571 IXMLDOMDocument3* iface,
2573 IXMLDOMParseError** error)
2575 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2576 FIXME("(%p)->(%p %p): stub\n", This, node, error);
2580 static HRESULT WINAPI domdoc_importNode(
2581 IXMLDOMDocument3* iface,
2584 IXMLDOMNode** clone)
2586 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2587 FIXME("(%p)->(%p %d %p): stub\n", This, node, deep, clone);
2591 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl =
2593 domdoc_QueryInterface,
2596 domdoc_GetTypeInfoCount,
2598 domdoc_GetIDsOfNames,
2600 domdoc_get_nodeName,
2601 domdoc_get_nodeValue,
2602 domdoc_put_nodeValue,
2603 domdoc_get_nodeType,
2604 domdoc_get_parentNode,
2605 domdoc_get_childNodes,
2606 domdoc_get_firstChild,
2607 domdoc_get_lastChild,
2608 domdoc_get_previousSibling,
2609 domdoc_get_nextSibling,
2610 domdoc_get_attributes,
2611 domdoc_insertBefore,
2612 domdoc_replaceChild,
2615 domdoc_hasChildNodes,
2616 domdoc_get_ownerDocument,
2618 domdoc_get_nodeTypeString,
2621 domdoc_get_specified,
2622 domdoc_get_definition,
2623 domdoc_get_nodeTypedValue,
2624 domdoc_put_nodeTypedValue,
2625 domdoc_get_dataType,
2626 domdoc_put_dataType,
2628 domdoc_transformNode,
2630 domdoc_selectSingleNode,
2632 domdoc_get_namespaceURI,
2634 domdoc_get_baseName,
2635 domdoc_transformNodeToObject,
2637 domdoc_get_implementation,
2638 domdoc_get_documentElement,
2639 domdoc_put_documentElement,
2640 domdoc_createElement,
2641 domdoc_createDocumentFragment,
2642 domdoc_createTextNode,
2643 domdoc_createComment,
2644 domdoc_createCDATASection,
2645 domdoc_createProcessingInstruction,
2646 domdoc_createAttribute,
2647 domdoc_createEntityReference,
2648 domdoc_getElementsByTagName,
2652 domdoc_get_readyState,
2653 domdoc_get_parseError,
2660 domdoc_get_validateOnParse,
2661 domdoc_put_validateOnParse,
2662 domdoc_get_resolveExternals,
2663 domdoc_put_resolveExternals,
2664 domdoc_get_preserveWhiteSpace,
2665 domdoc_put_preserveWhiteSpace,
2666 domdoc_put_onReadyStateChange,
2667 domdoc_put_onDataAvailable,
2668 domdoc_put_onTransformNode,
2669 domdoc_get_namespaces,
2671 domdoc_putref_schemas,
2675 domdoc_validateNode,
2679 /* xmldoc implementation of IObjectWithSite */
2680 static HRESULT WINAPI
2681 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2683 domdoc *This = impl_from_IObjectWithSite(iface);
2684 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2688 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2690 domdoc *This = impl_from_IObjectWithSite(iface);
2691 return IXMLDocument_AddRef((IXMLDocument *)This);
2695 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2697 domdoc *This = impl_from_IObjectWithSite(iface);
2698 return IXMLDocument_Release((IXMLDocument *)This);
2701 static HRESULT WINAPI
2702 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2704 domdoc *This = impl_from_IObjectWithSite(iface);
2706 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2711 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2714 static HRESULT WINAPI
2715 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2717 domdoc *This = impl_from_IObjectWithSite(iface);
2719 TRACE("(%p)->(%p)\n", iface, punk);
2725 IUnknown_Release( This->site );
2732 IUnknown_AddRef( punk );
2735 IUnknown_Release( This->site );
2742 static const IObjectWithSiteVtbl domdocObjectSite =
2744 xmldoc_ObjectWithSite_QueryInterface,
2745 xmldoc_ObjectWithSite_AddRef,
2746 xmldoc_ObjectWithSite_Release,
2751 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2753 domdoc *This = impl_from_IObjectSafety(iface);
2754 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2757 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2759 domdoc *This = impl_from_IObjectSafety(iface);
2760 return IXMLDocument_AddRef((IXMLDocument *)This);
2763 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2765 domdoc *This = impl_from_IObjectSafety(iface);
2766 return IXMLDocument_Release((IXMLDocument *)This);
2769 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2771 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2772 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2774 domdoc *This = impl_from_IObjectSafety(iface);
2776 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2778 if(!pdwSupportedOptions || !pdwEnabledOptions)
2781 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2782 *pdwEnabledOptions = This->safeopt;
2787 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2788 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2790 domdoc *This = impl_from_IObjectSafety(iface);
2791 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2793 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2796 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2800 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2801 xmldoc_Safety_QueryInterface,
2802 xmldoc_Safety_AddRef,
2803 xmldoc_Safety_Release,
2804 xmldoc_Safety_GetInterfaceSafetyOptions,
2805 xmldoc_Safety_SetInterfaceSafetyOptions
2809 static const tid_t domdoc_iface_tids[] = {
2811 IXMLDOMDocument_tid,
2812 IXMLDOMDocument2_tid,
2815 static dispex_static_data_t domdoc_dispex = {
2817 IXMLDOMDocument2_tid,
2822 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
2826 doc = heap_alloc( sizeof (*doc) );
2828 return E_OUTOFMEMORY;
2830 doc->lpVtbl = &domdoc_vtbl;
2831 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
2832 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2833 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2834 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2836 doc->async = VARIANT_TRUE;
2837 doc->validating = 0;
2839 doc->preserving = 0;
2840 doc->properties = properties_from_xmlDocPtr(xmldoc);
2848 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IXMLDOMNode*)&doc->lpVtbl, &domdoc_dispex);
2850 *document = (IXMLDOMDocument3*)&doc->lpVtbl;
2852 TRACE("returning iface %p\n", *document);
2856 HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
2861 TRACE("(%s, %p, %p)\n", debugstr_guid(clsid), pUnkOuter, ppObj);
2863 xmldoc = xmlNewDoc(NULL);
2865 return E_OUTOFMEMORY;
2867 xmldoc->_private = create_priv();
2868 priv_from_xmlDocPtr(xmldoc)->properties = create_properties(clsid);
2870 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument3**)ppObj);
2880 IUnknown* create_domdoc( xmlNodePtr document )
2885 TRACE("(%p)\n", document);
2887 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj);
2896 HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
2898 MESSAGE("This program tried to use a DOMDocument object, but\n"
2899 "libxml2 support was not present at compile time.\n");