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 void xmldoc_init(xmlDocPtr doc, const GUID *clsid)
398 doc->_private = create_priv();
399 priv_from_xmlDocPtr(doc)->properties = create_properties(clsid);
402 LONG xmldoc_add_ref(xmlDocPtr doc)
404 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
405 TRACE("(%p)->(%d)\n", doc, ref);
409 LONG xmldoc_release(xmlDocPtr doc)
411 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
412 LONG ref = InterlockedDecrement(&priv->refs);
413 TRACE("(%p)->(%d)\n", doc, ref);
416 orphan_entry *orphan, *orphan2;
417 TRACE("freeing docptr %p\n", doc);
419 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
421 xmlFreeNode( orphan->node );
424 free_properties(priv->properties);
425 heap_free(doc->_private);
433 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
435 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
438 entry = heap_alloc( sizeof (*entry) );
440 return E_OUTOFMEMORY;
443 list_add_head( &priv->orphans, &entry->entry );
447 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
449 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
450 orphan_entry *entry, *entry2;
452 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
454 if( entry->node == node )
456 list_remove( &entry->entry );
465 static inline xmlDocPtr get_doc( domdoc *This )
467 return (xmlDocPtr)This->node.node;
470 static HRESULT attach_xmldoc(domdoc *This, xmlDocPtr xml )
474 priv_from_xmlDocPtr(get_doc(This))->properties = NULL;
475 if (xmldoc_release(get_doc(This)) != 0)
476 priv_from_xmlDocPtr(get_doc(This))->properties =
477 copy_properties(This->properties);
480 This->node.node = (xmlNodePtr) xml;
484 xmldoc_add_ref(get_doc(This));
485 priv_from_xmlDocPtr(get_doc(This))->properties = This->properties;
491 static inline domdoc *impl_from_IXMLDOMDocument3( IXMLDOMDocument3 *iface )
493 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
496 static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
498 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStreamInit));
501 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
503 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
506 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
508 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
511 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
513 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
516 /************************************************************************
517 * domdoc implementation of IPersistStream.
519 static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
520 IPersistStreamInit *iface, REFIID riid, void **ppvObj)
522 domdoc *this = impl_from_IPersistStreamInit(iface);
523 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
526 static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
527 IPersistStreamInit *iface)
529 domdoc *this = impl_from_IPersistStreamInit(iface);
530 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
533 static ULONG WINAPI domdoc_IPersistStreamInit_Release(
534 IPersistStreamInit *iface)
536 domdoc *this = impl_from_IPersistStreamInit(iface);
537 return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
540 static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
541 IPersistStreamInit *iface, CLSID *classid)
543 TRACE("(%p,%p): stub!\n", iface, classid);
548 *classid = CLSID_DOMDocument2;
553 static HRESULT WINAPI domdoc_IPersistStreamInit_IsDirty(
554 IPersistStreamInit *iface)
556 domdoc *This = impl_from_IPersistStreamInit(iface);
557 FIXME("(%p): stub!\n", This);
561 static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
562 IPersistStreamInit *iface, LPSTREAM pStm)
564 domdoc *This = impl_from_IPersistStreamInit(iface);
567 DWORD read, written, len;
570 xmlDocPtr xmldoc = NULL;
572 TRACE("(%p)->(%p)\n", This, pStm);
577 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
583 IStream_Read(pStm, buf, sizeof(buf), &read);
584 hr = IStream_Write(This->stream, buf, read, &written);
585 } while(SUCCEEDED(hr) && written != 0 && read != 0);
589 ERR("Failed to copy stream\n");
593 hr = GetHGlobalFromStream(This->stream, &hglobal);
597 len = GlobalSize(hglobal);
598 ptr = GlobalLock(hglobal);
600 xmldoc = doparse(This, ptr, len);
601 GlobalUnlock(hglobal);
605 ERR("Failed to parse xml\n");
609 xmldoc->_private = create_priv();
611 return attach_xmldoc(This, xmldoc);
614 static HRESULT WINAPI domdoc_IPersistStreamInit_Save(
615 IPersistStreamInit *iface, IStream *stream, BOOL clr_dirty)
617 domdoc *This = impl_from_IPersistStreamInit(iface);
621 TRACE("(%p)->(%p %d)\n", This, stream, clr_dirty);
623 hr = IXMLDOMDocument3_get_xml( (IXMLDOMDocument3*)&This->lpVtbl, &xmlString );
626 DWORD len = SysStringLen(xmlString) * sizeof(WCHAR);
628 hr = IStream_Write( stream, xmlString, len, NULL );
629 SysFreeString(xmlString);
632 TRACE("ret 0x%08x\n", hr);
637 static HRESULT WINAPI domdoc_IPersistStreamInit_GetSizeMax(
638 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
640 domdoc *This = impl_from_IPersistStreamInit(iface);
641 TRACE("(%p)->(%p): stub!\n", This, pcbSize);
645 static HRESULT WINAPI domdoc_IPersistStreamInit_InitNew(
646 IPersistStreamInit *iface)
648 domdoc *This = impl_from_IPersistStreamInit(iface);
649 TRACE("(%p)\n", This);
653 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
655 domdoc_IPersistStreamInit_QueryInterface,
656 domdoc_IPersistStreamInit_AddRef,
657 domdoc_IPersistStreamInit_Release,
658 domdoc_IPersistStreamInit_GetClassID,
659 domdoc_IPersistStreamInit_IsDirty,
660 domdoc_IPersistStreamInit_Load,
661 domdoc_IPersistStreamInit_Save,
662 domdoc_IPersistStreamInit_GetSizeMax,
663 domdoc_IPersistStreamInit_InitNew
666 /* ISupportErrorInfo interface */
667 static HRESULT WINAPI support_error_QueryInterface(
668 ISupportErrorInfo *iface,
669 REFIID riid, void** ppvObj )
671 domdoc *This = impl_from_ISupportErrorInfo(iface);
672 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3 *)This, riid, ppvObj);
675 static ULONG WINAPI support_error_AddRef(
676 ISupportErrorInfo *iface )
678 domdoc *This = impl_from_ISupportErrorInfo(iface);
679 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3 *)This);
682 static ULONG WINAPI support_error_Release(
683 ISupportErrorInfo *iface )
685 domdoc *This = impl_from_ISupportErrorInfo(iface);
686 return IXMLDOMDocument3_Release((IXMLDOMDocument3 *)This);
689 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
690 ISupportErrorInfo *iface,
693 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
697 static const struct ISupportErrorInfoVtbl support_error_vtbl =
699 support_error_QueryInterface,
700 support_error_AddRef,
701 support_error_Release,
702 support_error_InterfaceSupportsErrorInfo
705 /* IXMLDOMDocument2 interface */
706 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID riid, void** ppvObject )
708 domdoc *This = impl_from_IXMLDOMDocument3( iface );
710 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
714 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
715 IsEqualGUID( riid, &IID_IDispatch ) ||
716 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
717 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
718 IsEqualGUID( riid, &IID_IXMLDOMDocument2 )||
719 IsEqualGUID( riid, &IID_IXMLDOMDocument3 ))
723 else if (IsEqualGUID(&IID_IPersistStream, riid) ||
724 IsEqualGUID(&IID_IPersistStreamInit, riid))
726 *ppvObject = &(This->lpvtblIPersistStreamInit);
728 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
730 *ppvObject = &(This->lpvtblIObjectWithSite);
732 else if (IsEqualGUID(&IID_IObjectSafety, riid))
734 *ppvObject = &(This->lpvtblIObjectSafety);
736 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
738 *ppvObject = &This->lpvtblISupportErrorInfo;
740 else if(node_query_interface(&This->node, riid, ppvObject))
742 return *ppvObject ? S_OK : E_NOINTERFACE;
744 else if(IsEqualGUID(&IID_IRunnableObject, riid))
746 TRACE("IID_IRunnableObject not supported returning NULL\n");
747 return E_NOINTERFACE;
751 FIXME("interface %s not implemented\n", debugstr_guid(riid));
752 return E_NOINTERFACE;
755 IUnknown_AddRef((IUnknown*)*ppvObject);
761 static ULONG WINAPI domdoc_AddRef(
762 IXMLDOMDocument3 *iface )
764 domdoc *This = impl_from_IXMLDOMDocument3( iface );
765 TRACE("%p\n", This );
766 return InterlockedIncrement( &This->ref );
770 static ULONG WINAPI domdoc_Release(
771 IXMLDOMDocument3 *iface )
773 domdoc *This = impl_from_IXMLDOMDocument3( iface );
776 TRACE("%p\n", This );
778 ref = InterlockedDecrement( &This->ref );
782 detach_bsc(This->bsc);
785 IUnknown_Release( This->site );
786 destroy_xmlnode(&This->node);
787 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
788 if (This->stream) IStream_Release(This->stream);
789 HeapFree( GetProcessHeap(), 0, This );
795 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument3 *iface, UINT* pctinfo )
797 domdoc *This = impl_from_IXMLDOMDocument3( iface );
799 TRACE("(%p)->(%p)\n", This, pctinfo);
806 static HRESULT WINAPI domdoc_GetTypeInfo(
807 IXMLDOMDocument3 *iface,
808 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
810 domdoc *This = impl_from_IXMLDOMDocument3( iface );
813 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
815 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
820 static HRESULT WINAPI domdoc_GetIDsOfNames(
821 IXMLDOMDocument3 *iface,
828 domdoc *This = impl_from_IXMLDOMDocument3( iface );
832 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
835 if(!rgszNames || cNames == 0 || !rgDispId)
838 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
841 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
842 ITypeInfo_Release(typeinfo);
849 static HRESULT WINAPI domdoc_Invoke(
850 IXMLDOMDocument3 *iface,
855 DISPPARAMS* pDispParams,
857 EXCEPINFO* pExcepInfo,
860 domdoc *This = impl_from_IXMLDOMDocument3( iface );
864 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
865 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
867 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
870 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
871 pVarResult, pExcepInfo, puArgErr);
872 ITypeInfo_Release(typeinfo);
879 static HRESULT WINAPI domdoc_get_nodeName(
880 IXMLDOMDocument3 *iface,
883 domdoc *This = impl_from_IXMLDOMDocument3( iface );
885 static const WCHAR documentW[] = {'#','d','o','c','u','m','e','n','t',0};
887 TRACE("(%p)->(%p)\n", This, name);
889 return return_bstr(documentW, name);
893 static HRESULT WINAPI domdoc_get_nodeValue(
894 IXMLDOMDocument3 *iface,
897 domdoc *This = impl_from_IXMLDOMDocument3( iface );
899 TRACE("(%p)->(%p)\n", This, value);
904 V_VT(value) = VT_NULL;
905 V_BSTR(value) = NULL; /* tests show that we should do this */
910 static HRESULT WINAPI domdoc_put_nodeValue(
911 IXMLDOMDocument3 *iface,
914 domdoc *This = impl_from_IXMLDOMDocument3( iface );
915 FIXME("(%p)->(v%d)\n", This, V_VT(&value));
920 static HRESULT WINAPI domdoc_get_nodeType(
921 IXMLDOMDocument3 *iface,
924 domdoc *This = impl_from_IXMLDOMDocument3( iface );
926 TRACE("(%p)->(%p)\n", This, type);
928 *type = NODE_DOCUMENT;
933 static HRESULT WINAPI domdoc_get_parentNode(
934 IXMLDOMDocument3 *iface,
935 IXMLDOMNode** parent )
937 domdoc *This = impl_from_IXMLDOMDocument3( iface );
939 TRACE("(%p)->(%p)\n", This, parent);
941 return node_get_parent(&This->node, parent);
945 static HRESULT WINAPI domdoc_get_childNodes(
946 IXMLDOMDocument3 *iface,
947 IXMLDOMNodeList** childList )
949 domdoc *This = impl_from_IXMLDOMDocument3( iface );
951 TRACE("(%p)->(%p)\n", This, childList);
953 return node_get_child_nodes(&This->node, childList);
957 static HRESULT WINAPI domdoc_get_firstChild(
958 IXMLDOMDocument3 *iface,
959 IXMLDOMNode** firstChild )
961 domdoc *This = impl_from_IXMLDOMDocument3( iface );
963 TRACE("(%p)->(%p)\n", This, firstChild);
965 return node_get_first_child(&This->node, firstChild);
969 static HRESULT WINAPI domdoc_get_lastChild(
970 IXMLDOMDocument3 *iface,
971 IXMLDOMNode** lastChild )
973 domdoc *This = impl_from_IXMLDOMDocument3( iface );
975 TRACE("(%p)->(%p)\n", This, lastChild);
977 return node_get_last_child(&This->node, lastChild);
981 static HRESULT WINAPI domdoc_get_previousSibling(
982 IXMLDOMDocument3 *iface,
983 IXMLDOMNode** previousSibling )
985 domdoc *This = impl_from_IXMLDOMDocument3( iface );
987 TRACE("(%p)->(%p)\n", This, previousSibling);
989 return return_null_node(previousSibling);
993 static HRESULT WINAPI domdoc_get_nextSibling(
994 IXMLDOMDocument3 *iface,
995 IXMLDOMNode** nextSibling )
997 domdoc *This = impl_from_IXMLDOMDocument3( iface );
999 TRACE("(%p)->(%p)\n", This, nextSibling);
1001 return return_null_node(nextSibling);
1005 static HRESULT WINAPI domdoc_get_attributes(
1006 IXMLDOMDocument3 *iface,
1007 IXMLDOMNamedNodeMap** attributeMap )
1009 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1011 TRACE("(%p)->(%p)\n", This, attributeMap);
1013 return return_null_ptr((void**)attributeMap);
1017 static HRESULT WINAPI domdoc_insertBefore(
1018 IXMLDOMDocument3 *iface,
1019 IXMLDOMNode* newChild,
1021 IXMLDOMNode** outNewChild )
1023 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1025 TRACE("(%p)->(%p x%d %p)\n", This, newChild, V_VT(&refChild), outNewChild);
1027 return node_insert_before(&This->node, newChild, &refChild, outNewChild);
1031 static HRESULT WINAPI domdoc_replaceChild(
1032 IXMLDOMDocument3 *iface,
1033 IXMLDOMNode* newChild,
1034 IXMLDOMNode* oldChild,
1035 IXMLDOMNode** outOldChild)
1037 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1039 TRACE("(%p)->(%p %p %p)\n", This, newChild, oldChild, outOldChild);
1041 return node_replace_child(&This->node, newChild, oldChild, outOldChild);
1045 static HRESULT WINAPI domdoc_removeChild(
1046 IXMLDOMDocument3 *iface,
1047 IXMLDOMNode* childNode,
1048 IXMLDOMNode** oldChild)
1050 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1051 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
1055 static HRESULT WINAPI domdoc_appendChild(
1056 IXMLDOMDocument3 *iface,
1057 IXMLDOMNode* newChild,
1058 IXMLDOMNode** outNewChild)
1060 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1061 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
1065 static HRESULT WINAPI domdoc_hasChildNodes(
1066 IXMLDOMDocument3 *iface,
1067 VARIANT_BOOL* hasChild)
1069 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1070 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
1074 static HRESULT WINAPI domdoc_get_ownerDocument(
1075 IXMLDOMDocument3 *iface,
1076 IXMLDOMDocument** DOMDocument)
1078 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1079 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
1083 static HRESULT WINAPI domdoc_cloneNode(
1084 IXMLDOMDocument3 *iface,
1086 IXMLDOMNode** cloneRoot)
1088 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1089 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
1093 static HRESULT WINAPI domdoc_get_nodeTypeString(
1094 IXMLDOMDocument3 *iface,
1097 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1098 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
1102 static HRESULT WINAPI domdoc_get_text(
1103 IXMLDOMDocument3 *iface,
1106 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1107 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
1111 static HRESULT WINAPI domdoc_put_text(
1112 IXMLDOMDocument3 *iface,
1115 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1116 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
1120 static HRESULT WINAPI domdoc_get_specified(
1121 IXMLDOMDocument3 *iface,
1122 VARIANT_BOOL* isSpecified )
1124 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1125 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
1129 static HRESULT WINAPI domdoc_get_definition(
1130 IXMLDOMDocument3 *iface,
1131 IXMLDOMNode** definitionNode )
1133 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1134 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
1138 static HRESULT WINAPI domdoc_get_nodeTypedValue(
1139 IXMLDOMDocument3 *iface,
1140 VARIANT* typedValue )
1142 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1143 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
1146 static HRESULT WINAPI domdoc_put_nodeTypedValue(
1147 IXMLDOMDocument3 *iface,
1148 VARIANT typedValue )
1150 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1151 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
1155 static HRESULT WINAPI domdoc_get_dataType(
1156 IXMLDOMDocument3 *iface,
1157 VARIANT* dataTypeName )
1159 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1160 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
1164 static HRESULT WINAPI domdoc_put_dataType(
1165 IXMLDOMDocument3 *iface,
1168 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1169 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
1173 static HRESULT WINAPI domdoc_get_xml(
1174 IXMLDOMDocument3 *iface,
1177 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1178 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
1182 static HRESULT WINAPI domdoc_transformNode(
1183 IXMLDOMDocument3 *iface,
1184 IXMLDOMNode* styleSheet,
1187 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1188 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
1192 static HRESULT WINAPI domdoc_selectNodes(
1193 IXMLDOMDocument3 *iface,
1195 IXMLDOMNodeList** resultList )
1197 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1198 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
1202 static HRESULT WINAPI domdoc_selectSingleNode(
1203 IXMLDOMDocument3 *iface,
1205 IXMLDOMNode** resultNode )
1207 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1208 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
1212 static HRESULT WINAPI domdoc_get_parsed(
1213 IXMLDOMDocument3 *iface,
1214 VARIANT_BOOL* isParsed )
1216 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1217 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
1221 static HRESULT WINAPI domdoc_get_namespaceURI(
1222 IXMLDOMDocument3 *iface,
1223 BSTR* namespaceURI )
1225 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1226 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
1230 static HRESULT WINAPI domdoc_get_prefix(
1231 IXMLDOMDocument3 *iface,
1232 BSTR* prefixString )
1234 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1235 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
1239 static HRESULT WINAPI domdoc_get_baseName(
1240 IXMLDOMDocument3 *iface,
1243 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1244 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
1248 static HRESULT WINAPI domdoc_transformNodeToObject(
1249 IXMLDOMDocument3 *iface,
1250 IXMLDOMNode* stylesheet,
1251 VARIANT outputObject)
1253 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1254 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
1258 static HRESULT WINAPI domdoc_get_doctype(
1259 IXMLDOMDocument3 *iface,
1260 IXMLDOMDocumentType** documentType )
1262 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1263 FIXME("(%p)\n", This);
1268 static HRESULT WINAPI domdoc_get_implementation(
1269 IXMLDOMDocument3 *iface,
1270 IXMLDOMImplementation** impl )
1272 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1274 TRACE("(%p)->(%p)\n", This, impl);
1277 return E_INVALIDARG;
1279 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1284 static HRESULT WINAPI domdoc_get_documentElement(
1285 IXMLDOMDocument3 *iface,
1286 IXMLDOMElement** DOMElement )
1288 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1289 IXMLDOMNode *element_node;
1293 TRACE("(%p)->(%p)\n", This, DOMElement);
1296 return E_INVALIDARG;
1300 root = xmlDocGetRootElement( get_doc(This) );
1304 element_node = create_node( root );
1305 if(!element_node) return S_FALSE;
1307 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (void**)DOMElement);
1308 IXMLDOMNode_Release(element_node);
1314 static HRESULT WINAPI domdoc_put_documentElement(
1315 IXMLDOMDocument3 *iface,
1316 IXMLDOMElement* DOMElement )
1318 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1319 IXMLDOMNode *elementNode;
1324 TRACE("(%p)->(%p)\n", This, DOMElement);
1326 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1330 xmlNode = get_node_obj( elementNode );
1332 FIXME("elementNode is not our object\n");
1336 if(!xmlNode->node->parent)
1337 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1338 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1340 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1341 IXMLDOMNode_Release( elementNode );
1344 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1350 static HRESULT WINAPI domdoc_createElement(
1351 IXMLDOMDocument3 *iface,
1353 IXMLDOMElement** element )
1355 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1360 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1362 if (!element || !tagname) return E_INVALIDARG;
1364 V_VT(&type) = VT_I1;
1365 V_I1(&type) = NODE_ELEMENT;
1367 hr = IXMLDOMDocument3_createNode(iface, type, tagname, NULL, &node);
1370 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1371 IXMLDOMNode_Release(node);
1378 static HRESULT WINAPI domdoc_createDocumentFragment(
1379 IXMLDOMDocument3 *iface,
1380 IXMLDOMDocumentFragment** frag )
1382 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1387 TRACE("(%p)->(%p)\n", This, frag);
1389 if (!frag) return E_INVALIDARG;
1393 V_VT(&type) = VT_I1;
1394 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1396 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1399 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1400 IXMLDOMNode_Release(node);
1407 static HRESULT WINAPI domdoc_createTextNode(
1408 IXMLDOMDocument3 *iface,
1410 IXMLDOMText** text )
1412 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1417 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1419 if (!text) return E_INVALIDARG;
1423 V_VT(&type) = VT_I1;
1424 V_I1(&type) = NODE_TEXT;
1426 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1429 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1430 IXMLDOMNode_Release(node);
1431 hr = IXMLDOMText_put_data(*text, data);
1438 static HRESULT WINAPI domdoc_createComment(
1439 IXMLDOMDocument3 *iface,
1441 IXMLDOMComment** comment )
1443 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1448 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1450 if (!comment) return E_INVALIDARG;
1454 V_VT(&type) = VT_I1;
1455 V_I1(&type) = NODE_COMMENT;
1457 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1460 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1461 IXMLDOMNode_Release(node);
1462 hr = IXMLDOMComment_put_data(*comment, data);
1469 static HRESULT WINAPI domdoc_createCDATASection(
1470 IXMLDOMDocument3 *iface,
1472 IXMLDOMCDATASection** cdata )
1474 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1479 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1481 if (!cdata) return E_INVALIDARG;
1485 V_VT(&type) = VT_I1;
1486 V_I1(&type) = NODE_CDATA_SECTION;
1488 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1491 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1492 IXMLDOMNode_Release(node);
1493 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1500 static HRESULT WINAPI domdoc_createProcessingInstruction(
1501 IXMLDOMDocument3 *iface,
1504 IXMLDOMProcessingInstruction** pi )
1506 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1511 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1513 if (!pi) return E_INVALIDARG;
1517 V_VT(&type) = VT_I1;
1518 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1520 hr = IXMLDOMDocument3_createNode(iface, type, target, NULL, &node);
1526 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1527 node_obj = get_node_obj(node);
1528 V_VT(&v_data) = VT_BSTR;
1529 V_BSTR(&v_data) = data;
1531 hr = node_put_value(node_obj, &v_data);
1533 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1534 IXMLDOMNode_Release(node);
1541 static HRESULT WINAPI domdoc_createAttribute(
1542 IXMLDOMDocument3 *iface,
1544 IXMLDOMAttribute** attribute )
1546 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1551 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1553 if (!attribute || !name) return E_INVALIDARG;
1555 V_VT(&type) = VT_I1;
1556 V_I1(&type) = NODE_ATTRIBUTE;
1558 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1561 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1562 IXMLDOMNode_Release(node);
1569 static HRESULT WINAPI domdoc_createEntityReference(
1570 IXMLDOMDocument3 *iface,
1572 IXMLDOMEntityReference** entityref )
1574 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1579 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1581 if (!entityref) return E_INVALIDARG;
1585 V_VT(&type) = VT_I1;
1586 V_I1(&type) = NODE_ENTITY_REFERENCE;
1588 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1591 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1592 IXMLDOMNode_Release(node);
1599 static HRESULT WINAPI domdoc_getElementsByTagName(
1600 IXMLDOMDocument3 *iface,
1602 IXMLDOMNodeList** resultList )
1604 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1607 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1609 if (!tagName || !resultList) return E_INVALIDARG;
1611 if (tagName[0] == '*' && tagName[1] == 0)
1613 static const WCHAR formatallW[] = {'/','/','*',0};
1614 hr = queryresult_create((xmlNodePtr)get_doc(This), formatallW, resultList);
1618 static const WCHAR xpathformat[] =
1619 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
1620 static const WCHAR closeW[] = { '\'',']',0 };
1626 length = lstrlenW(tagName);
1628 /* without two WCHARs from format specifier */
1629 ptr = pattern = heap_alloc(sizeof(xpathformat) + length*sizeof(WCHAR) + sizeof(closeW));
1631 memcpy(ptr, xpathformat, sizeof(xpathformat));
1632 ptr += sizeof(xpathformat)/sizeof(WCHAR);
1633 memcpy(ptr, tagName, length*sizeof(WCHAR));
1635 memcpy(ptr, closeW, sizeof(closeW));
1637 hr = queryresult_create((xmlNodePtr)get_doc(This), pattern, resultList);
1644 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1650 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1652 return E_INVALIDARG;
1659 static HRESULT WINAPI domdoc_createNode(
1660 IXMLDOMDocument3 *iface,
1664 IXMLDOMNode** node )
1666 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1667 DOMNodeType node_type;
1669 xmlChar *xml_name, *href;
1672 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1674 if(!node) return E_INVALIDARG;
1676 hr = get_node_type(Type, &node_type);
1677 if(FAILED(hr)) return hr;
1679 if(namespaceURI && namespaceURI[0] && node_type != NODE_ELEMENT)
1680 FIXME("nodes with namespaces currently not supported.\n");
1682 TRACE("node_type %d\n", node_type);
1684 /* exit earlier for types that need name */
1688 case NODE_ATTRIBUTE:
1689 case NODE_ENTITY_REFERENCE:
1690 case NODE_PROCESSING_INSTRUCTION:
1691 if (!name || *name == 0) return E_FAIL;
1696 xml_name = xmlChar_from_wchar(name);
1697 /* prevent empty href to be allocated */
1698 href = namespaceURI ? xmlChar_from_wchar(namespaceURI) : NULL;
1704 xmlChar *local, *prefix;
1706 local = xmlSplitQName2(xml_name, &prefix);
1708 xmlnode = xmlNewDocNode(get_doc(This), NULL, local ? local : xml_name, NULL);
1710 /* allow to create default namespace xmlns= */
1711 if (local || (href && *href))
1713 xmlNsPtr ns = xmlNewNs(xmlnode, href, prefix);
1714 xmlSetNs(xmlnode, ns);
1722 case NODE_ATTRIBUTE:
1723 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1726 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1728 case NODE_CDATA_SECTION:
1729 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1731 case NODE_ENTITY_REFERENCE:
1732 xmlnode = xmlNewReference(get_doc(This), xml_name);
1734 case NODE_PROCESSING_INSTRUCTION:
1735 #ifdef HAVE_XMLNEWDOCPI
1736 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1738 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1743 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1745 case NODE_DOCUMENT_FRAGMENT:
1746 xmlnode = xmlNewDocFragment(get_doc(This));
1748 /* unsupported types */
1750 case NODE_DOCUMENT_TYPE:
1753 heap_free(xml_name);
1754 return E_INVALIDARG;
1756 FIXME("unhandled node type %d\n", node_type);
1761 *node = create_node(xmlnode);
1762 heap_free(xml_name);
1767 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1768 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1775 static HRESULT WINAPI domdoc_nodeFromID(
1776 IXMLDOMDocument3 *iface,
1778 IXMLDOMNode** node )
1780 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1781 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1785 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1790 xmldoc = doparse(This, ptr, len);
1792 xmldoc->_private = create_priv();
1793 return attach_xmldoc(This, xmldoc);
1799 static HRESULT doread( domdoc *This, LPWSTR filename )
1804 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1809 detach_bsc(This->bsc);
1815 static HRESULT WINAPI domdoc_load(
1816 IXMLDOMDocument3 *iface,
1818 VARIANT_BOOL* isSuccessful )
1820 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1821 LPWSTR filename = NULL;
1822 HRESULT hr = S_FALSE;
1823 IXMLDOMDocument3 *pNewDoc = NULL;
1824 IStream *pStream = NULL;
1827 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1829 *isSuccessful = VARIANT_FALSE;
1831 assert( &This->node );
1833 switch( V_VT(&xmlSource) )
1836 filename = V_BSTR(&xmlSource);
1839 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument3, (void**)&pNewDoc);
1844 domdoc *newDoc = impl_from_IXMLDOMDocument3( pNewDoc );
1845 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1846 hr = attach_xmldoc(This, xmldoc);
1849 *isSuccessful = VARIANT_TRUE;
1854 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1857 IPersistStream *pDocStream;
1858 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1861 hr = IPersistStream_Load(pDocStream, pStream);
1862 IStream_Release(pStream);
1865 *isSuccessful = VARIANT_TRUE;
1867 TRACE("Using IStream to load Document\n");
1872 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1877 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1882 /* ISequentialStream */
1883 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1887 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1890 TRACE("filename (%s)\n", debugstr_w(filename));
1894 hr = doread( This, filename );
1897 This->error = E_FAIL;
1900 hr = This->error = S_OK;
1901 *isSuccessful = VARIANT_TRUE;
1905 if(!filename || FAILED(hr)) {
1906 xmldoc = xmlNewDoc(NULL);
1907 xmldoc->_private = create_priv();
1908 hr = attach_xmldoc(This, xmldoc);
1913 TRACE("ret (%d)\n", hr);
1919 static HRESULT WINAPI domdoc_get_readyState(
1920 IXMLDOMDocument3 *iface,
1923 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1924 FIXME("stub! (%p)->(%p)\n", This, value);
1927 return E_INVALIDARG;
1929 *value = READYSTATE_COMPLETE;
1934 static HRESULT WINAPI domdoc_get_parseError(
1935 IXMLDOMDocument3 *iface,
1936 IXMLDOMParseError** errorObj )
1938 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1939 static const WCHAR err[] = {'e','r','r','o','r',0};
1940 BSTR error_string = NULL;
1942 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1945 error_string = SysAllocString(err);
1947 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1948 if(!*errorObj) return E_OUTOFMEMORY;
1953 static HRESULT WINAPI domdoc_get_url(
1954 IXMLDOMDocument3 *iface,
1957 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1958 FIXME("(%p)->(%p)\n", This, urlString);
1963 static HRESULT WINAPI domdoc_get_async(
1964 IXMLDOMDocument3 *iface,
1965 VARIANT_BOOL* isAsync )
1967 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1969 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1970 *isAsync = This->async;
1975 static HRESULT WINAPI domdoc_put_async(
1976 IXMLDOMDocument3 *iface,
1977 VARIANT_BOOL isAsync )
1979 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1981 TRACE("(%p)->(%d)\n", This, isAsync);
1982 This->async = isAsync;
1987 static HRESULT WINAPI domdoc_abort(
1988 IXMLDOMDocument3 *iface )
1990 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1991 FIXME("%p\n", This);
1996 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
2001 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
2002 str = heap_alloc( len );
2005 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
2011 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
2012 static HRESULT WINAPI domdoc_loadXML(
2013 IXMLDOMDocument3 *iface,
2015 VARIANT_BOOL* isSuccessful )
2017 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2018 xmlDocPtr xmldoc = NULL;
2019 HRESULT hr = S_FALSE, hr2;
2023 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
2025 assert ( &This->node );
2029 *isSuccessful = VARIANT_FALSE;
2031 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
2033 xmldoc = doparse(This, str, len);
2036 This->error = E_FAIL;
2039 hr = This->error = S_OK;
2040 *isSuccessful = VARIANT_TRUE;
2041 TRACE("parsed document %p\n", xmldoc);
2046 xmldoc = xmlNewDoc(NULL);
2048 xmldoc->_private = create_priv();
2050 hr2 = attach_xmldoc(This, xmldoc);
2057 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
2062 if(!WriteFile(ctx, buffer, len, &written, NULL))
2064 WARN("write error\n");
2071 static int XMLCALL domdoc_save_closecallback(void *ctx)
2073 return CloseHandle(ctx) ? 0 : -1;
2076 static HRESULT WINAPI domdoc_save(
2077 IXMLDOMDocument3 *iface,
2078 VARIANT destination )
2080 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2086 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
2087 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
2089 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
2091 FIXME("Unhandled vt %d\n", V_VT(&destination));
2095 if(V_VT(&destination) == VT_UNKNOWN)
2097 IUnknown *pUnk = V_UNKNOWN(&destination);
2098 IXMLDOMDocument2 *pDocument;
2100 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&pDocument);
2103 VARIANT_BOOL success;
2106 ret = IXMLDOMDocument3_get_xml(iface, &xml);
2109 ret = IXMLDOMDocument3_loadXML(pDocument, xml, &success);
2113 IXMLDOMDocument3_Release(pDocument);
2116 TRACE("ret %d\n", ret);
2121 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
2122 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
2123 if( handle == INVALID_HANDLE_VALUE )
2125 WARN("failed to create file\n");
2129 /* disable top XML declaration */
2130 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
2131 handle, NULL, XML_SAVE_NO_DECL);
2134 CloseHandle(handle);
2138 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
2139 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
2140 xmldoc_link_xmldecl(get_doc(This), xmldecl);
2142 /* will close file through close callback */
2148 static HRESULT WINAPI domdoc_get_validateOnParse(
2149 IXMLDOMDocument3 *iface,
2150 VARIANT_BOOL* isValidating )
2152 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2153 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
2154 *isValidating = This->validating;
2159 static HRESULT WINAPI domdoc_put_validateOnParse(
2160 IXMLDOMDocument3 *iface,
2161 VARIANT_BOOL isValidating )
2163 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2164 TRACE("(%p)->(%d)\n", This, isValidating);
2165 This->validating = isValidating;
2170 static HRESULT WINAPI domdoc_get_resolveExternals(
2171 IXMLDOMDocument3 *iface,
2172 VARIANT_BOOL* isResolving )
2174 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2175 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
2176 *isResolving = This->resolving;
2181 static HRESULT WINAPI domdoc_put_resolveExternals(
2182 IXMLDOMDocument3 *iface,
2183 VARIANT_BOOL isResolving )
2185 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2186 TRACE("(%p)->(%d)\n", This, isResolving);
2187 This->resolving = isResolving;
2192 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
2193 IXMLDOMDocument3 *iface,
2194 VARIANT_BOOL* isPreserving )
2196 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2197 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
2198 *isPreserving = This->preserving;
2203 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
2204 IXMLDOMDocument3 *iface,
2205 VARIANT_BOOL isPreserving )
2207 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2208 TRACE("(%p)->(%d)\n", This, isPreserving);
2209 This->preserving = isPreserving;
2214 static HRESULT WINAPI domdoc_put_onReadyStateChange(
2215 IXMLDOMDocument3 *iface,
2216 VARIANT readyStateChangeSink )
2218 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2219 FIXME("%p\n", This);
2224 static HRESULT WINAPI domdoc_put_onDataAvailable(
2225 IXMLDOMDocument3 *iface,
2226 VARIANT onDataAvailableSink )
2228 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2229 FIXME("%p\n", This);
2233 static HRESULT WINAPI domdoc_put_onTransformNode(
2234 IXMLDOMDocument3 *iface,
2235 VARIANT onTransformNodeSink )
2237 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2238 FIXME("%p\n", This);
2242 static HRESULT WINAPI domdoc_get_namespaces(
2243 IXMLDOMDocument3* iface,
2244 IXMLDOMSchemaCollection** schemaCollection )
2246 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2247 FIXME("(%p)->(%p)\n", This, schemaCollection);
2251 static HRESULT WINAPI domdoc_get_schemas(
2252 IXMLDOMDocument3* iface,
2255 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2256 HRESULT hr = S_FALSE;
2257 IXMLDOMSchemaCollection *cur_schema = This->schema;
2259 TRACE("(%p)->(%p)\n", This, var1);
2261 VariantInit(var1); /* Test shows we don't call VariantClear here */
2262 V_VT(var1) = VT_NULL;
2266 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
2268 V_VT(var1) = VT_DISPATCH;
2273 static HRESULT WINAPI domdoc_putref_schemas(
2274 IXMLDOMDocument3* iface,
2277 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2278 HRESULT hr = E_FAIL;
2279 IXMLDOMSchemaCollection *new_schema = NULL;
2281 FIXME("(%p): semi-stub\n", This);
2285 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2289 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2298 WARN("Can't get schema from vt %x\n", V_VT(&var1));
2303 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
2304 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
2310 static HRESULT WINAPI domdoc_validate(
2311 IXMLDOMDocument3* iface,
2312 IXMLDOMParseError** err)
2314 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2316 xmlValidCtxtPtr vctx;
2318 TRACE("(%p)->(%p)\n", This, err);
2319 domdoc_get_readyState(iface, &state);
2320 if (state != READYSTATE_COMPLETE)
2323 *err = create_parseError(0, NULL, NULL, NULL, 0, 0, 0);
2327 vctx = xmlNewValidCtxt();
2328 vctx->error = NULL; /* TODO: error callback */
2329 vctx->warning = NULL; /* TODO: warning callback */
2331 if (xmlValidateDocument(vctx, get_doc(This)))
2334 *err = create_parseError(0, NULL, NULL, NULL, 0, 0, 0);
2335 xmlFreeValidCtxt(vctx);
2339 FIXME("partial stub!\n");
2341 *err = create_parseError(0xC00CE223, NULL, NULL, NULL, 0, 0, 0);
2342 xmlFreeValidCtxt(vctx);
2346 static HRESULT WINAPI domdoc_setProperty(
2347 IXMLDOMDocument3* iface,
2351 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2353 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
2355 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2361 V_VT(&varStr) = VT_EMPTY;
2362 if (V_VT(&var) != VT_BSTR)
2364 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2366 bstr = V_BSTR(&varStr);
2369 bstr = V_BSTR(&var);
2372 if (lstrcmpiW(bstr, PropValueXPathW) == 0)
2373 This->properties->XPath = TRUE;
2374 else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
2375 This->properties->XPath = FALSE;
2379 VariantClear(&varStr);
2382 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2387 xmlChar *pTokBegin, *pTokEnd, *pTokInner;
2388 xmlChar *nsStr = (xmlChar*)This->properties->selectNsStr;
2389 xmlXPathContextPtr ctx;
2390 struct list *pNsList;
2391 select_ns_entry* pNsEntry = NULL;
2393 V_VT(&varStr) = VT_EMPTY;
2394 if (V_VT(&var) != VT_BSTR)
2396 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2398 bstr = V_BSTR(&varStr);
2401 bstr = V_BSTR(&var);
2405 pNsList = &(This->properties->selectNsList);
2406 clear_selectNsList(pNsList);
2408 nsStr = xmlChar_from_wchar(bstr);
2411 TRACE("Setting SelectionNamespaces property to: %s\n", nsStr);
2413 This->properties->selectNsStr = nsStr;
2414 This->properties->selectNsStr_len = xmlStrlen(nsStr);
2417 ctx = xmlXPathNewContext(This->node.node->doc);
2420 for (; *pTokBegin; pTokBegin = pTokEnd)
2422 if (pNsEntry != NULL)
2423 memset(pNsEntry, 0, sizeof(select_ns_entry));
2425 pNsEntry = heap_alloc_zero(sizeof(select_ns_entry));
2427 while (*pTokBegin == ' ')
2429 pTokEnd = pTokBegin;
2430 while (*pTokEnd != ' ' && *pTokEnd != 0)
2433 if (xmlStrncmp(pTokBegin, (xmlChar const*)"xmlns", 5) != 0)
2436 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2437 wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokBegin, pTokEnd-pTokBegin));
2442 if (*pTokBegin == '=')
2444 /*valid for XSLPattern?*/
2445 FIXME("Setting default xmlns not supported - skipping.\n");
2446 pTokBegin = pTokEnd;
2449 else if (*pTokBegin == ':')
2451 pNsEntry->prefix = ++pTokBegin;
2452 for (pTokInner = pTokBegin; pTokInner != pTokEnd && *pTokInner != '='; ++pTokInner)
2455 if (pTokInner == pTokEnd)
2458 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2459 wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokBegin, pTokEnd-pTokBegin));
2463 pNsEntry->prefix_end = *pTokInner;
2467 if (pTokEnd-pTokInner > 1 &&
2468 ((*pTokInner == '\'' && *(pTokEnd-1) == '\'') ||
2469 (*pTokInner == '"' && *(pTokEnd-1) == '"')))
2471 pNsEntry->href = ++pTokInner;
2472 pNsEntry->href_end = *(pTokEnd-1);
2474 list_add_tail(pNsList, &pNsEntry->entry);
2475 /*let libxml figure out if they're valid from here ;)*/
2476 if (xmlXPathRegisterNs(ctx, pNsEntry->prefix, pNsEntry->href) != 0)
2485 WARN("Syntax error in xmlns string: %s\n\tat token: %s\n",
2486 wine_dbgstr_w(bstr), wine_dbgstr_an((const char*)pTokInner, pTokEnd-pTokInner));
2487 list_add_tail(pNsList, &pNsEntry->entry);
2500 heap_free(pNsEntry);
2501 xmlXPathFreeContext(ctx);
2504 VariantClear(&varStr);
2507 else if (lstrcmpiW(p, PropertyProhibitDTDW) == 0 ||
2508 lstrcmpiW(p, PropertyNewParserW) == 0)
2511 FIXME("Ignoring property %s, value %d\n", debugstr_w(p), V_BOOL(&var));
2515 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2519 static HRESULT WINAPI domdoc_getProperty(
2520 IXMLDOMDocument3* iface,
2524 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2526 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2529 return E_INVALIDARG;
2531 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2533 V_VT(var) = VT_BSTR;
2534 V_BSTR(var) = This->properties->XPath ?
2535 SysAllocString(PropValueXPathW) :
2536 SysAllocString(PropValueXSLPatternW);
2537 return V_BSTR(var) ? S_OK : E_OUTOFMEMORY;
2539 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2542 BSTR rebuiltStr, cur;
2543 const xmlChar *nsStr;
2544 struct list *pNsList;
2545 select_ns_entry* pNsEntry;
2547 V_VT(var) = VT_BSTR;
2548 nsStr = This->properties->selectNsStr;
2549 pNsList = &This->properties->selectNsList;
2550 lenA = This->properties->selectNsStr_len;
2551 lenW = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, NULL, 0);
2552 rebuiltStr = heap_alloc(lenW*sizeof(WCHAR));
2553 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)nsStr, lenA+1, rebuiltStr, lenW);
2555 /* this is fine because all of the chars that end tokens are ASCII*/
2556 LIST_FOR_EACH_ENTRY(pNsEntry, pNsList, select_ns_entry, entry)
2558 while (*cur != 0) ++cur;
2559 if (pNsEntry->prefix_end)
2561 *cur = pNsEntry->prefix_end;
2562 while (*cur != 0) ++cur;
2565 if (pNsEntry->href_end)
2567 *cur = pNsEntry->href_end;
2570 V_BSTR(var) = SysAllocString(rebuiltStr);
2571 heap_free(rebuiltStr);
2575 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2579 static HRESULT WINAPI domdoc_validateNode(
2580 IXMLDOMDocument3* iface,
2582 IXMLDOMParseError** error)
2584 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2585 FIXME("(%p)->(%p %p): stub\n", This, node, error);
2589 static HRESULT WINAPI domdoc_importNode(
2590 IXMLDOMDocument3* iface,
2593 IXMLDOMNode** clone)
2595 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2596 FIXME("(%p)->(%p %d %p): stub\n", This, node, deep, clone);
2600 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl =
2602 domdoc_QueryInterface,
2605 domdoc_GetTypeInfoCount,
2607 domdoc_GetIDsOfNames,
2609 domdoc_get_nodeName,
2610 domdoc_get_nodeValue,
2611 domdoc_put_nodeValue,
2612 domdoc_get_nodeType,
2613 domdoc_get_parentNode,
2614 domdoc_get_childNodes,
2615 domdoc_get_firstChild,
2616 domdoc_get_lastChild,
2617 domdoc_get_previousSibling,
2618 domdoc_get_nextSibling,
2619 domdoc_get_attributes,
2620 domdoc_insertBefore,
2621 domdoc_replaceChild,
2624 domdoc_hasChildNodes,
2625 domdoc_get_ownerDocument,
2627 domdoc_get_nodeTypeString,
2630 domdoc_get_specified,
2631 domdoc_get_definition,
2632 domdoc_get_nodeTypedValue,
2633 domdoc_put_nodeTypedValue,
2634 domdoc_get_dataType,
2635 domdoc_put_dataType,
2637 domdoc_transformNode,
2639 domdoc_selectSingleNode,
2641 domdoc_get_namespaceURI,
2643 domdoc_get_baseName,
2644 domdoc_transformNodeToObject,
2646 domdoc_get_implementation,
2647 domdoc_get_documentElement,
2648 domdoc_put_documentElement,
2649 domdoc_createElement,
2650 domdoc_createDocumentFragment,
2651 domdoc_createTextNode,
2652 domdoc_createComment,
2653 domdoc_createCDATASection,
2654 domdoc_createProcessingInstruction,
2655 domdoc_createAttribute,
2656 domdoc_createEntityReference,
2657 domdoc_getElementsByTagName,
2661 domdoc_get_readyState,
2662 domdoc_get_parseError,
2669 domdoc_get_validateOnParse,
2670 domdoc_put_validateOnParse,
2671 domdoc_get_resolveExternals,
2672 domdoc_put_resolveExternals,
2673 domdoc_get_preserveWhiteSpace,
2674 domdoc_put_preserveWhiteSpace,
2675 domdoc_put_onReadyStateChange,
2676 domdoc_put_onDataAvailable,
2677 domdoc_put_onTransformNode,
2678 domdoc_get_namespaces,
2680 domdoc_putref_schemas,
2684 domdoc_validateNode,
2688 /* xmldoc implementation of IObjectWithSite */
2689 static HRESULT WINAPI
2690 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2692 domdoc *This = impl_from_IObjectWithSite(iface);
2693 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2697 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2699 domdoc *This = impl_from_IObjectWithSite(iface);
2700 return IXMLDocument_AddRef((IXMLDocument *)This);
2704 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2706 domdoc *This = impl_from_IObjectWithSite(iface);
2707 return IXMLDocument_Release((IXMLDocument *)This);
2710 static HRESULT WINAPI
2711 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2713 domdoc *This = impl_from_IObjectWithSite(iface);
2715 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2720 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2723 static HRESULT WINAPI
2724 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2726 domdoc *This = impl_from_IObjectWithSite(iface);
2728 TRACE("(%p)->(%p)\n", iface, punk);
2734 IUnknown_Release( This->site );
2741 IUnknown_AddRef( punk );
2744 IUnknown_Release( This->site );
2751 static const IObjectWithSiteVtbl domdocObjectSite =
2753 xmldoc_ObjectWithSite_QueryInterface,
2754 xmldoc_ObjectWithSite_AddRef,
2755 xmldoc_ObjectWithSite_Release,
2760 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2762 domdoc *This = impl_from_IObjectSafety(iface);
2763 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2766 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2768 domdoc *This = impl_from_IObjectSafety(iface);
2769 return IXMLDocument_AddRef((IXMLDocument *)This);
2772 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2774 domdoc *This = impl_from_IObjectSafety(iface);
2775 return IXMLDocument_Release((IXMLDocument *)This);
2778 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2780 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2781 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2783 domdoc *This = impl_from_IObjectSafety(iface);
2785 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2787 if(!pdwSupportedOptions || !pdwEnabledOptions)
2790 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2791 *pdwEnabledOptions = This->safeopt;
2796 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2797 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2799 domdoc *This = impl_from_IObjectSafety(iface);
2800 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2802 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2805 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2809 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2810 xmldoc_Safety_QueryInterface,
2811 xmldoc_Safety_AddRef,
2812 xmldoc_Safety_Release,
2813 xmldoc_Safety_GetInterfaceSafetyOptions,
2814 xmldoc_Safety_SetInterfaceSafetyOptions
2818 static const tid_t domdoc_iface_tids[] = {
2820 IXMLDOMDocument_tid,
2821 IXMLDOMDocument2_tid,
2824 static dispex_static_data_t domdoc_dispex = {
2826 IXMLDOMDocument2_tid,
2831 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
2835 doc = heap_alloc( sizeof (*doc) );
2837 return E_OUTOFMEMORY;
2839 doc->lpVtbl = &domdoc_vtbl;
2840 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
2841 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2842 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2843 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2845 doc->async = VARIANT_TRUE;
2846 doc->validating = 0;
2848 doc->preserving = 0;
2849 doc->properties = properties_from_xmlDocPtr(xmldoc);
2857 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IXMLDOMNode*)&doc->lpVtbl, &domdoc_dispex);
2859 *document = (IXMLDOMDocument3*)&doc->lpVtbl;
2861 TRACE("returning iface %p\n", *document);
2865 HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
2870 TRACE("(%s, %p, %p)\n", debugstr_guid(clsid), pUnkOuter, ppObj);
2872 xmldoc = xmlNewDoc(NULL);
2874 return E_OUTOFMEMORY;
2876 xmldoc->_private = create_priv();
2877 priv_from_xmlDocPtr(xmldoc)->properties = create_properties(clsid);
2879 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument3**)ppObj);
2882 free_properties(properties_from_xmlDocPtr(xmldoc));
2883 heap_free(xmldoc->_private);
2891 IUnknown* create_domdoc( xmlNodePtr document )
2896 TRACE("(%p)\n", document);
2898 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj);
2907 HRESULT DOMDocument_create(const GUID *clsid, IUnknown *pUnkOuter, void **ppObj)
2909 MESSAGE("This program tried to use a DOMDocument object, but\n"
2910 "libxml2 support was not present at compile time.\n");