msxml3: Don't use xmlnode's IXMLDOMNode iface in get_nodeType and get_nodeParent...
[wine-rt.git] / dlls / msxml3 / domdoc.c
blobf2a7ad68dd513e30051253a8b4f048f347b5bf1f
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 );
755 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
759 static HRESULT WINAPI domdoc_get_firstChild(
760 IXMLDOMDocument3 *iface,
761 IXMLDOMNode** firstChild )
763 domdoc *This = impl_from_IXMLDOMDocument3( iface );
764 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
768 static HRESULT WINAPI domdoc_get_lastChild(
769 IXMLDOMDocument3 *iface,
770 IXMLDOMNode** lastChild )
772 domdoc *This = impl_from_IXMLDOMDocument3( iface );
773 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
777 static HRESULT WINAPI domdoc_get_previousSibling(
778 IXMLDOMDocument3 *iface,
779 IXMLDOMNode** previousSibling )
781 domdoc *This = impl_from_IXMLDOMDocument3( iface );
782 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
786 static HRESULT WINAPI domdoc_get_nextSibling(
787 IXMLDOMDocument3 *iface,
788 IXMLDOMNode** nextSibling )
790 domdoc *This = impl_from_IXMLDOMDocument3( iface );
791 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
795 static HRESULT WINAPI domdoc_get_attributes(
796 IXMLDOMDocument3 *iface,
797 IXMLDOMNamedNodeMap** attributeMap )
799 domdoc *This = impl_from_IXMLDOMDocument3( iface );
800 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
804 static HRESULT WINAPI domdoc_insertBefore(
805 IXMLDOMDocument3 *iface,
806 IXMLDOMNode* newChild,
807 VARIANT refChild,
808 IXMLDOMNode** outNewChild )
810 domdoc *This = impl_from_IXMLDOMDocument3( iface );
811 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
815 static HRESULT WINAPI domdoc_replaceChild(
816 IXMLDOMDocument3 *iface,
817 IXMLDOMNode* newChild,
818 IXMLDOMNode* oldChild,
819 IXMLDOMNode** outOldChild)
821 domdoc *This = impl_from_IXMLDOMDocument3( iface );
822 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
826 static HRESULT WINAPI domdoc_removeChild(
827 IXMLDOMDocument3 *iface,
828 IXMLDOMNode* childNode,
829 IXMLDOMNode** oldChild)
831 domdoc *This = impl_from_IXMLDOMDocument3( iface );
832 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
836 static HRESULT WINAPI domdoc_appendChild(
837 IXMLDOMDocument3 *iface,
838 IXMLDOMNode* newChild,
839 IXMLDOMNode** outNewChild)
841 domdoc *This = impl_from_IXMLDOMDocument3( iface );
842 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
846 static HRESULT WINAPI domdoc_hasChildNodes(
847 IXMLDOMDocument3 *iface,
848 VARIANT_BOOL* hasChild)
850 domdoc *This = impl_from_IXMLDOMDocument3( iface );
851 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
855 static HRESULT WINAPI domdoc_get_ownerDocument(
856 IXMLDOMDocument3 *iface,
857 IXMLDOMDocument** DOMDocument)
859 domdoc *This = impl_from_IXMLDOMDocument3( iface );
860 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
864 static HRESULT WINAPI domdoc_cloneNode(
865 IXMLDOMDocument3 *iface,
866 VARIANT_BOOL deep,
867 IXMLDOMNode** cloneRoot)
869 domdoc *This = impl_from_IXMLDOMDocument3( iface );
870 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
874 static HRESULT WINAPI domdoc_get_nodeTypeString(
875 IXMLDOMDocument3 *iface,
876 BSTR* nodeType )
878 domdoc *This = impl_from_IXMLDOMDocument3( iface );
879 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
883 static HRESULT WINAPI domdoc_get_text(
884 IXMLDOMDocument3 *iface,
885 BSTR* text )
887 domdoc *This = impl_from_IXMLDOMDocument3( iface );
888 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
892 static HRESULT WINAPI domdoc_put_text(
893 IXMLDOMDocument3 *iface,
894 BSTR text )
896 domdoc *This = impl_from_IXMLDOMDocument3( iface );
897 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
901 static HRESULT WINAPI domdoc_get_specified(
902 IXMLDOMDocument3 *iface,
903 VARIANT_BOOL* isSpecified )
905 domdoc *This = impl_from_IXMLDOMDocument3( iface );
906 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
910 static HRESULT WINAPI domdoc_get_definition(
911 IXMLDOMDocument3 *iface,
912 IXMLDOMNode** definitionNode )
914 domdoc *This = impl_from_IXMLDOMDocument3( iface );
915 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
919 static HRESULT WINAPI domdoc_get_nodeTypedValue(
920 IXMLDOMDocument3 *iface,
921 VARIANT* typedValue )
923 domdoc *This = impl_from_IXMLDOMDocument3( iface );
924 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
927 static HRESULT WINAPI domdoc_put_nodeTypedValue(
928 IXMLDOMDocument3 *iface,
929 VARIANT typedValue )
931 domdoc *This = impl_from_IXMLDOMDocument3( iface );
932 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
936 static HRESULT WINAPI domdoc_get_dataType(
937 IXMLDOMDocument3 *iface,
938 VARIANT* dataTypeName )
940 domdoc *This = impl_from_IXMLDOMDocument3( iface );
941 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
945 static HRESULT WINAPI domdoc_put_dataType(
946 IXMLDOMDocument3 *iface,
947 BSTR dataTypeName )
949 domdoc *This = impl_from_IXMLDOMDocument3( iface );
950 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
954 static HRESULT WINAPI domdoc_get_xml(
955 IXMLDOMDocument3 *iface,
956 BSTR* xmlString )
958 domdoc *This = impl_from_IXMLDOMDocument3( iface );
959 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
963 static HRESULT WINAPI domdoc_transformNode(
964 IXMLDOMDocument3 *iface,
965 IXMLDOMNode* styleSheet,
966 BSTR* xmlString )
968 domdoc *This = impl_from_IXMLDOMDocument3( iface );
969 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
973 static HRESULT WINAPI domdoc_selectNodes(
974 IXMLDOMDocument3 *iface,
975 BSTR queryString,
976 IXMLDOMNodeList** resultList )
978 domdoc *This = impl_from_IXMLDOMDocument3( iface );
979 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
983 static HRESULT WINAPI domdoc_selectSingleNode(
984 IXMLDOMDocument3 *iface,
985 BSTR queryString,
986 IXMLDOMNode** resultNode )
988 domdoc *This = impl_from_IXMLDOMDocument3( iface );
989 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
993 static HRESULT WINAPI domdoc_get_parsed(
994 IXMLDOMDocument3 *iface,
995 VARIANT_BOOL* isParsed )
997 domdoc *This = impl_from_IXMLDOMDocument3( iface );
998 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
1002 static HRESULT WINAPI domdoc_get_namespaceURI(
1003 IXMLDOMDocument3 *iface,
1004 BSTR* namespaceURI )
1006 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1007 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
1011 static HRESULT WINAPI domdoc_get_prefix(
1012 IXMLDOMDocument3 *iface,
1013 BSTR* prefixString )
1015 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1016 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
1020 static HRESULT WINAPI domdoc_get_baseName(
1021 IXMLDOMDocument3 *iface,
1022 BSTR* nameString )
1024 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1025 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
1029 static HRESULT WINAPI domdoc_transformNodeToObject(
1030 IXMLDOMDocument3 *iface,
1031 IXMLDOMNode* stylesheet,
1032 VARIANT outputObject)
1034 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1035 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
1039 static HRESULT WINAPI domdoc_get_doctype(
1040 IXMLDOMDocument3 *iface,
1041 IXMLDOMDocumentType** documentType )
1043 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1044 FIXME("(%p)\n", This);
1045 return E_NOTIMPL;
1049 static HRESULT WINAPI domdoc_get_implementation(
1050 IXMLDOMDocument3 *iface,
1051 IXMLDOMImplementation** impl )
1053 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1055 TRACE("(%p)->(%p)\n", This, impl);
1057 if(!impl)
1058 return E_INVALIDARG;
1060 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1062 return S_OK;
1065 static HRESULT WINAPI domdoc_get_documentElement(
1066 IXMLDOMDocument3 *iface,
1067 IXMLDOMElement** DOMElement )
1069 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1070 IXMLDOMNode *element_node;
1071 xmlNodePtr root;
1072 HRESULT hr;
1074 TRACE("(%p)->(%p)\n", This, DOMElement);
1076 if(!DOMElement)
1077 return E_INVALIDARG;
1079 *DOMElement = NULL;
1081 root = xmlDocGetRootElement( get_doc(This) );
1082 if ( !root )
1083 return S_FALSE;
1085 element_node = create_node( root );
1086 if(!element_node) return S_FALSE;
1088 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (void**)DOMElement);
1089 IXMLDOMNode_Release(element_node);
1091 return hr;
1095 static HRESULT WINAPI domdoc_put_documentElement(
1096 IXMLDOMDocument3 *iface,
1097 IXMLDOMElement* DOMElement )
1099 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1100 IXMLDOMNode *elementNode;
1101 xmlNodePtr oldRoot;
1102 xmlnode *xmlNode;
1103 HRESULT hr;
1105 TRACE("(%p)->(%p)\n", This, DOMElement);
1107 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1108 if(FAILED(hr))
1109 return hr;
1111 xmlNode = get_node_obj( elementNode );
1112 if(!xmlNode) {
1113 FIXME("elementNode is not our object\n");
1114 return E_FAIL;
1117 if(!xmlNode->node->parent)
1118 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1119 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1121 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1122 IXMLDOMNode_Release( elementNode );
1124 if(oldRoot)
1125 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1127 return S_OK;
1131 static HRESULT WINAPI domdoc_createElement(
1132 IXMLDOMDocument3 *iface,
1133 BSTR tagname,
1134 IXMLDOMElement** element )
1136 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1137 IXMLDOMNode *node;
1138 VARIANT type;
1139 HRESULT hr;
1141 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1143 if (!element || !tagname) return E_INVALIDARG;
1145 V_VT(&type) = VT_I1;
1146 V_I1(&type) = NODE_ELEMENT;
1148 hr = IXMLDOMDocument3_createNode(iface, type, tagname, NULL, &node);
1149 if (hr == S_OK)
1151 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1152 IXMLDOMNode_Release(node);
1155 return hr;
1159 static HRESULT WINAPI domdoc_createDocumentFragment(
1160 IXMLDOMDocument3 *iface,
1161 IXMLDOMDocumentFragment** frag )
1163 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1164 IXMLDOMNode *node;
1165 VARIANT type;
1166 HRESULT hr;
1168 TRACE("(%p)->(%p)\n", This, frag);
1170 if (!frag) return E_INVALIDARG;
1172 *frag = NULL;
1174 V_VT(&type) = VT_I1;
1175 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1177 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1178 if (hr == S_OK)
1180 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1181 IXMLDOMNode_Release(node);
1184 return hr;
1188 static HRESULT WINAPI domdoc_createTextNode(
1189 IXMLDOMDocument3 *iface,
1190 BSTR data,
1191 IXMLDOMText** text )
1193 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1194 IXMLDOMNode *node;
1195 VARIANT type;
1196 HRESULT hr;
1198 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1200 if (!text) return E_INVALIDARG;
1202 *text = NULL;
1204 V_VT(&type) = VT_I1;
1205 V_I1(&type) = NODE_TEXT;
1207 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1208 if (hr == S_OK)
1210 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1211 IXMLDOMNode_Release(node);
1212 hr = IXMLDOMText_put_data(*text, data);
1215 return hr;
1219 static HRESULT WINAPI domdoc_createComment(
1220 IXMLDOMDocument3 *iface,
1221 BSTR data,
1222 IXMLDOMComment** comment )
1224 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1225 VARIANT type;
1226 HRESULT hr;
1227 IXMLDOMNode *node;
1229 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1231 if (!comment) return E_INVALIDARG;
1233 *comment = NULL;
1235 V_VT(&type) = VT_I1;
1236 V_I1(&type) = NODE_COMMENT;
1238 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1239 if (hr == S_OK)
1241 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1242 IXMLDOMNode_Release(node);
1243 hr = IXMLDOMComment_put_data(*comment, data);
1246 return hr;
1250 static HRESULT WINAPI domdoc_createCDATASection(
1251 IXMLDOMDocument3 *iface,
1252 BSTR data,
1253 IXMLDOMCDATASection** cdata )
1255 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1256 IXMLDOMNode *node;
1257 VARIANT type;
1258 HRESULT hr;
1260 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1262 if (!cdata) return E_INVALIDARG;
1264 *cdata = NULL;
1266 V_VT(&type) = VT_I1;
1267 V_I1(&type) = NODE_CDATA_SECTION;
1269 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1270 if (hr == S_OK)
1272 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1273 IXMLDOMNode_Release(node);
1274 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1277 return hr;
1281 static HRESULT WINAPI domdoc_createProcessingInstruction(
1282 IXMLDOMDocument3 *iface,
1283 BSTR target,
1284 BSTR data,
1285 IXMLDOMProcessingInstruction** pi )
1287 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1288 IXMLDOMNode *node;
1289 VARIANT type;
1290 HRESULT hr;
1292 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1294 if (!pi) return E_INVALIDARG;
1296 *pi = NULL;
1298 V_VT(&type) = VT_I1;
1299 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1301 hr = IXMLDOMDocument3_createNode(iface, type, target, NULL, &node);
1302 if (hr == S_OK)
1304 VARIANT v_data;
1305 xmlnode *node_obj;
1307 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1308 node_obj = get_node_obj(node);
1309 V_VT(&v_data) = VT_BSTR;
1310 V_BSTR(&v_data) = data;
1312 hr = node_put_value(node_obj, &v_data);
1314 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1315 IXMLDOMNode_Release(node);
1318 return hr;
1322 static HRESULT WINAPI domdoc_createAttribute(
1323 IXMLDOMDocument3 *iface,
1324 BSTR name,
1325 IXMLDOMAttribute** attribute )
1327 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1328 IXMLDOMNode *node;
1329 VARIANT type;
1330 HRESULT hr;
1332 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1334 if (!attribute || !name) return E_INVALIDARG;
1336 V_VT(&type) = VT_I1;
1337 V_I1(&type) = NODE_ATTRIBUTE;
1339 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1340 if (hr == S_OK)
1342 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1343 IXMLDOMNode_Release(node);
1346 return hr;
1350 static HRESULT WINAPI domdoc_createEntityReference(
1351 IXMLDOMDocument3 *iface,
1352 BSTR name,
1353 IXMLDOMEntityReference** entityref )
1355 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1356 IXMLDOMNode *node;
1357 VARIANT type;
1358 HRESULT hr;
1360 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1362 if (!entityref) return E_INVALIDARG;
1364 *entityref = NULL;
1366 V_VT(&type) = VT_I1;
1367 V_I1(&type) = NODE_ENTITY_REFERENCE;
1369 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1370 if (hr == S_OK)
1372 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1373 IXMLDOMNode_Release(node);
1376 return hr;
1380 static HRESULT WINAPI domdoc_getElementsByTagName(
1381 IXMLDOMDocument3 *iface,
1382 BSTR tagName,
1383 IXMLDOMNodeList** resultList )
1385 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1386 HRESULT hr;
1388 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1390 if (!tagName || !resultList) return E_INVALIDARG;
1392 if (tagName[0] == '*' && tagName[1] == 0)
1394 static const WCHAR formatallW[] = {'/','/','*',0};
1395 hr = queryresult_create((xmlNodePtr)get_doc(This), formatallW, resultList);
1397 else
1399 static const WCHAR xpathformat[] =
1400 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
1401 static const WCHAR closeW[] = { '\'',']',0 };
1403 LPWSTR pattern;
1404 WCHAR *ptr;
1405 INT length;
1407 length = lstrlenW(tagName);
1409 /* without two WCHARs from format specifier */
1410 ptr = pattern = heap_alloc(sizeof(xpathformat) + length*sizeof(WCHAR) + sizeof(closeW));
1412 memcpy(ptr, xpathformat, sizeof(xpathformat));
1413 ptr += sizeof(xpathformat)/sizeof(WCHAR);
1414 memcpy(ptr, tagName, length*sizeof(WCHAR));
1415 ptr += length;
1416 memcpy(ptr, closeW, sizeof(closeW));
1418 hr = queryresult_create((xmlNodePtr)get_doc(This), pattern, resultList);
1419 heap_free(pattern);
1422 return hr;
1425 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1427 VARIANT tmp;
1428 HRESULT hr;
1430 VariantInit(&tmp);
1431 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1432 if(FAILED(hr))
1433 return E_INVALIDARG;
1435 *type = V_I4(&tmp);
1437 return S_OK;
1440 static HRESULT WINAPI domdoc_createNode(
1441 IXMLDOMDocument3 *iface,
1442 VARIANT Type,
1443 BSTR name,
1444 BSTR namespaceURI,
1445 IXMLDOMNode** node )
1447 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1448 DOMNodeType node_type;
1449 xmlNodePtr xmlnode;
1450 xmlChar *xml_name;
1451 HRESULT hr;
1453 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1455 if(!node) return E_INVALIDARG;
1457 if(namespaceURI && namespaceURI[0])
1458 FIXME("nodes with namespaces currently not supported.\n");
1460 hr = get_node_type(Type, &node_type);
1461 if(FAILED(hr)) return hr;
1463 TRACE("node_type %d\n", node_type);
1465 /* exit earlier for types that need name */
1466 switch(node_type)
1468 case NODE_ELEMENT:
1469 case NODE_ATTRIBUTE:
1470 case NODE_ENTITY_REFERENCE:
1471 case NODE_PROCESSING_INSTRUCTION:
1472 if (!name || *name == 0) return E_FAIL;
1473 default:
1474 break;
1477 xml_name = xmlChar_from_wchar(name);
1479 switch(node_type)
1481 case NODE_ELEMENT:
1482 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1483 break;
1484 case NODE_ATTRIBUTE:
1485 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1486 break;
1487 case NODE_TEXT:
1488 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1489 break;
1490 case NODE_CDATA_SECTION:
1491 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1492 break;
1493 case NODE_ENTITY_REFERENCE:
1494 xmlnode = xmlNewReference(get_doc(This), xml_name);
1495 break;
1496 case NODE_PROCESSING_INSTRUCTION:
1497 #ifdef HAVE_XMLNEWDOCPI
1498 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1499 #else
1500 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1501 xmlnode = NULL;
1502 #endif
1503 break;
1504 case NODE_COMMENT:
1505 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1506 break;
1507 case NODE_DOCUMENT_FRAGMENT:
1508 xmlnode = xmlNewDocFragment(get_doc(This));
1509 break;
1510 /* unsupported types */
1511 case NODE_DOCUMENT:
1512 case NODE_DOCUMENT_TYPE:
1513 case NODE_ENTITY:
1514 case NODE_NOTATION:
1515 heap_free(xml_name);
1516 return E_INVALIDARG;
1517 default:
1518 FIXME("unhandled node type %d\n", node_type);
1519 xmlnode = NULL;
1520 break;
1523 *node = create_node(xmlnode);
1524 heap_free(xml_name);
1526 if(*node)
1528 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1529 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1530 return S_OK;
1533 return E_FAIL;
1536 static HRESULT WINAPI domdoc_nodeFromID(
1537 IXMLDOMDocument3 *iface,
1538 BSTR idString,
1539 IXMLDOMNode** node )
1541 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1542 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1543 return E_NOTIMPL;
1546 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1548 domdoc *This = obj;
1549 xmlDocPtr xmldoc;
1551 xmldoc = doparse( ptr, len, NULL );
1552 if(xmldoc) {
1553 xmldoc->_private = create_priv();
1554 return attach_xmldoc(&This->node, xmldoc);
1557 return S_OK;
1560 static HRESULT doread( domdoc *This, LPWSTR filename )
1562 bsc_t *bsc;
1563 HRESULT hr;
1565 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1566 if(FAILED(hr))
1567 return hr;
1569 if(This->bsc)
1570 detach_bsc(This->bsc);
1572 This->bsc = bsc;
1573 return S_OK;
1576 static HRESULT WINAPI domdoc_load(
1577 IXMLDOMDocument3 *iface,
1578 VARIANT xmlSource,
1579 VARIANT_BOOL* isSuccessful )
1581 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1582 LPWSTR filename = NULL;
1583 HRESULT hr = S_FALSE;
1584 IXMLDOMDocument3 *pNewDoc = NULL;
1585 IStream *pStream = NULL;
1586 xmlDocPtr xmldoc;
1588 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1590 *isSuccessful = VARIANT_FALSE;
1592 assert( &This->node );
1594 switch( V_VT(&xmlSource) )
1596 case VT_BSTR:
1597 filename = V_BSTR(&xmlSource);
1598 break;
1599 case VT_UNKNOWN:
1600 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument3, (void**)&pNewDoc);
1601 if(hr == S_OK)
1603 if(pNewDoc)
1605 domdoc *newDoc = impl_from_IXMLDOMDocument3( pNewDoc );
1606 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1607 hr = attach_xmldoc(&This->node, xmldoc);
1609 if(SUCCEEDED(hr))
1610 *isSuccessful = VARIANT_TRUE;
1612 return hr;
1615 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1616 if(hr == S_OK)
1618 IPersistStream *pDocStream;
1619 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1620 if(hr == S_OK)
1622 hr = IPersistStream_Load(pDocStream, pStream);
1623 IStream_Release(pStream);
1624 if(hr == S_OK)
1626 *isSuccessful = VARIANT_TRUE;
1628 TRACE("Using IStream to load Document\n");
1629 return S_OK;
1631 else
1633 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1636 else
1638 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1641 else
1643 /* ISequentialStream */
1644 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1646 break;
1647 default:
1648 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1651 TRACE("filename (%s)\n", debugstr_w(filename));
1653 if ( filename )
1655 hr = doread( This, filename );
1657 if ( FAILED(hr) )
1658 This->error = E_FAIL;
1659 else
1661 hr = This->error = S_OK;
1662 *isSuccessful = VARIANT_TRUE;
1666 if(!filename || FAILED(hr)) {
1667 xmldoc = xmlNewDoc(NULL);
1668 xmldoc->_private = create_priv();
1669 hr = attach_xmldoc(&This->node, xmldoc);
1670 if(SUCCEEDED(hr))
1671 hr = S_FALSE;
1674 TRACE("ret (%d)\n", hr);
1676 return hr;
1680 static HRESULT WINAPI domdoc_get_readyState(
1681 IXMLDOMDocument3 *iface,
1682 LONG *value )
1684 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1685 FIXME("(%p)->(%p)\n", This, value);
1686 return E_NOTIMPL;
1690 static HRESULT WINAPI domdoc_get_parseError(
1691 IXMLDOMDocument3 *iface,
1692 IXMLDOMParseError** errorObj )
1694 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1695 static const WCHAR err[] = {'e','r','r','o','r',0};
1696 BSTR error_string = NULL;
1698 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1700 if(This->error)
1701 error_string = SysAllocString(err);
1703 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1704 if(!*errorObj) return E_OUTOFMEMORY;
1705 return S_OK;
1709 static HRESULT WINAPI domdoc_get_url(
1710 IXMLDOMDocument3 *iface,
1711 BSTR* urlString )
1713 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1714 FIXME("(%p)->(%p)\n", This, urlString);
1715 return E_NOTIMPL;
1719 static HRESULT WINAPI domdoc_get_async(
1720 IXMLDOMDocument3 *iface,
1721 VARIANT_BOOL* isAsync )
1723 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1725 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1726 *isAsync = This->async;
1727 return S_OK;
1731 static HRESULT WINAPI domdoc_put_async(
1732 IXMLDOMDocument3 *iface,
1733 VARIANT_BOOL isAsync )
1735 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1737 TRACE("(%p)->(%d)\n", This, isAsync);
1738 This->async = isAsync;
1739 return S_OK;
1743 static HRESULT WINAPI domdoc_abort(
1744 IXMLDOMDocument3 *iface )
1746 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1747 FIXME("%p\n", This);
1748 return E_NOTIMPL;
1752 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1754 UINT len;
1755 LPSTR str;
1757 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
1758 str = heap_alloc( len );
1759 if ( !str )
1760 return FALSE;
1761 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
1762 *plen = len;
1763 *pstr = str;
1764 return TRUE;
1767 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
1768 static HRESULT WINAPI domdoc_loadXML(
1769 IXMLDOMDocument3 *iface,
1770 BSTR bstrXML,
1771 VARIANT_BOOL* isSuccessful )
1773 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1774 xmlDocPtr xmldoc = NULL;
1775 HRESULT hr = S_FALSE, hr2;
1776 char *str;
1777 int len;
1779 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
1781 assert ( &This->node );
1783 if ( isSuccessful )
1785 *isSuccessful = VARIANT_FALSE;
1787 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1789 xmldoc = doparse( str, len, "UTF-8" );
1790 heap_free( str );
1791 if ( !xmldoc )
1792 This->error = E_FAIL;
1793 else
1795 hr = This->error = S_OK;
1796 *isSuccessful = VARIANT_TRUE;
1797 TRACE("parsed document %p\n", xmldoc);
1801 if(!xmldoc)
1802 xmldoc = xmlNewDoc(NULL);
1804 xmldoc->_private = create_priv();
1805 hr2 = attach_xmldoc( &This->node, xmldoc );
1806 if( FAILED(hr2) )
1807 hr = hr2;
1809 return hr;
1812 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1813 int len)
1815 DWORD written = -1;
1817 if(!WriteFile(ctx, buffer, len, &written, NULL))
1819 WARN("write error\n");
1820 return -1;
1822 else
1823 return written;
1826 static int XMLCALL domdoc_save_closecallback(void *ctx)
1828 return CloseHandle(ctx) ? 0 : -1;
1831 static HRESULT WINAPI domdoc_save(
1832 IXMLDOMDocument3 *iface,
1833 VARIANT destination )
1835 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1836 HANDLE handle;
1837 xmlSaveCtxtPtr ctx;
1838 xmlNodePtr xmldecl;
1839 HRESULT ret = S_OK;
1841 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1842 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1844 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1846 FIXME("Unhandled vt %d\n", V_VT(&destination));
1847 return S_FALSE;
1850 if(V_VT(&destination) == VT_UNKNOWN)
1852 IUnknown *pUnk = V_UNKNOWN(&destination);
1853 IXMLDOMDocument2 *pDocument;
1855 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&pDocument);
1856 if(ret == S_OK)
1858 VARIANT_BOOL success;
1859 BSTR xml;
1861 ret = IXMLDOMDocument3_get_xml(iface, &xml);
1862 if(ret == S_OK)
1864 ret = IXMLDOMDocument3_loadXML(pDocument, xml, &success);
1865 SysFreeString(xml);
1868 IXMLDOMDocument3_Release(pDocument);
1871 TRACE("ret %d\n", ret);
1873 return ret;
1876 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1877 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1878 if( handle == INVALID_HANDLE_VALUE )
1880 WARN("failed to create file\n");
1881 return S_FALSE;
1884 /* disable top XML declaration */
1885 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1886 handle, NULL, XML_SAVE_NO_DECL);
1887 if (!ctx)
1889 CloseHandle(handle);
1890 return S_FALSE;
1893 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
1894 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1895 xmldoc_link_xmldecl(get_doc(This), xmldecl);
1897 /* will close file through close callback */
1898 xmlSaveClose(ctx);
1900 return ret;
1903 static HRESULT WINAPI domdoc_get_validateOnParse(
1904 IXMLDOMDocument3 *iface,
1905 VARIANT_BOOL* isValidating )
1907 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1908 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
1909 *isValidating = This->validating;
1910 return S_OK;
1914 static HRESULT WINAPI domdoc_put_validateOnParse(
1915 IXMLDOMDocument3 *iface,
1916 VARIANT_BOOL isValidating )
1918 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1919 TRACE("(%p)->(%d)\n", This, isValidating);
1920 This->validating = isValidating;
1921 return S_OK;
1925 static HRESULT WINAPI domdoc_get_resolveExternals(
1926 IXMLDOMDocument3 *iface,
1927 VARIANT_BOOL* isResolving )
1929 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1930 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
1931 *isResolving = This->resolving;
1932 return S_OK;
1936 static HRESULT WINAPI domdoc_put_resolveExternals(
1937 IXMLDOMDocument3 *iface,
1938 VARIANT_BOOL isResolving )
1940 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1941 TRACE("(%p)->(%d)\n", This, isResolving);
1942 This->resolving = isResolving;
1943 return S_OK;
1947 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1948 IXMLDOMDocument3 *iface,
1949 VARIANT_BOOL* isPreserving )
1951 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1952 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
1953 *isPreserving = This->preserving;
1954 return S_OK;
1958 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1959 IXMLDOMDocument3 *iface,
1960 VARIANT_BOOL isPreserving )
1962 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1963 TRACE("(%p)->(%d)\n", This, isPreserving);
1964 This->preserving = isPreserving;
1965 return S_OK;
1969 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1970 IXMLDOMDocument3 *iface,
1971 VARIANT readyStateChangeSink )
1973 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1974 FIXME("%p\n", This);
1975 return E_NOTIMPL;
1979 static HRESULT WINAPI domdoc_put_onDataAvailable(
1980 IXMLDOMDocument3 *iface,
1981 VARIANT onDataAvailableSink )
1983 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1984 FIXME("%p\n", This);
1985 return E_NOTIMPL;
1988 static HRESULT WINAPI domdoc_put_onTransformNode(
1989 IXMLDOMDocument3 *iface,
1990 VARIANT onTransformNodeSink )
1992 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1993 FIXME("%p\n", This);
1994 return E_NOTIMPL;
1997 static HRESULT WINAPI domdoc_get_namespaces(
1998 IXMLDOMDocument3* iface,
1999 IXMLDOMSchemaCollection** schemaCollection )
2001 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2002 FIXME("(%p)->(%p)\n", This, schemaCollection);
2003 return E_NOTIMPL;
2006 static HRESULT WINAPI domdoc_get_schemas(
2007 IXMLDOMDocument3* iface,
2008 VARIANT* var1 )
2010 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2011 HRESULT hr = S_FALSE;
2012 IXMLDOMSchemaCollection *cur_schema = This->schema;
2014 TRACE("(%p)->(%p)\n", This, var1);
2016 VariantInit(var1); /* Test shows we don't call VariantClear here */
2017 V_VT(var1) = VT_NULL;
2019 if(cur_schema)
2021 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
2022 if(SUCCEEDED(hr))
2023 V_VT(var1) = VT_DISPATCH;
2025 return hr;
2028 static HRESULT WINAPI domdoc_putref_schemas(
2029 IXMLDOMDocument3* iface,
2030 VARIANT var1)
2032 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2033 HRESULT hr = E_FAIL;
2034 IXMLDOMSchemaCollection *new_schema = NULL;
2036 FIXME("(%p): semi-stub\n", This);
2037 switch(V_VT(&var1))
2039 case VT_UNKNOWN:
2040 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2041 break;
2043 case VT_DISPATCH:
2044 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2045 break;
2047 case VT_NULL:
2048 case VT_EMPTY:
2049 hr = S_OK;
2050 break;
2052 default:
2053 WARN("Can't get schema from vt %x\n", V_VT(&var1));
2056 if(SUCCEEDED(hr))
2058 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
2059 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
2062 return hr;
2065 static HRESULT WINAPI domdoc_validate(
2066 IXMLDOMDocument3* iface,
2067 IXMLDOMParseError** err)
2069 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2070 FIXME("(%p)->(%p)\n", This, err);
2071 return E_NOTIMPL;
2074 static HRESULT WINAPI domdoc_setProperty(
2075 IXMLDOMDocument3* iface,
2076 BSTR p,
2077 VARIANT var)
2079 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2081 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
2083 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2085 VARIANT varStr;
2086 HRESULT hr;
2087 BSTR bstr;
2089 V_VT(&varStr) = VT_EMPTY;
2090 if (V_VT(&var) != VT_BSTR)
2092 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2093 return hr;
2094 bstr = V_BSTR(&varStr);
2096 else
2097 bstr = V_BSTR(&var);
2099 hr = S_OK;
2100 if (lstrcmpiW(bstr, PropValueXPathW) == 0)
2101 This->bUseXPath = TRUE;
2102 else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
2103 This->bUseXPath = FALSE;
2104 else
2105 hr = E_FAIL;
2107 VariantClear(&varStr);
2108 return hr;
2110 else if (lstrcmpiW(p, PropertyProhibitDTDW) == 0)
2112 /* Ignore */
2113 FIXME("Ignoring property ProhibitDTD, value %d\n", V_BOOL(&var));
2114 return S_OK;
2116 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2118 if (V_VT(&var) == VT_BSTR)
2119 FIXME("Unsupported SelectionNamespaces: %s\n", wine_dbgstr_w(V_BSTR(&var)));
2120 return E_FAIL;
2123 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2124 return E_FAIL;
2127 static HRESULT WINAPI domdoc_getProperty(
2128 IXMLDOMDocument3* iface,
2129 BSTR p,
2130 VARIANT* var)
2132 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2134 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2136 if (var == NULL)
2137 return E_INVALIDARG;
2139 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2141 V_VT(var) = VT_BSTR;
2142 if (This->bUseXPath)
2143 V_BSTR(var) = SysAllocString(PropValueXPathW);
2144 else
2145 V_BSTR(var) = SysAllocString(PropValueXSLPatternW);
2146 return S_OK;
2149 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2150 return E_FAIL;
2153 static HRESULT WINAPI domdoc_validateNode(
2154 IXMLDOMDocument3* iface,
2155 IXMLDOMNode* node,
2156 IXMLDOMParseError** error)
2158 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2159 FIXME("(%p)->(%p %p): stub\n", This, node, error);
2160 return E_NOTIMPL;
2163 static HRESULT WINAPI domdoc_importNode(
2164 IXMLDOMDocument3* iface,
2165 IXMLDOMNode* node,
2166 VARIANT_BOOL deep,
2167 IXMLDOMNode** clone)
2169 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2170 FIXME("(%p)->(%p %d %p): stub\n", This, node, deep, clone);
2171 return E_NOTIMPL;
2174 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl =
2176 domdoc_QueryInterface,
2177 domdoc_AddRef,
2178 domdoc_Release,
2179 domdoc_GetTypeInfoCount,
2180 domdoc_GetTypeInfo,
2181 domdoc_GetIDsOfNames,
2182 domdoc_Invoke,
2183 domdoc_get_nodeName,
2184 domdoc_get_nodeValue,
2185 domdoc_put_nodeValue,
2186 domdoc_get_nodeType,
2187 domdoc_get_parentNode,
2188 domdoc_get_childNodes,
2189 domdoc_get_firstChild,
2190 domdoc_get_lastChild,
2191 domdoc_get_previousSibling,
2192 domdoc_get_nextSibling,
2193 domdoc_get_attributes,
2194 domdoc_insertBefore,
2195 domdoc_replaceChild,
2196 domdoc_removeChild,
2197 domdoc_appendChild,
2198 domdoc_hasChildNodes,
2199 domdoc_get_ownerDocument,
2200 domdoc_cloneNode,
2201 domdoc_get_nodeTypeString,
2202 domdoc_get_text,
2203 domdoc_put_text,
2204 domdoc_get_specified,
2205 domdoc_get_definition,
2206 domdoc_get_nodeTypedValue,
2207 domdoc_put_nodeTypedValue,
2208 domdoc_get_dataType,
2209 domdoc_put_dataType,
2210 domdoc_get_xml,
2211 domdoc_transformNode,
2212 domdoc_selectNodes,
2213 domdoc_selectSingleNode,
2214 domdoc_get_parsed,
2215 domdoc_get_namespaceURI,
2216 domdoc_get_prefix,
2217 domdoc_get_baseName,
2218 domdoc_transformNodeToObject,
2219 domdoc_get_doctype,
2220 domdoc_get_implementation,
2221 domdoc_get_documentElement,
2222 domdoc_put_documentElement,
2223 domdoc_createElement,
2224 domdoc_createDocumentFragment,
2225 domdoc_createTextNode,
2226 domdoc_createComment,
2227 domdoc_createCDATASection,
2228 domdoc_createProcessingInstruction,
2229 domdoc_createAttribute,
2230 domdoc_createEntityReference,
2231 domdoc_getElementsByTagName,
2232 domdoc_createNode,
2233 domdoc_nodeFromID,
2234 domdoc_load,
2235 domdoc_get_readyState,
2236 domdoc_get_parseError,
2237 domdoc_get_url,
2238 domdoc_get_async,
2239 domdoc_put_async,
2240 domdoc_abort,
2241 domdoc_loadXML,
2242 domdoc_save,
2243 domdoc_get_validateOnParse,
2244 domdoc_put_validateOnParse,
2245 domdoc_get_resolveExternals,
2246 domdoc_put_resolveExternals,
2247 domdoc_get_preserveWhiteSpace,
2248 domdoc_put_preserveWhiteSpace,
2249 domdoc_put_onReadyStateChange,
2250 domdoc_put_onDataAvailable,
2251 domdoc_put_onTransformNode,
2252 domdoc_get_namespaces,
2253 domdoc_get_schemas,
2254 domdoc_putref_schemas,
2255 domdoc_validate,
2256 domdoc_setProperty,
2257 domdoc_getProperty,
2258 domdoc_validateNode,
2259 domdoc_importNode
2262 /* xmldoc implementation of IObjectWithSite */
2263 static HRESULT WINAPI
2264 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2266 domdoc *This = impl_from_IObjectWithSite(iface);
2267 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2270 static ULONG WINAPI
2271 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2273 domdoc *This = impl_from_IObjectWithSite(iface);
2274 return IXMLDocument_AddRef((IXMLDocument *)This);
2277 static ULONG WINAPI
2278 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2280 domdoc *This = impl_from_IObjectWithSite(iface);
2281 return IXMLDocument_Release((IXMLDocument *)This);
2284 static HRESULT WINAPI
2285 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2287 domdoc *This = impl_from_IObjectWithSite(iface);
2289 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2291 if ( !This->site )
2292 return E_FAIL;
2294 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2297 static HRESULT WINAPI
2298 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2300 domdoc *This = impl_from_IObjectWithSite(iface);
2302 TRACE("(%p)->(%p)\n", iface, punk);
2304 if(!punk)
2306 if(This->site)
2308 IUnknown_Release( This->site );
2309 This->site = NULL;
2312 return S_OK;
2315 IUnknown_AddRef( punk );
2317 if(This->site)
2318 IUnknown_Release( This->site );
2320 This->site = punk;
2322 return S_OK;
2325 static const IObjectWithSiteVtbl domdocObjectSite =
2327 xmldoc_ObjectWithSite_QueryInterface,
2328 xmldoc_ObjectWithSite_AddRef,
2329 xmldoc_ObjectWithSite_Release,
2330 xmldoc_SetSite,
2331 xmldoc_GetSite,
2334 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2336 domdoc *This = impl_from_IObjectSafety(iface);
2337 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2340 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2342 domdoc *This = impl_from_IObjectSafety(iface);
2343 return IXMLDocument_AddRef((IXMLDocument *)This);
2346 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2348 domdoc *This = impl_from_IObjectSafety(iface);
2349 return IXMLDocument_Release((IXMLDocument *)This);
2352 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2354 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2355 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2357 domdoc *This = impl_from_IObjectSafety(iface);
2359 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2361 if(!pdwSupportedOptions || !pdwEnabledOptions)
2362 return E_POINTER;
2364 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2365 *pdwEnabledOptions = This->safeopt;
2367 return S_OK;
2370 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2371 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2373 domdoc *This = impl_from_IObjectSafety(iface);
2374 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2376 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2377 return E_FAIL;
2379 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2380 return S_OK;
2383 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2384 xmldoc_Safety_QueryInterface,
2385 xmldoc_Safety_AddRef,
2386 xmldoc_Safety_Release,
2387 xmldoc_Safety_GetInterfaceSafetyOptions,
2388 xmldoc_Safety_SetInterfaceSafetyOptions
2392 static const tid_t domdoc_iface_tids[] = {
2393 IXMLDOMNode_tid,
2394 IXMLDOMDocument_tid,
2395 IXMLDOMDocument2_tid,
2398 static dispex_static_data_t domdoc_dispex = {
2399 NULL,
2400 IXMLDOMDocument2_tid,
2401 NULL,
2402 domdoc_iface_tids
2405 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
2407 domdoc *doc;
2409 doc = heap_alloc( sizeof (*doc) );
2410 if( !doc )
2411 return E_OUTOFMEMORY;
2413 doc->lpVtbl = &domdoc_vtbl;
2414 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
2415 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2416 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2417 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2418 doc->ref = 1;
2419 doc->async = VARIANT_TRUE;
2420 doc->validating = 0;
2421 doc->resolving = 0;
2422 doc->preserving = 0;
2423 doc->bUseXPath = FALSE;
2424 doc->error = S_OK;
2425 doc->schema = NULL;
2426 doc->stream = NULL;
2427 doc->site = NULL;
2428 doc->safeopt = 0;
2429 doc->bsc = NULL;
2431 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IXMLDOMNode*)&doc->lpVtbl, &domdoc_dispex);
2433 *document = (IXMLDOMDocument3*)&doc->lpVtbl;
2435 TRACE("returning iface %p\n", *document);
2436 return S_OK;
2439 HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj)
2441 xmlDocPtr xmldoc;
2442 HRESULT hr;
2444 TRACE("(%p, %p)\n", pUnkOuter, ppObj);
2446 xmldoc = xmlNewDoc(NULL);
2447 if(!xmldoc)
2448 return E_OUTOFMEMORY;
2450 xmldoc->_private = create_priv();
2452 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument3**)ppObj);
2453 if(FAILED(hr))
2454 xmlFreeDoc(xmldoc);
2456 return hr;
2459 IUnknown* create_domdoc( xmlNodePtr document )
2461 void* pObj = NULL;
2462 HRESULT hr;
2464 TRACE("(%p)\n", document);
2466 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj);
2467 if (FAILED(hr))
2468 return NULL;
2470 return pObj;
2473 #else
2475 HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj)
2477 MESSAGE("This program tried to use a DOMDocument object, but\n"
2478 "libxml2 support was not present at compile time.\n");
2479 return E_NOTIMPL;
2482 #endif