msxml3: Support elements with namespaces.
[wine.git] / dlls / msxml3 / domdoc.c
blob9053a7d27a93b0693dc55eca683c7c76e3b93dcf
1 /*
2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #define NONAMELESSUNION
24 #include "config.h"
26 #include <stdarg.h>
27 #include <assert.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "winnls.h"
32 #include "ole2.h"
33 #include "msxml6.h"
34 #include "wininet.h"
35 #include "winreg.h"
36 #include "shlwapi.h"
37 #include "ocidl.h"
38 #include "objsafe.h"
39 #include "dispex.h"
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 #include "msxml_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
48 #ifdef HAVE_LIBXML2
50 #include <libxml/xmlsave.h>
52 /* not defined in older versions */
53 #define XML_SAVE_FORMAT 1
54 #define XML_SAVE_NO_DECL 2
55 #define XML_SAVE_NO_EMPTY 4
56 #define XML_SAVE_NO_XHTML 8
57 #define XML_SAVE_XHTML 16
58 #define XML_SAVE_AS_XML 32
59 #define XML_SAVE_AS_HTML 64
61 static const WCHAR PropertySelectionLanguageW[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
62 static const WCHAR PropertySelectionNamespacesW[] = {'S','e','l','e','c','t','i','o','n','N','a','m','e','s','p','a','c','e','s',0};
63 static const WCHAR PropertyProhibitDTDW[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
64 static const WCHAR PropValueXPathW[] = {'X','P','a','t','h',0};
65 static const WCHAR PropValueXSLPatternW[] = {'X','S','L','P','a','t','t','e','r','n',0};
67 typedef struct _domdoc
69 xmlnode node;
70 const struct IXMLDOMDocument3Vtbl *lpVtbl;
71 const struct IPersistStreamInitVtbl *lpvtblIPersistStreamInit;
72 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
73 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
74 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
75 LONG ref;
76 VARIANT_BOOL async;
77 VARIANT_BOOL validating;
78 VARIANT_BOOL resolving;
79 VARIANT_BOOL preserving;
80 BOOL bUseXPath;
81 IXMLDOMSchemaCollection *schema;
82 bsc_t *bsc;
83 HRESULT error;
85 /* IPersistStream */
86 IStream *stream;
88 /* IObjectWithSite*/
89 IUnknown *site;
91 /* IObjectSafety */
92 DWORD safeopt;
93 } domdoc;
96 In native windows, the whole lifetime management of XMLDOMNodes is
97 managed automatically using reference counts. Wine emulates that by
98 maintaining a reference count to the document that is increased for
99 each IXMLDOMNode pointer passed out for this document. If all these
100 pointers are gone, the document is unreachable and gets freed, that
101 is, all nodes in the tree of the document get freed.
103 You are able to create nodes that are associated to a document (in
104 fact, in msxml's XMLDOM model, all nodes are associated to a document),
105 but not in the tree of that document, for example using the createFoo
106 functions from IXMLDOMDocument. These nodes do not get cleaned up
107 by libxml, so we have to do it ourselves.
109 To catch these nodes, a list of "orphan nodes" is introduced.
110 It contains pointers to all roots of node trees that are
111 associated with the document without being part of the document
112 tree. All nodes with parent==NULL (except for the document root nodes)
113 should be in the orphan node list of their document. All orphan nodes
114 get freed together with the document itself.
117 typedef struct _xmldoc_priv {
118 LONG refs;
119 struct list orphans;
120 } xmldoc_priv;
122 typedef struct _orphan_entry {
123 struct list entry;
124 xmlNode * node;
125 } orphan_entry;
127 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
129 return doc->_private;
132 static xmldoc_priv * create_priv(void)
134 xmldoc_priv *priv;
135 priv = heap_alloc( sizeof (*priv) );
137 if(priv)
139 priv->refs = 0;
140 list_init( &priv->orphans );
143 return priv;
146 /* links a "<?xml" node as a first child */
147 void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
149 assert(doc != NULL);
150 if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
153 /* unlinks a first "<?xml" child if it was created */
154 xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
156 xmlNodePtr node;
158 assert(doc != NULL);
160 if (doc->standalone != -1)
162 node = doc->children;
163 xmlUnlinkNode( node );
165 else
166 node = NULL;
168 return node;
171 static xmlDocPtr doparse( char *ptr, int len, const char *encoding )
173 xmlDocPtr doc;
175 #ifdef HAVE_XMLREADMEMORY
177 * use xmlReadMemory if possible so we can suppress
178 * writing errors to stderr
180 doc = xmlReadMemory( ptr, len, NULL, encoding,
181 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
182 #else
183 doc = xmlParseMemory( ptr, len );
184 #endif
186 /* create first child as a <?xml...?> */
187 if (doc && doc->standalone != -1)
189 xmlNodePtr node;
190 char buff[30];
191 xmlChar *xmlbuff = (xmlChar*)buff;
193 node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL );
195 /* version attribute can't be omitted */
196 sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0");
197 xmlNodeAddContent( node, xmlbuff );
199 if (doc->encoding)
201 sprintf(buff, " encoding=\"%s\"", doc->encoding);
202 xmlNodeAddContent( node, xmlbuff );
205 if (doc->standalone != -2)
207 sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes");
208 xmlNodeAddContent( node, xmlbuff );
211 xmldoc_link_xmldecl( doc, node );
214 return doc;
217 LONG xmldoc_add_ref(xmlDocPtr doc)
219 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
220 TRACE("(%p)->(%d)\n", doc, ref);
221 return ref;
224 LONG xmldoc_release(xmlDocPtr doc)
226 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
227 LONG ref = InterlockedDecrement(&priv->refs);
228 TRACE("(%p)->(%d)\n", doc, ref);
229 if(ref == 0)
231 orphan_entry *orphan, *orphan2;
232 TRACE("freeing docptr %p\n", doc);
234 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
236 xmlFreeNode( orphan->node );
237 heap_free( orphan );
239 heap_free(doc->_private);
241 xmlFreeDoc(doc);
244 return ref;
247 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
249 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
250 orphan_entry *entry;
252 entry = heap_alloc( sizeof (*entry) );
253 if(!entry)
254 return E_OUTOFMEMORY;
256 entry->node = node;
257 list_add_head( &priv->orphans, &entry->entry );
258 return S_OK;
261 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
263 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
264 orphan_entry *entry, *entry2;
266 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
268 if( entry->node == node )
270 list_remove( &entry->entry );
271 heap_free( entry );
272 return S_OK;
276 return S_FALSE;
279 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
281 if(node->node)
282 xmldoc_release(node->node->doc);
284 node->node = (xmlNodePtr) xml;
285 if(node->node)
286 xmldoc_add_ref(node->node->doc);
288 return S_OK;
291 static inline domdoc *impl_from_IXMLDOMDocument3( IXMLDOMDocument3 *iface )
293 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
296 static inline xmlDocPtr get_doc( domdoc *This )
298 return (xmlDocPtr)This->node.node;
301 static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
303 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStreamInit));
306 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
308 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
311 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
313 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
316 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
318 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
321 /************************************************************************
322 * domdoc implementation of IPersistStream.
324 static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
325 IPersistStreamInit *iface, REFIID riid, void **ppvObj)
327 domdoc *this = impl_from_IPersistStreamInit(iface);
328 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
331 static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
332 IPersistStreamInit *iface)
334 domdoc *this = impl_from_IPersistStreamInit(iface);
335 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
338 static ULONG WINAPI domdoc_IPersistStreamInit_Release(
339 IPersistStreamInit *iface)
341 domdoc *this = impl_from_IPersistStreamInit(iface);
342 return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
345 static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
346 IPersistStreamInit *iface, CLSID *classid)
348 TRACE("(%p,%p): stub!\n", iface, classid);
350 if(!classid)
351 return E_POINTER;
353 *classid = CLSID_DOMDocument2;
355 return S_OK;
358 static HRESULT WINAPI domdoc_IPersistStreamInit_IsDirty(
359 IPersistStreamInit *iface)
361 domdoc *This = impl_from_IPersistStreamInit(iface);
362 FIXME("(%p): stub!\n", This);
363 return S_FALSE;
366 static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
367 IPersistStreamInit *iface, LPSTREAM pStm)
369 domdoc *This = impl_from_IPersistStreamInit(iface);
370 HRESULT hr;
371 HGLOBAL hglobal;
372 DWORD read, written, len;
373 BYTE buf[4096];
374 char *ptr;
375 xmlDocPtr xmldoc = NULL;
377 TRACE("(%p)->(%p)\n", This, pStm);
379 if (!pStm)
380 return E_INVALIDARG;
382 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
383 if (FAILED(hr))
384 return hr;
388 IStream_Read(pStm, buf, sizeof(buf), &read);
389 hr = IStream_Write(This->stream, buf, read, &written);
390 } while(SUCCEEDED(hr) && written != 0 && read != 0);
392 if (FAILED(hr))
394 ERR("Failed to copy stream\n");
395 return hr;
398 hr = GetHGlobalFromStream(This->stream, &hglobal);
399 if (FAILED(hr))
400 return hr;
402 len = GlobalSize(hglobal);
403 ptr = GlobalLock(hglobal);
404 if (len != 0)
405 xmldoc = doparse(ptr, len, NULL);
406 GlobalUnlock(hglobal);
408 if (!xmldoc)
410 ERR("Failed to parse xml\n");
411 return E_FAIL;
414 xmldoc->_private = create_priv();
416 return attach_xmldoc( &This->node, xmldoc );
419 static HRESULT WINAPI domdoc_IPersistStreamInit_Save(
420 IPersistStreamInit *iface, IStream *stream, BOOL clr_dirty)
422 domdoc *This = impl_from_IPersistStreamInit(iface);
423 BSTR xmlString;
424 HRESULT hr;
426 TRACE("(%p)->(%p %d)\n", This, stream, clr_dirty);
428 hr = IXMLDOMDocument3_get_xml( (IXMLDOMDocument3*)&This->lpVtbl, &xmlString );
429 if(hr == S_OK)
431 DWORD len = SysStringLen(xmlString) * sizeof(WCHAR);
433 hr = IStream_Write( stream, xmlString, len, NULL );
434 SysFreeString(xmlString);
437 TRACE("ret 0x%08x\n", hr);
439 return hr;
442 static HRESULT WINAPI domdoc_IPersistStreamInit_GetSizeMax(
443 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
445 domdoc *This = impl_from_IPersistStreamInit(iface);
446 TRACE("(%p)->(%p): stub!\n", This, pcbSize);
447 return E_NOTIMPL;
450 static HRESULT WINAPI domdoc_IPersistStreamInit_InitNew(
451 IPersistStreamInit *iface)
453 domdoc *This = impl_from_IPersistStreamInit(iface);
454 TRACE("(%p)\n", This);
455 return S_OK;
458 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
460 domdoc_IPersistStreamInit_QueryInterface,
461 domdoc_IPersistStreamInit_AddRef,
462 domdoc_IPersistStreamInit_Release,
463 domdoc_IPersistStreamInit_GetClassID,
464 domdoc_IPersistStreamInit_IsDirty,
465 domdoc_IPersistStreamInit_Load,
466 domdoc_IPersistStreamInit_Save,
467 domdoc_IPersistStreamInit_GetSizeMax,
468 domdoc_IPersistStreamInit_InitNew
471 /* ISupportErrorInfo interface */
472 static HRESULT WINAPI support_error_QueryInterface(
473 ISupportErrorInfo *iface,
474 REFIID riid, void** ppvObj )
476 domdoc *This = impl_from_ISupportErrorInfo(iface);
477 return IXMLDOMDocument3_QueryInterface((IXMLDOMDocument3 *)This, riid, ppvObj);
480 static ULONG WINAPI support_error_AddRef(
481 ISupportErrorInfo *iface )
483 domdoc *This = impl_from_ISupportErrorInfo(iface);
484 return IXMLDOMDocument3_AddRef((IXMLDOMDocument3 *)This);
487 static ULONG WINAPI support_error_Release(
488 ISupportErrorInfo *iface )
490 domdoc *This = impl_from_ISupportErrorInfo(iface);
491 return IXMLDOMDocument3_Release((IXMLDOMDocument3 *)This);
494 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
495 ISupportErrorInfo *iface,
496 REFIID riid )
498 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
499 return S_FALSE;
502 static const struct ISupportErrorInfoVtbl support_error_vtbl =
504 support_error_QueryInterface,
505 support_error_AddRef,
506 support_error_Release,
507 support_error_InterfaceSupportsErrorInfo
510 /* IXMLDOMDocument2 interface */
511 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument3 *iface, REFIID riid, void** ppvObject )
513 domdoc *This = impl_from_IXMLDOMDocument3( iface );
515 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
517 *ppvObject = NULL;
519 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
520 IsEqualGUID( riid, &IID_IDispatch ) ||
521 IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
522 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
523 IsEqualGUID( riid, &IID_IXMLDOMDocument2 )||
524 IsEqualGUID( riid, &IID_IXMLDOMDocument3 ))
526 *ppvObject = iface;
528 else if (IsEqualGUID(&IID_IPersistStream, riid) ||
529 IsEqualGUID(&IID_IPersistStreamInit, riid))
531 *ppvObject = &(This->lpvtblIPersistStreamInit);
533 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
535 *ppvObject = &(This->lpvtblIObjectWithSite);
537 else if (IsEqualGUID(&IID_IObjectSafety, riid))
539 *ppvObject = &(This->lpvtblIObjectSafety);
541 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
543 *ppvObject = &This->lpvtblISupportErrorInfo;
545 else if(node_query_interface(&This->node, riid, ppvObject))
547 return *ppvObject ? S_OK : E_NOINTERFACE;
549 else if(IsEqualGUID(&IID_IRunnableObject, riid))
551 TRACE("IID_IRunnableObject not supported returning NULL\n");
552 return E_NOINTERFACE;
554 else
556 FIXME("interface %s not implemented\n", debugstr_guid(riid));
557 return E_NOINTERFACE;
560 IUnknown_AddRef((IUnknown*)*ppvObject);
562 return S_OK;
566 static ULONG WINAPI domdoc_AddRef(
567 IXMLDOMDocument3 *iface )
569 domdoc *This = impl_from_IXMLDOMDocument3( iface );
570 TRACE("%p\n", This );
571 return InterlockedIncrement( &This->ref );
575 static ULONG WINAPI domdoc_Release(
576 IXMLDOMDocument3 *iface )
578 domdoc *This = impl_from_IXMLDOMDocument3( iface );
579 LONG ref;
581 TRACE("%p\n", This );
583 ref = InterlockedDecrement( &This->ref );
584 if ( ref == 0 )
586 if(This->bsc)
587 detach_bsc(This->bsc);
589 if (This->site)
590 IUnknown_Release( This->site );
591 destroy_xmlnode(&This->node);
592 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
593 if (This->stream) IStream_Release(This->stream);
594 HeapFree( GetProcessHeap(), 0, This );
597 return ref;
600 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument3 *iface, UINT* pctinfo )
602 domdoc *This = impl_from_IXMLDOMDocument3( iface );
604 TRACE("(%p)->(%p)\n", This, pctinfo);
606 *pctinfo = 1;
608 return S_OK;
611 static HRESULT WINAPI domdoc_GetTypeInfo(
612 IXMLDOMDocument3 *iface,
613 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
615 domdoc *This = impl_from_IXMLDOMDocument3( iface );
616 HRESULT hr;
618 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
620 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
622 return hr;
625 static HRESULT WINAPI domdoc_GetIDsOfNames(
626 IXMLDOMDocument3 *iface,
627 REFIID riid,
628 LPOLESTR* rgszNames,
629 UINT cNames,
630 LCID lcid,
631 DISPID* rgDispId)
633 domdoc *This = impl_from_IXMLDOMDocument3( iface );
634 ITypeInfo *typeinfo;
635 HRESULT hr;
637 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
638 lcid, rgDispId);
640 if(!rgszNames || cNames == 0 || !rgDispId)
641 return E_INVALIDARG;
643 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
644 if(SUCCEEDED(hr))
646 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
647 ITypeInfo_Release(typeinfo);
650 return hr;
654 static HRESULT WINAPI domdoc_Invoke(
655 IXMLDOMDocument3 *iface,
656 DISPID dispIdMember,
657 REFIID riid,
658 LCID lcid,
659 WORD wFlags,
660 DISPPARAMS* pDispParams,
661 VARIANT* pVarResult,
662 EXCEPINFO* pExcepInfo,
663 UINT* puArgErr)
665 domdoc *This = impl_from_IXMLDOMDocument3( iface );
666 ITypeInfo *typeinfo;
667 HRESULT hr;
669 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
670 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
672 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
673 if(SUCCEEDED(hr))
675 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
676 pVarResult, pExcepInfo, puArgErr);
677 ITypeInfo_Release(typeinfo);
680 return hr;
684 static HRESULT WINAPI domdoc_get_nodeName(
685 IXMLDOMDocument3 *iface,
686 BSTR* name )
688 domdoc *This = impl_from_IXMLDOMDocument3( iface );
690 static const WCHAR documentW[] = {'#','d','o','c','u','m','e','n','t',0};
692 TRACE("(%p)->(%p)\n", This, name);
694 return return_bstr(documentW, name);
698 static HRESULT WINAPI domdoc_get_nodeValue(
699 IXMLDOMDocument3 *iface,
700 VARIANT* value )
702 domdoc *This = impl_from_IXMLDOMDocument3( iface );
704 TRACE("(%p)->(%p)\n", This, value);
706 if(!value)
707 return E_INVALIDARG;
709 V_VT(value) = VT_NULL;
710 V_BSTR(value) = NULL; /* tests show that we should do this */
711 return S_FALSE;
715 static HRESULT WINAPI domdoc_put_nodeValue(
716 IXMLDOMDocument3 *iface,
717 VARIANT value)
719 domdoc *This = impl_from_IXMLDOMDocument3( iface );
720 FIXME("(%p)->(v%d)\n", This, V_VT(&value));
721 return E_FAIL;
725 static HRESULT WINAPI domdoc_get_nodeType(
726 IXMLDOMDocument3 *iface,
727 DOMNodeType* type )
729 domdoc *This = impl_from_IXMLDOMDocument3( iface );
731 TRACE("(%p)->(%p)\n", This, type);
733 *type = NODE_DOCUMENT;
734 return S_OK;
738 static HRESULT WINAPI domdoc_get_parentNode(
739 IXMLDOMDocument3 *iface,
740 IXMLDOMNode** parent )
742 domdoc *This = impl_from_IXMLDOMDocument3( iface );
744 TRACE("(%p)->(%p)\n", This, parent);
746 return node_get_parent(&This->node, parent);
750 static HRESULT WINAPI domdoc_get_childNodes(
751 IXMLDOMDocument3 *iface,
752 IXMLDOMNodeList** childList )
754 domdoc *This = impl_from_IXMLDOMDocument3( iface );
756 TRACE("(%p)->(%p)\n", This, childList);
758 return node_get_child_nodes(&This->node, childList);
762 static HRESULT WINAPI domdoc_get_firstChild(
763 IXMLDOMDocument3 *iface,
764 IXMLDOMNode** firstChild )
766 domdoc *This = impl_from_IXMLDOMDocument3( iface );
768 TRACE("(%p)->(%p)\n", This, firstChild);
770 return node_get_first_child(&This->node, firstChild);
774 static HRESULT WINAPI domdoc_get_lastChild(
775 IXMLDOMDocument3 *iface,
776 IXMLDOMNode** lastChild )
778 domdoc *This = impl_from_IXMLDOMDocument3( iface );
780 TRACE("(%p)->(%p)\n", This, lastChild);
782 return node_get_last_child(&This->node, lastChild);
786 static HRESULT WINAPI domdoc_get_previousSibling(
787 IXMLDOMDocument3 *iface,
788 IXMLDOMNode** previousSibling )
790 domdoc *This = impl_from_IXMLDOMDocument3( iface );
792 TRACE("(%p)->(%p)\n", This, previousSibling);
794 return return_null_node(previousSibling);
798 static HRESULT WINAPI domdoc_get_nextSibling(
799 IXMLDOMDocument3 *iface,
800 IXMLDOMNode** nextSibling )
802 domdoc *This = impl_from_IXMLDOMDocument3( iface );
804 TRACE("(%p)->(%p)\n", This, nextSibling);
806 return return_null_node(nextSibling);
810 static HRESULT WINAPI domdoc_get_attributes(
811 IXMLDOMDocument3 *iface,
812 IXMLDOMNamedNodeMap** attributeMap )
814 domdoc *This = impl_from_IXMLDOMDocument3( iface );
816 TRACE("(%p)->(%p)\n", This, attributeMap);
818 return return_null_ptr((void**)attributeMap);
822 static HRESULT WINAPI domdoc_insertBefore(
823 IXMLDOMDocument3 *iface,
824 IXMLDOMNode* newChild,
825 VARIANT refChild,
826 IXMLDOMNode** outNewChild )
828 domdoc *This = impl_from_IXMLDOMDocument3( iface );
830 TRACE("(%p)->(%p x%d %p)\n", This, newChild, V_VT(&refChild), outNewChild);
832 return node_insert_before(&This->node, newChild, &refChild, outNewChild);
836 static HRESULT WINAPI domdoc_replaceChild(
837 IXMLDOMDocument3 *iface,
838 IXMLDOMNode* newChild,
839 IXMLDOMNode* oldChild,
840 IXMLDOMNode** outOldChild)
842 domdoc *This = impl_from_IXMLDOMDocument3( iface );
843 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
847 static HRESULT WINAPI domdoc_removeChild(
848 IXMLDOMDocument3 *iface,
849 IXMLDOMNode* childNode,
850 IXMLDOMNode** oldChild)
852 domdoc *This = impl_from_IXMLDOMDocument3( iface );
853 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
857 static HRESULT WINAPI domdoc_appendChild(
858 IXMLDOMDocument3 *iface,
859 IXMLDOMNode* newChild,
860 IXMLDOMNode** outNewChild)
862 domdoc *This = impl_from_IXMLDOMDocument3( iface );
863 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
867 static HRESULT WINAPI domdoc_hasChildNodes(
868 IXMLDOMDocument3 *iface,
869 VARIANT_BOOL* hasChild)
871 domdoc *This = impl_from_IXMLDOMDocument3( iface );
872 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
876 static HRESULT WINAPI domdoc_get_ownerDocument(
877 IXMLDOMDocument3 *iface,
878 IXMLDOMDocument** DOMDocument)
880 domdoc *This = impl_from_IXMLDOMDocument3( iface );
881 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
885 static HRESULT WINAPI domdoc_cloneNode(
886 IXMLDOMDocument3 *iface,
887 VARIANT_BOOL deep,
888 IXMLDOMNode** cloneRoot)
890 domdoc *This = impl_from_IXMLDOMDocument3( iface );
891 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
895 static HRESULT WINAPI domdoc_get_nodeTypeString(
896 IXMLDOMDocument3 *iface,
897 BSTR* nodeType )
899 domdoc *This = impl_from_IXMLDOMDocument3( iface );
900 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
904 static HRESULT WINAPI domdoc_get_text(
905 IXMLDOMDocument3 *iface,
906 BSTR* text )
908 domdoc *This = impl_from_IXMLDOMDocument3( iface );
909 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
913 static HRESULT WINAPI domdoc_put_text(
914 IXMLDOMDocument3 *iface,
915 BSTR text )
917 domdoc *This = impl_from_IXMLDOMDocument3( iface );
918 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
922 static HRESULT WINAPI domdoc_get_specified(
923 IXMLDOMDocument3 *iface,
924 VARIANT_BOOL* isSpecified )
926 domdoc *This = impl_from_IXMLDOMDocument3( iface );
927 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
931 static HRESULT WINAPI domdoc_get_definition(
932 IXMLDOMDocument3 *iface,
933 IXMLDOMNode** definitionNode )
935 domdoc *This = impl_from_IXMLDOMDocument3( iface );
936 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
940 static HRESULT WINAPI domdoc_get_nodeTypedValue(
941 IXMLDOMDocument3 *iface,
942 VARIANT* typedValue )
944 domdoc *This = impl_from_IXMLDOMDocument3( iface );
945 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
948 static HRESULT WINAPI domdoc_put_nodeTypedValue(
949 IXMLDOMDocument3 *iface,
950 VARIANT typedValue )
952 domdoc *This = impl_from_IXMLDOMDocument3( iface );
953 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
957 static HRESULT WINAPI domdoc_get_dataType(
958 IXMLDOMDocument3 *iface,
959 VARIANT* dataTypeName )
961 domdoc *This = impl_from_IXMLDOMDocument3( iface );
962 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
966 static HRESULT WINAPI domdoc_put_dataType(
967 IXMLDOMDocument3 *iface,
968 BSTR dataTypeName )
970 domdoc *This = impl_from_IXMLDOMDocument3( iface );
971 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
975 static HRESULT WINAPI domdoc_get_xml(
976 IXMLDOMDocument3 *iface,
977 BSTR* xmlString )
979 domdoc *This = impl_from_IXMLDOMDocument3( iface );
980 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
984 static HRESULT WINAPI domdoc_transformNode(
985 IXMLDOMDocument3 *iface,
986 IXMLDOMNode* styleSheet,
987 BSTR* xmlString )
989 domdoc *This = impl_from_IXMLDOMDocument3( iface );
990 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
994 static HRESULT WINAPI domdoc_selectNodes(
995 IXMLDOMDocument3 *iface,
996 BSTR queryString,
997 IXMLDOMNodeList** resultList )
999 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1000 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
1004 static HRESULT WINAPI domdoc_selectSingleNode(
1005 IXMLDOMDocument3 *iface,
1006 BSTR queryString,
1007 IXMLDOMNode** resultNode )
1009 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1010 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
1014 static HRESULT WINAPI domdoc_get_parsed(
1015 IXMLDOMDocument3 *iface,
1016 VARIANT_BOOL* isParsed )
1018 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1019 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
1023 static HRESULT WINAPI domdoc_get_namespaceURI(
1024 IXMLDOMDocument3 *iface,
1025 BSTR* namespaceURI )
1027 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1028 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
1032 static HRESULT WINAPI domdoc_get_prefix(
1033 IXMLDOMDocument3 *iface,
1034 BSTR* prefixString )
1036 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1037 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
1041 static HRESULT WINAPI domdoc_get_baseName(
1042 IXMLDOMDocument3 *iface,
1043 BSTR* nameString )
1045 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1046 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
1050 static HRESULT WINAPI domdoc_transformNodeToObject(
1051 IXMLDOMDocument3 *iface,
1052 IXMLDOMNode* stylesheet,
1053 VARIANT outputObject)
1055 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1056 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
1060 static HRESULT WINAPI domdoc_get_doctype(
1061 IXMLDOMDocument3 *iface,
1062 IXMLDOMDocumentType** documentType )
1064 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1065 FIXME("(%p)\n", This);
1066 return E_NOTIMPL;
1070 static HRESULT WINAPI domdoc_get_implementation(
1071 IXMLDOMDocument3 *iface,
1072 IXMLDOMImplementation** impl )
1074 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1076 TRACE("(%p)->(%p)\n", This, impl);
1078 if(!impl)
1079 return E_INVALIDARG;
1081 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1083 return S_OK;
1086 static HRESULT WINAPI domdoc_get_documentElement(
1087 IXMLDOMDocument3 *iface,
1088 IXMLDOMElement** DOMElement )
1090 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1091 IXMLDOMNode *element_node;
1092 xmlNodePtr root;
1093 HRESULT hr;
1095 TRACE("(%p)->(%p)\n", This, DOMElement);
1097 if(!DOMElement)
1098 return E_INVALIDARG;
1100 *DOMElement = NULL;
1102 root = xmlDocGetRootElement( get_doc(This) );
1103 if ( !root )
1104 return S_FALSE;
1106 element_node = create_node( root );
1107 if(!element_node) return S_FALSE;
1109 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (void**)DOMElement);
1110 IXMLDOMNode_Release(element_node);
1112 return hr;
1116 static HRESULT WINAPI domdoc_put_documentElement(
1117 IXMLDOMDocument3 *iface,
1118 IXMLDOMElement* DOMElement )
1120 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1121 IXMLDOMNode *elementNode;
1122 xmlNodePtr oldRoot;
1123 xmlnode *xmlNode;
1124 HRESULT hr;
1126 TRACE("(%p)->(%p)\n", This, DOMElement);
1128 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1129 if(FAILED(hr))
1130 return hr;
1132 xmlNode = get_node_obj( elementNode );
1133 if(!xmlNode) {
1134 FIXME("elementNode is not our object\n");
1135 return E_FAIL;
1138 if(!xmlNode->node->parent)
1139 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1140 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1142 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1143 IXMLDOMNode_Release( elementNode );
1145 if(oldRoot)
1146 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1148 return S_OK;
1152 static HRESULT WINAPI domdoc_createElement(
1153 IXMLDOMDocument3 *iface,
1154 BSTR tagname,
1155 IXMLDOMElement** element )
1157 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1158 IXMLDOMNode *node;
1159 VARIANT type;
1160 HRESULT hr;
1162 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1164 if (!element || !tagname) return E_INVALIDARG;
1166 V_VT(&type) = VT_I1;
1167 V_I1(&type) = NODE_ELEMENT;
1169 hr = IXMLDOMDocument3_createNode(iface, type, tagname, NULL, &node);
1170 if (hr == S_OK)
1172 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1173 IXMLDOMNode_Release(node);
1176 return hr;
1180 static HRESULT WINAPI domdoc_createDocumentFragment(
1181 IXMLDOMDocument3 *iface,
1182 IXMLDOMDocumentFragment** frag )
1184 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1185 IXMLDOMNode *node;
1186 VARIANT type;
1187 HRESULT hr;
1189 TRACE("(%p)->(%p)\n", This, frag);
1191 if (!frag) return E_INVALIDARG;
1193 *frag = NULL;
1195 V_VT(&type) = VT_I1;
1196 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1198 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1199 if (hr == S_OK)
1201 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1202 IXMLDOMNode_Release(node);
1205 return hr;
1209 static HRESULT WINAPI domdoc_createTextNode(
1210 IXMLDOMDocument3 *iface,
1211 BSTR data,
1212 IXMLDOMText** text )
1214 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1215 IXMLDOMNode *node;
1216 VARIANT type;
1217 HRESULT hr;
1219 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1221 if (!text) return E_INVALIDARG;
1223 *text = NULL;
1225 V_VT(&type) = VT_I1;
1226 V_I1(&type) = NODE_TEXT;
1228 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1229 if (hr == S_OK)
1231 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1232 IXMLDOMNode_Release(node);
1233 hr = IXMLDOMText_put_data(*text, data);
1236 return hr;
1240 static HRESULT WINAPI domdoc_createComment(
1241 IXMLDOMDocument3 *iface,
1242 BSTR data,
1243 IXMLDOMComment** comment )
1245 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1246 VARIANT type;
1247 HRESULT hr;
1248 IXMLDOMNode *node;
1250 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1252 if (!comment) return E_INVALIDARG;
1254 *comment = NULL;
1256 V_VT(&type) = VT_I1;
1257 V_I1(&type) = NODE_COMMENT;
1259 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1260 if (hr == S_OK)
1262 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1263 IXMLDOMNode_Release(node);
1264 hr = IXMLDOMComment_put_data(*comment, data);
1267 return hr;
1271 static HRESULT WINAPI domdoc_createCDATASection(
1272 IXMLDOMDocument3 *iface,
1273 BSTR data,
1274 IXMLDOMCDATASection** cdata )
1276 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1277 IXMLDOMNode *node;
1278 VARIANT type;
1279 HRESULT hr;
1281 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1283 if (!cdata) return E_INVALIDARG;
1285 *cdata = NULL;
1287 V_VT(&type) = VT_I1;
1288 V_I1(&type) = NODE_CDATA_SECTION;
1290 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1291 if (hr == S_OK)
1293 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1294 IXMLDOMNode_Release(node);
1295 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1298 return hr;
1302 static HRESULT WINAPI domdoc_createProcessingInstruction(
1303 IXMLDOMDocument3 *iface,
1304 BSTR target,
1305 BSTR data,
1306 IXMLDOMProcessingInstruction** pi )
1308 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1309 IXMLDOMNode *node;
1310 VARIANT type;
1311 HRESULT hr;
1313 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1315 if (!pi) return E_INVALIDARG;
1317 *pi = NULL;
1319 V_VT(&type) = VT_I1;
1320 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1322 hr = IXMLDOMDocument3_createNode(iface, type, target, NULL, &node);
1323 if (hr == S_OK)
1325 VARIANT v_data;
1326 xmlnode *node_obj;
1328 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1329 node_obj = get_node_obj(node);
1330 V_VT(&v_data) = VT_BSTR;
1331 V_BSTR(&v_data) = data;
1333 hr = node_put_value(node_obj, &v_data);
1335 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1336 IXMLDOMNode_Release(node);
1339 return hr;
1343 static HRESULT WINAPI domdoc_createAttribute(
1344 IXMLDOMDocument3 *iface,
1345 BSTR name,
1346 IXMLDOMAttribute** attribute )
1348 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1349 IXMLDOMNode *node;
1350 VARIANT type;
1351 HRESULT hr;
1353 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1355 if (!attribute || !name) return E_INVALIDARG;
1357 V_VT(&type) = VT_I1;
1358 V_I1(&type) = NODE_ATTRIBUTE;
1360 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1361 if (hr == S_OK)
1363 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1364 IXMLDOMNode_Release(node);
1367 return hr;
1371 static HRESULT WINAPI domdoc_createEntityReference(
1372 IXMLDOMDocument3 *iface,
1373 BSTR name,
1374 IXMLDOMEntityReference** entityref )
1376 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1377 IXMLDOMNode *node;
1378 VARIANT type;
1379 HRESULT hr;
1381 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1383 if (!entityref) return E_INVALIDARG;
1385 *entityref = NULL;
1387 V_VT(&type) = VT_I1;
1388 V_I1(&type) = NODE_ENTITY_REFERENCE;
1390 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1391 if (hr == S_OK)
1393 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1394 IXMLDOMNode_Release(node);
1397 return hr;
1401 static HRESULT WINAPI domdoc_getElementsByTagName(
1402 IXMLDOMDocument3 *iface,
1403 BSTR tagName,
1404 IXMLDOMNodeList** resultList )
1406 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1407 HRESULT hr;
1409 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1411 if (!tagName || !resultList) return E_INVALIDARG;
1413 if (tagName[0] == '*' && tagName[1] == 0)
1415 static const WCHAR formatallW[] = {'/','/','*',0};
1416 hr = queryresult_create((xmlNodePtr)get_doc(This), formatallW, resultList);
1418 else
1420 static const WCHAR xpathformat[] =
1421 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
1422 static const WCHAR closeW[] = { '\'',']',0 };
1424 LPWSTR pattern;
1425 WCHAR *ptr;
1426 INT length;
1428 length = lstrlenW(tagName);
1430 /* without two WCHARs from format specifier */
1431 ptr = pattern = heap_alloc(sizeof(xpathformat) + length*sizeof(WCHAR) + sizeof(closeW));
1433 memcpy(ptr, xpathformat, sizeof(xpathformat));
1434 ptr += sizeof(xpathformat)/sizeof(WCHAR);
1435 memcpy(ptr, tagName, length*sizeof(WCHAR));
1436 ptr += length;
1437 memcpy(ptr, closeW, sizeof(closeW));
1439 hr = queryresult_create((xmlNodePtr)get_doc(This), pattern, resultList);
1440 heap_free(pattern);
1443 return hr;
1446 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1448 VARIANT tmp;
1449 HRESULT hr;
1451 VariantInit(&tmp);
1452 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1453 if(FAILED(hr))
1454 return E_INVALIDARG;
1456 *type = V_I4(&tmp);
1458 return S_OK;
1461 static HRESULT WINAPI domdoc_createNode(
1462 IXMLDOMDocument3 *iface,
1463 VARIANT Type,
1464 BSTR name,
1465 BSTR namespaceURI,
1466 IXMLDOMNode** node )
1468 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1469 DOMNodeType node_type;
1470 xmlNodePtr xmlnode;
1471 xmlChar *xml_name, *href;
1472 HRESULT hr;
1474 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1476 if(!node) return E_INVALIDARG;
1478 hr = get_node_type(Type, &node_type);
1479 if(FAILED(hr)) return hr;
1481 if(namespaceURI && namespaceURI[0] && node_type != NODE_ELEMENT)
1482 FIXME("nodes with namespaces currently not supported.\n");
1484 TRACE("node_type %d\n", node_type);
1486 /* exit earlier for types that need name */
1487 switch(node_type)
1489 case NODE_ELEMENT:
1490 case NODE_ATTRIBUTE:
1491 case NODE_ENTITY_REFERENCE:
1492 case NODE_PROCESSING_INSTRUCTION:
1493 if (!name || *name == 0) return E_FAIL;
1494 default:
1495 break;
1498 xml_name = xmlChar_from_wchar(name);
1499 /* prevent empty href to be allocated */
1500 href = namespaceURI ? xmlChar_from_wchar(namespaceURI) : NULL;
1502 switch(node_type)
1504 case NODE_ELEMENT:
1506 xmlChar *local, *prefix;
1508 local = xmlSplitQName2(xml_name, &prefix);
1510 xmlnode = xmlNewDocNode(get_doc(This), NULL, local ? local : xml_name, NULL);
1512 /* allow to create default namespace xmlns= */
1513 if (local || (href && *href))
1515 xmlNsPtr ns = xmlNewNs(xmlnode, href, prefix);
1516 xmlSetNs(xmlnode, ns);
1519 xmlFree(local);
1520 xmlFree(prefix);
1522 break;
1524 case NODE_ATTRIBUTE:
1525 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1526 break;
1527 case NODE_TEXT:
1528 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1529 break;
1530 case NODE_CDATA_SECTION:
1531 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1532 break;
1533 case NODE_ENTITY_REFERENCE:
1534 xmlnode = xmlNewReference(get_doc(This), xml_name);
1535 break;
1536 case NODE_PROCESSING_INSTRUCTION:
1537 #ifdef HAVE_XMLNEWDOCPI
1538 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1539 #else
1540 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1541 xmlnode = NULL;
1542 #endif
1543 break;
1544 case NODE_COMMENT:
1545 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1546 break;
1547 case NODE_DOCUMENT_FRAGMENT:
1548 xmlnode = xmlNewDocFragment(get_doc(This));
1549 break;
1550 /* unsupported types */
1551 case NODE_DOCUMENT:
1552 case NODE_DOCUMENT_TYPE:
1553 case NODE_ENTITY:
1554 case NODE_NOTATION:
1555 heap_free(xml_name);
1556 return E_INVALIDARG;
1557 default:
1558 FIXME("unhandled node type %d\n", node_type);
1559 xmlnode = NULL;
1560 break;
1563 *node = create_node(xmlnode);
1564 heap_free(xml_name);
1565 heap_free(href);
1567 if(*node)
1569 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1570 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1571 return S_OK;
1574 return E_FAIL;
1577 static HRESULT WINAPI domdoc_nodeFromID(
1578 IXMLDOMDocument3 *iface,
1579 BSTR idString,
1580 IXMLDOMNode** node )
1582 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1583 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1584 return E_NOTIMPL;
1587 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1589 domdoc *This = obj;
1590 xmlDocPtr xmldoc;
1592 xmldoc = doparse( ptr, len, NULL );
1593 if(xmldoc) {
1594 xmldoc->_private = create_priv();
1595 return attach_xmldoc(&This->node, xmldoc);
1598 return S_OK;
1601 static HRESULT doread( domdoc *This, LPWSTR filename )
1603 bsc_t *bsc;
1604 HRESULT hr;
1606 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1607 if(FAILED(hr))
1608 return hr;
1610 if(This->bsc)
1611 detach_bsc(This->bsc);
1613 This->bsc = bsc;
1614 return S_OK;
1617 static HRESULT WINAPI domdoc_load(
1618 IXMLDOMDocument3 *iface,
1619 VARIANT xmlSource,
1620 VARIANT_BOOL* isSuccessful )
1622 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1623 LPWSTR filename = NULL;
1624 HRESULT hr = S_FALSE;
1625 IXMLDOMDocument3 *pNewDoc = NULL;
1626 IStream *pStream = NULL;
1627 xmlDocPtr xmldoc;
1629 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1631 *isSuccessful = VARIANT_FALSE;
1633 assert( &This->node );
1635 switch( V_VT(&xmlSource) )
1637 case VT_BSTR:
1638 filename = V_BSTR(&xmlSource);
1639 break;
1640 case VT_UNKNOWN:
1641 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument3, (void**)&pNewDoc);
1642 if(hr == S_OK)
1644 if(pNewDoc)
1646 domdoc *newDoc = impl_from_IXMLDOMDocument3( pNewDoc );
1647 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1648 hr = attach_xmldoc(&This->node, xmldoc);
1650 if(SUCCEEDED(hr))
1651 *isSuccessful = VARIANT_TRUE;
1653 return hr;
1656 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1657 if(hr == S_OK)
1659 IPersistStream *pDocStream;
1660 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1661 if(hr == S_OK)
1663 hr = IPersistStream_Load(pDocStream, pStream);
1664 IStream_Release(pStream);
1665 if(hr == S_OK)
1667 *isSuccessful = VARIANT_TRUE;
1669 TRACE("Using IStream to load Document\n");
1670 return S_OK;
1672 else
1674 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1677 else
1679 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1682 else
1684 /* ISequentialStream */
1685 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1687 break;
1688 default:
1689 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1692 TRACE("filename (%s)\n", debugstr_w(filename));
1694 if ( filename )
1696 hr = doread( This, filename );
1698 if ( FAILED(hr) )
1699 This->error = E_FAIL;
1700 else
1702 hr = This->error = S_OK;
1703 *isSuccessful = VARIANT_TRUE;
1707 if(!filename || FAILED(hr)) {
1708 xmldoc = xmlNewDoc(NULL);
1709 xmldoc->_private = create_priv();
1710 hr = attach_xmldoc(&This->node, xmldoc);
1711 if(SUCCEEDED(hr))
1712 hr = S_FALSE;
1715 TRACE("ret (%d)\n", hr);
1717 return hr;
1721 static HRESULT WINAPI domdoc_get_readyState(
1722 IXMLDOMDocument3 *iface,
1723 LONG *value )
1725 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1726 FIXME("(%p)->(%p)\n", This, value);
1727 return E_NOTIMPL;
1731 static HRESULT WINAPI domdoc_get_parseError(
1732 IXMLDOMDocument3 *iface,
1733 IXMLDOMParseError** errorObj )
1735 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1736 static const WCHAR err[] = {'e','r','r','o','r',0};
1737 BSTR error_string = NULL;
1739 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1741 if(This->error)
1742 error_string = SysAllocString(err);
1744 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1745 if(!*errorObj) return E_OUTOFMEMORY;
1746 return S_OK;
1750 static HRESULT WINAPI domdoc_get_url(
1751 IXMLDOMDocument3 *iface,
1752 BSTR* urlString )
1754 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1755 FIXME("(%p)->(%p)\n", This, urlString);
1756 return E_NOTIMPL;
1760 static HRESULT WINAPI domdoc_get_async(
1761 IXMLDOMDocument3 *iface,
1762 VARIANT_BOOL* isAsync )
1764 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1766 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1767 *isAsync = This->async;
1768 return S_OK;
1772 static HRESULT WINAPI domdoc_put_async(
1773 IXMLDOMDocument3 *iface,
1774 VARIANT_BOOL isAsync )
1776 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1778 TRACE("(%p)->(%d)\n", This, isAsync);
1779 This->async = isAsync;
1780 return S_OK;
1784 static HRESULT WINAPI domdoc_abort(
1785 IXMLDOMDocument3 *iface )
1787 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1788 FIXME("%p\n", This);
1789 return E_NOTIMPL;
1793 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1795 UINT len;
1796 LPSTR str;
1798 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
1799 str = heap_alloc( len );
1800 if ( !str )
1801 return FALSE;
1802 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
1803 *plen = len;
1804 *pstr = str;
1805 return TRUE;
1808 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
1809 static HRESULT WINAPI domdoc_loadXML(
1810 IXMLDOMDocument3 *iface,
1811 BSTR bstrXML,
1812 VARIANT_BOOL* isSuccessful )
1814 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1815 xmlDocPtr xmldoc = NULL;
1816 HRESULT hr = S_FALSE, hr2;
1817 char *str;
1818 int len;
1820 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
1822 assert ( &This->node );
1824 if ( isSuccessful )
1826 *isSuccessful = VARIANT_FALSE;
1828 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1830 xmldoc = doparse( str, len, "UTF-8" );
1831 heap_free( str );
1832 if ( !xmldoc )
1833 This->error = E_FAIL;
1834 else
1836 hr = This->error = S_OK;
1837 *isSuccessful = VARIANT_TRUE;
1838 TRACE("parsed document %p\n", xmldoc);
1842 if(!xmldoc)
1843 xmldoc = xmlNewDoc(NULL);
1845 xmldoc->_private = create_priv();
1846 hr2 = attach_xmldoc( &This->node, xmldoc );
1847 if( FAILED(hr2) )
1848 hr = hr2;
1850 return hr;
1853 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1854 int len)
1856 DWORD written = -1;
1858 if(!WriteFile(ctx, buffer, len, &written, NULL))
1860 WARN("write error\n");
1861 return -1;
1863 else
1864 return written;
1867 static int XMLCALL domdoc_save_closecallback(void *ctx)
1869 return CloseHandle(ctx) ? 0 : -1;
1872 static HRESULT WINAPI domdoc_save(
1873 IXMLDOMDocument3 *iface,
1874 VARIANT destination )
1876 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1877 HANDLE handle;
1878 xmlSaveCtxtPtr ctx;
1879 xmlNodePtr xmldecl;
1880 HRESULT ret = S_OK;
1882 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1883 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1885 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1887 FIXME("Unhandled vt %d\n", V_VT(&destination));
1888 return S_FALSE;
1891 if(V_VT(&destination) == VT_UNKNOWN)
1893 IUnknown *pUnk = V_UNKNOWN(&destination);
1894 IXMLDOMDocument2 *pDocument;
1896 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&pDocument);
1897 if(ret == S_OK)
1899 VARIANT_BOOL success;
1900 BSTR xml;
1902 ret = IXMLDOMDocument3_get_xml(iface, &xml);
1903 if(ret == S_OK)
1905 ret = IXMLDOMDocument3_loadXML(pDocument, xml, &success);
1906 SysFreeString(xml);
1909 IXMLDOMDocument3_Release(pDocument);
1912 TRACE("ret %d\n", ret);
1914 return ret;
1917 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1918 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1919 if( handle == INVALID_HANDLE_VALUE )
1921 WARN("failed to create file\n");
1922 return S_FALSE;
1925 /* disable top XML declaration */
1926 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1927 handle, NULL, XML_SAVE_NO_DECL);
1928 if (!ctx)
1930 CloseHandle(handle);
1931 return S_FALSE;
1934 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
1935 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1936 xmldoc_link_xmldecl(get_doc(This), xmldecl);
1938 /* will close file through close callback */
1939 xmlSaveClose(ctx);
1941 return ret;
1944 static HRESULT WINAPI domdoc_get_validateOnParse(
1945 IXMLDOMDocument3 *iface,
1946 VARIANT_BOOL* isValidating )
1948 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1949 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
1950 *isValidating = This->validating;
1951 return S_OK;
1955 static HRESULT WINAPI domdoc_put_validateOnParse(
1956 IXMLDOMDocument3 *iface,
1957 VARIANT_BOOL isValidating )
1959 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1960 TRACE("(%p)->(%d)\n", This, isValidating);
1961 This->validating = isValidating;
1962 return S_OK;
1966 static HRESULT WINAPI domdoc_get_resolveExternals(
1967 IXMLDOMDocument3 *iface,
1968 VARIANT_BOOL* isResolving )
1970 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1971 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
1972 *isResolving = This->resolving;
1973 return S_OK;
1977 static HRESULT WINAPI domdoc_put_resolveExternals(
1978 IXMLDOMDocument3 *iface,
1979 VARIANT_BOOL isResolving )
1981 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1982 TRACE("(%p)->(%d)\n", This, isResolving);
1983 This->resolving = isResolving;
1984 return S_OK;
1988 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1989 IXMLDOMDocument3 *iface,
1990 VARIANT_BOOL* isPreserving )
1992 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1993 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
1994 *isPreserving = This->preserving;
1995 return S_OK;
1999 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
2000 IXMLDOMDocument3 *iface,
2001 VARIANT_BOOL isPreserving )
2003 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2004 TRACE("(%p)->(%d)\n", This, isPreserving);
2005 This->preserving = isPreserving;
2006 return S_OK;
2010 static HRESULT WINAPI domdoc_put_onReadyStateChange(
2011 IXMLDOMDocument3 *iface,
2012 VARIANT readyStateChangeSink )
2014 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2015 FIXME("%p\n", This);
2016 return E_NOTIMPL;
2020 static HRESULT WINAPI domdoc_put_onDataAvailable(
2021 IXMLDOMDocument3 *iface,
2022 VARIANT onDataAvailableSink )
2024 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2025 FIXME("%p\n", This);
2026 return E_NOTIMPL;
2029 static HRESULT WINAPI domdoc_put_onTransformNode(
2030 IXMLDOMDocument3 *iface,
2031 VARIANT onTransformNodeSink )
2033 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2034 FIXME("%p\n", This);
2035 return E_NOTIMPL;
2038 static HRESULT WINAPI domdoc_get_namespaces(
2039 IXMLDOMDocument3* iface,
2040 IXMLDOMSchemaCollection** schemaCollection )
2042 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2043 FIXME("(%p)->(%p)\n", This, schemaCollection);
2044 return E_NOTIMPL;
2047 static HRESULT WINAPI domdoc_get_schemas(
2048 IXMLDOMDocument3* iface,
2049 VARIANT* var1 )
2051 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2052 HRESULT hr = S_FALSE;
2053 IXMLDOMSchemaCollection *cur_schema = This->schema;
2055 TRACE("(%p)->(%p)\n", This, var1);
2057 VariantInit(var1); /* Test shows we don't call VariantClear here */
2058 V_VT(var1) = VT_NULL;
2060 if(cur_schema)
2062 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
2063 if(SUCCEEDED(hr))
2064 V_VT(var1) = VT_DISPATCH;
2066 return hr;
2069 static HRESULT WINAPI domdoc_putref_schemas(
2070 IXMLDOMDocument3* iface,
2071 VARIANT var1)
2073 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2074 HRESULT hr = E_FAIL;
2075 IXMLDOMSchemaCollection *new_schema = NULL;
2077 FIXME("(%p): semi-stub\n", This);
2078 switch(V_VT(&var1))
2080 case VT_UNKNOWN:
2081 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2082 break;
2084 case VT_DISPATCH:
2085 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2086 break;
2088 case VT_NULL:
2089 case VT_EMPTY:
2090 hr = S_OK;
2091 break;
2093 default:
2094 WARN("Can't get schema from vt %x\n", V_VT(&var1));
2097 if(SUCCEEDED(hr))
2099 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
2100 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
2103 return hr;
2106 static HRESULT WINAPI domdoc_validate(
2107 IXMLDOMDocument3* iface,
2108 IXMLDOMParseError** err)
2110 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2111 FIXME("(%p)->(%p)\n", This, err);
2112 return E_NOTIMPL;
2115 static HRESULT WINAPI domdoc_setProperty(
2116 IXMLDOMDocument3* iface,
2117 BSTR p,
2118 VARIANT var)
2120 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2122 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
2124 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2126 VARIANT varStr;
2127 HRESULT hr;
2128 BSTR bstr;
2130 V_VT(&varStr) = VT_EMPTY;
2131 if (V_VT(&var) != VT_BSTR)
2133 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2134 return hr;
2135 bstr = V_BSTR(&varStr);
2137 else
2138 bstr = V_BSTR(&var);
2140 hr = S_OK;
2141 if (lstrcmpiW(bstr, PropValueXPathW) == 0)
2142 This->bUseXPath = TRUE;
2143 else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
2144 This->bUseXPath = FALSE;
2145 else
2146 hr = E_FAIL;
2148 VariantClear(&varStr);
2149 return hr;
2151 else if (lstrcmpiW(p, PropertyProhibitDTDW) == 0)
2153 /* Ignore */
2154 FIXME("Ignoring property ProhibitDTD, value %d\n", V_BOOL(&var));
2155 return S_OK;
2157 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2159 if (V_VT(&var) == VT_BSTR)
2160 FIXME("Unsupported SelectionNamespaces: %s\n", wine_dbgstr_w(V_BSTR(&var)));
2161 return E_FAIL;
2164 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2165 return E_FAIL;
2168 static HRESULT WINAPI domdoc_getProperty(
2169 IXMLDOMDocument3* iface,
2170 BSTR p,
2171 VARIANT* var)
2173 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2175 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2177 if (var == NULL)
2178 return E_INVALIDARG;
2180 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2182 V_VT(var) = VT_BSTR;
2183 if (This->bUseXPath)
2184 V_BSTR(var) = SysAllocString(PropValueXPathW);
2185 else
2186 V_BSTR(var) = SysAllocString(PropValueXSLPatternW);
2187 return S_OK;
2190 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2191 return E_FAIL;
2194 static HRESULT WINAPI domdoc_validateNode(
2195 IXMLDOMDocument3* iface,
2196 IXMLDOMNode* node,
2197 IXMLDOMParseError** error)
2199 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2200 FIXME("(%p)->(%p %p): stub\n", This, node, error);
2201 return E_NOTIMPL;
2204 static HRESULT WINAPI domdoc_importNode(
2205 IXMLDOMDocument3* iface,
2206 IXMLDOMNode* node,
2207 VARIANT_BOOL deep,
2208 IXMLDOMNode** clone)
2210 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2211 FIXME("(%p)->(%p %d %p): stub\n", This, node, deep, clone);
2212 return E_NOTIMPL;
2215 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl =
2217 domdoc_QueryInterface,
2218 domdoc_AddRef,
2219 domdoc_Release,
2220 domdoc_GetTypeInfoCount,
2221 domdoc_GetTypeInfo,
2222 domdoc_GetIDsOfNames,
2223 domdoc_Invoke,
2224 domdoc_get_nodeName,
2225 domdoc_get_nodeValue,
2226 domdoc_put_nodeValue,
2227 domdoc_get_nodeType,
2228 domdoc_get_parentNode,
2229 domdoc_get_childNodes,
2230 domdoc_get_firstChild,
2231 domdoc_get_lastChild,
2232 domdoc_get_previousSibling,
2233 domdoc_get_nextSibling,
2234 domdoc_get_attributes,
2235 domdoc_insertBefore,
2236 domdoc_replaceChild,
2237 domdoc_removeChild,
2238 domdoc_appendChild,
2239 domdoc_hasChildNodes,
2240 domdoc_get_ownerDocument,
2241 domdoc_cloneNode,
2242 domdoc_get_nodeTypeString,
2243 domdoc_get_text,
2244 domdoc_put_text,
2245 domdoc_get_specified,
2246 domdoc_get_definition,
2247 domdoc_get_nodeTypedValue,
2248 domdoc_put_nodeTypedValue,
2249 domdoc_get_dataType,
2250 domdoc_put_dataType,
2251 domdoc_get_xml,
2252 domdoc_transformNode,
2253 domdoc_selectNodes,
2254 domdoc_selectSingleNode,
2255 domdoc_get_parsed,
2256 domdoc_get_namespaceURI,
2257 domdoc_get_prefix,
2258 domdoc_get_baseName,
2259 domdoc_transformNodeToObject,
2260 domdoc_get_doctype,
2261 domdoc_get_implementation,
2262 domdoc_get_documentElement,
2263 domdoc_put_documentElement,
2264 domdoc_createElement,
2265 domdoc_createDocumentFragment,
2266 domdoc_createTextNode,
2267 domdoc_createComment,
2268 domdoc_createCDATASection,
2269 domdoc_createProcessingInstruction,
2270 domdoc_createAttribute,
2271 domdoc_createEntityReference,
2272 domdoc_getElementsByTagName,
2273 domdoc_createNode,
2274 domdoc_nodeFromID,
2275 domdoc_load,
2276 domdoc_get_readyState,
2277 domdoc_get_parseError,
2278 domdoc_get_url,
2279 domdoc_get_async,
2280 domdoc_put_async,
2281 domdoc_abort,
2282 domdoc_loadXML,
2283 domdoc_save,
2284 domdoc_get_validateOnParse,
2285 domdoc_put_validateOnParse,
2286 domdoc_get_resolveExternals,
2287 domdoc_put_resolveExternals,
2288 domdoc_get_preserveWhiteSpace,
2289 domdoc_put_preserveWhiteSpace,
2290 domdoc_put_onReadyStateChange,
2291 domdoc_put_onDataAvailable,
2292 domdoc_put_onTransformNode,
2293 domdoc_get_namespaces,
2294 domdoc_get_schemas,
2295 domdoc_putref_schemas,
2296 domdoc_validate,
2297 domdoc_setProperty,
2298 domdoc_getProperty,
2299 domdoc_validateNode,
2300 domdoc_importNode
2303 /* xmldoc implementation of IObjectWithSite */
2304 static HRESULT WINAPI
2305 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2307 domdoc *This = impl_from_IObjectWithSite(iface);
2308 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2311 static ULONG WINAPI
2312 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2314 domdoc *This = impl_from_IObjectWithSite(iface);
2315 return IXMLDocument_AddRef((IXMLDocument *)This);
2318 static ULONG WINAPI
2319 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2321 domdoc *This = impl_from_IObjectWithSite(iface);
2322 return IXMLDocument_Release((IXMLDocument *)This);
2325 static HRESULT WINAPI
2326 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2328 domdoc *This = impl_from_IObjectWithSite(iface);
2330 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2332 if ( !This->site )
2333 return E_FAIL;
2335 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2338 static HRESULT WINAPI
2339 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2341 domdoc *This = impl_from_IObjectWithSite(iface);
2343 TRACE("(%p)->(%p)\n", iface, punk);
2345 if(!punk)
2347 if(This->site)
2349 IUnknown_Release( This->site );
2350 This->site = NULL;
2353 return S_OK;
2356 IUnknown_AddRef( punk );
2358 if(This->site)
2359 IUnknown_Release( This->site );
2361 This->site = punk;
2363 return S_OK;
2366 static const IObjectWithSiteVtbl domdocObjectSite =
2368 xmldoc_ObjectWithSite_QueryInterface,
2369 xmldoc_ObjectWithSite_AddRef,
2370 xmldoc_ObjectWithSite_Release,
2371 xmldoc_SetSite,
2372 xmldoc_GetSite,
2375 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2377 domdoc *This = impl_from_IObjectSafety(iface);
2378 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2381 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2383 domdoc *This = impl_from_IObjectSafety(iface);
2384 return IXMLDocument_AddRef((IXMLDocument *)This);
2387 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2389 domdoc *This = impl_from_IObjectSafety(iface);
2390 return IXMLDocument_Release((IXMLDocument *)This);
2393 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2395 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2396 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2398 domdoc *This = impl_from_IObjectSafety(iface);
2400 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2402 if(!pdwSupportedOptions || !pdwEnabledOptions)
2403 return E_POINTER;
2405 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2406 *pdwEnabledOptions = This->safeopt;
2408 return S_OK;
2411 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2412 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2414 domdoc *This = impl_from_IObjectSafety(iface);
2415 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2417 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2418 return E_FAIL;
2420 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2421 return S_OK;
2424 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2425 xmldoc_Safety_QueryInterface,
2426 xmldoc_Safety_AddRef,
2427 xmldoc_Safety_Release,
2428 xmldoc_Safety_GetInterfaceSafetyOptions,
2429 xmldoc_Safety_SetInterfaceSafetyOptions
2433 static const tid_t domdoc_iface_tids[] = {
2434 IXMLDOMNode_tid,
2435 IXMLDOMDocument_tid,
2436 IXMLDOMDocument2_tid,
2439 static dispex_static_data_t domdoc_dispex = {
2440 NULL,
2441 IXMLDOMDocument2_tid,
2442 NULL,
2443 domdoc_iface_tids
2446 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
2448 domdoc *doc;
2450 doc = heap_alloc( sizeof (*doc) );
2451 if( !doc )
2452 return E_OUTOFMEMORY;
2454 doc->lpVtbl = &domdoc_vtbl;
2455 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
2456 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2457 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2458 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2459 doc->ref = 1;
2460 doc->async = VARIANT_TRUE;
2461 doc->validating = 0;
2462 doc->resolving = 0;
2463 doc->preserving = 0;
2464 doc->bUseXPath = FALSE;
2465 doc->error = S_OK;
2466 doc->schema = NULL;
2467 doc->stream = NULL;
2468 doc->site = NULL;
2469 doc->safeopt = 0;
2470 doc->bsc = NULL;
2472 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IXMLDOMNode*)&doc->lpVtbl, &domdoc_dispex);
2474 *document = (IXMLDOMDocument3*)&doc->lpVtbl;
2476 TRACE("returning iface %p\n", *document);
2477 return S_OK;
2480 HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj)
2482 xmlDocPtr xmldoc;
2483 HRESULT hr;
2485 TRACE("(%p, %p)\n", pUnkOuter, ppObj);
2487 xmldoc = xmlNewDoc(NULL);
2488 if(!xmldoc)
2489 return E_OUTOFMEMORY;
2491 xmldoc->_private = create_priv();
2493 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument3**)ppObj);
2494 if(FAILED(hr))
2495 xmlFreeDoc(xmldoc);
2497 return hr;
2500 IUnknown* create_domdoc( xmlNodePtr document )
2502 void* pObj = NULL;
2503 HRESULT hr;
2505 TRACE("(%p)\n", document);
2507 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj);
2508 if (FAILED(hr))
2509 return NULL;
2511 return pObj;
2514 #else
2516 HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj)
2518 MESSAGE("This program tried to use a DOMDocument object, but\n"
2519 "libxml2 support was not present at compile time.\n");
2520 return E_NOTIMPL;
2523 #endif