msxml3: Fix invalid parameter handling for IXMLDOMElement::getElementsByTagName().
[wine.git] / dlls / msxml3 / domdoc.c
blob98045a06ff007ea9d479de0d90c5884830d05650
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 = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), &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_IXMLDOMDocument ) ||
522 IsEqualGUID( riid, &IID_IXMLDOMDocument2 )||
523 IsEqualGUID( riid, &IID_IXMLDOMDocument3 ))
525 *ppvObject = iface;
527 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
529 *ppvObject = IXMLDOMNode_from_impl(&This->node);
531 else if (IsEqualGUID(&IID_IPersistStream, riid) ||
532 IsEqualGUID(&IID_IPersistStreamInit, riid))
534 *ppvObject = &(This->lpvtblIPersistStreamInit);
536 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
538 *ppvObject = &(This->lpvtblIObjectWithSite);
540 else if (IsEqualGUID(&IID_IObjectSafety, riid))
542 *ppvObject = &(This->lpvtblIObjectSafety);
544 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
546 *ppvObject = &This->lpvtblISupportErrorInfo;
548 else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
550 return *ppvObject ? S_OK : E_NOINTERFACE;
552 else if(IsEqualGUID(&IID_IRunnableObject, riid))
554 TRACE("IID_IRunnableObject not supported returning NULL\n");
555 return E_NOINTERFACE;
557 else
559 FIXME("interface %s not implemented\n", debugstr_guid(riid));
560 return E_NOINTERFACE;
563 IUnknown_AddRef((IUnknown*)*ppvObject);
565 return S_OK;
569 static ULONG WINAPI domdoc_AddRef(
570 IXMLDOMDocument3 *iface )
572 domdoc *This = impl_from_IXMLDOMDocument3( iface );
573 TRACE("%p\n", This );
574 return InterlockedIncrement( &This->ref );
578 static ULONG WINAPI domdoc_Release(
579 IXMLDOMDocument3 *iface )
581 domdoc *This = impl_from_IXMLDOMDocument3( iface );
582 LONG ref;
584 TRACE("%p\n", This );
586 ref = InterlockedDecrement( &This->ref );
587 if ( ref == 0 )
589 if(This->bsc)
590 detach_bsc(This->bsc);
592 if (This->site)
593 IUnknown_Release( This->site );
594 destroy_xmlnode(&This->node);
595 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
596 if (This->stream) IStream_Release(This->stream);
597 HeapFree( GetProcessHeap(), 0, This );
600 return ref;
603 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument3 *iface, UINT* pctinfo )
605 domdoc *This = impl_from_IXMLDOMDocument3( iface );
607 TRACE("(%p)->(%p)\n", This, pctinfo);
609 *pctinfo = 1;
611 return S_OK;
614 static HRESULT WINAPI domdoc_GetTypeInfo(
615 IXMLDOMDocument3 *iface,
616 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
618 domdoc *This = impl_from_IXMLDOMDocument3( iface );
619 HRESULT hr;
621 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
623 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
625 return hr;
628 static HRESULT WINAPI domdoc_GetIDsOfNames(
629 IXMLDOMDocument3 *iface,
630 REFIID riid,
631 LPOLESTR* rgszNames,
632 UINT cNames,
633 LCID lcid,
634 DISPID* rgDispId)
636 domdoc *This = impl_from_IXMLDOMDocument3( iface );
637 ITypeInfo *typeinfo;
638 HRESULT hr;
640 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
641 lcid, rgDispId);
643 if(!rgszNames || cNames == 0 || !rgDispId)
644 return E_INVALIDARG;
646 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
647 if(SUCCEEDED(hr))
649 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
650 ITypeInfo_Release(typeinfo);
653 return hr;
657 static HRESULT WINAPI domdoc_Invoke(
658 IXMLDOMDocument3 *iface,
659 DISPID dispIdMember,
660 REFIID riid,
661 LCID lcid,
662 WORD wFlags,
663 DISPPARAMS* pDispParams,
664 VARIANT* pVarResult,
665 EXCEPINFO* pExcepInfo,
666 UINT* puArgErr)
668 domdoc *This = impl_from_IXMLDOMDocument3( iface );
669 ITypeInfo *typeinfo;
670 HRESULT hr;
672 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
673 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
675 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
676 if(SUCCEEDED(hr))
678 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
679 pVarResult, pExcepInfo, puArgErr);
680 ITypeInfo_Release(typeinfo);
683 return hr;
687 static HRESULT WINAPI domdoc_get_nodeName(
688 IXMLDOMDocument3 *iface,
689 BSTR* name )
691 domdoc *This = impl_from_IXMLDOMDocument3( iface );
692 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
696 static HRESULT WINAPI domdoc_get_nodeValue(
697 IXMLDOMDocument3 *iface,
698 VARIANT* value )
700 domdoc *This = impl_from_IXMLDOMDocument3( iface );
701 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
705 static HRESULT WINAPI domdoc_put_nodeValue(
706 IXMLDOMDocument3 *iface,
707 VARIANT value)
709 domdoc *This = impl_from_IXMLDOMDocument3( iface );
710 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
714 static HRESULT WINAPI domdoc_get_nodeType(
715 IXMLDOMDocument3 *iface,
716 DOMNodeType* type )
718 domdoc *This = impl_from_IXMLDOMDocument3( iface );
719 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
723 static HRESULT WINAPI domdoc_get_parentNode(
724 IXMLDOMDocument3 *iface,
725 IXMLDOMNode** parent )
727 domdoc *This = impl_from_IXMLDOMDocument3( iface );
728 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
732 static HRESULT WINAPI domdoc_get_childNodes(
733 IXMLDOMDocument3 *iface,
734 IXMLDOMNodeList** childList )
736 domdoc *This = impl_from_IXMLDOMDocument3( iface );
737 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
741 static HRESULT WINAPI domdoc_get_firstChild(
742 IXMLDOMDocument3 *iface,
743 IXMLDOMNode** firstChild )
745 domdoc *This = impl_from_IXMLDOMDocument3( iface );
746 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
750 static HRESULT WINAPI domdoc_get_lastChild(
751 IXMLDOMDocument3 *iface,
752 IXMLDOMNode** lastChild )
754 domdoc *This = impl_from_IXMLDOMDocument3( iface );
755 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
759 static HRESULT WINAPI domdoc_get_previousSibling(
760 IXMLDOMDocument3 *iface,
761 IXMLDOMNode** previousSibling )
763 domdoc *This = impl_from_IXMLDOMDocument3( iface );
764 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
768 static HRESULT WINAPI domdoc_get_nextSibling(
769 IXMLDOMDocument3 *iface,
770 IXMLDOMNode** nextSibling )
772 domdoc *This = impl_from_IXMLDOMDocument3( iface );
773 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
777 static HRESULT WINAPI domdoc_get_attributes(
778 IXMLDOMDocument3 *iface,
779 IXMLDOMNamedNodeMap** attributeMap )
781 domdoc *This = impl_from_IXMLDOMDocument3( iface );
782 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
786 static HRESULT WINAPI domdoc_insertBefore(
787 IXMLDOMDocument3 *iface,
788 IXMLDOMNode* newChild,
789 VARIANT refChild,
790 IXMLDOMNode** outNewChild )
792 domdoc *This = impl_from_IXMLDOMDocument3( iface );
793 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
797 static HRESULT WINAPI domdoc_replaceChild(
798 IXMLDOMDocument3 *iface,
799 IXMLDOMNode* newChild,
800 IXMLDOMNode* oldChild,
801 IXMLDOMNode** outOldChild)
803 domdoc *This = impl_from_IXMLDOMDocument3( iface );
804 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
808 static HRESULT WINAPI domdoc_removeChild(
809 IXMLDOMDocument3 *iface,
810 IXMLDOMNode* childNode,
811 IXMLDOMNode** oldChild)
813 domdoc *This = impl_from_IXMLDOMDocument3( iface );
814 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
818 static HRESULT WINAPI domdoc_appendChild(
819 IXMLDOMDocument3 *iface,
820 IXMLDOMNode* newChild,
821 IXMLDOMNode** outNewChild)
823 domdoc *This = impl_from_IXMLDOMDocument3( iface );
824 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
828 static HRESULT WINAPI domdoc_hasChildNodes(
829 IXMLDOMDocument3 *iface,
830 VARIANT_BOOL* hasChild)
832 domdoc *This = impl_from_IXMLDOMDocument3( iface );
833 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
837 static HRESULT WINAPI domdoc_get_ownerDocument(
838 IXMLDOMDocument3 *iface,
839 IXMLDOMDocument** DOMDocument)
841 domdoc *This = impl_from_IXMLDOMDocument3( iface );
842 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
846 static HRESULT WINAPI domdoc_cloneNode(
847 IXMLDOMDocument3 *iface,
848 VARIANT_BOOL deep,
849 IXMLDOMNode** cloneRoot)
851 domdoc *This = impl_from_IXMLDOMDocument3( iface );
852 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
856 static HRESULT WINAPI domdoc_get_nodeTypeString(
857 IXMLDOMDocument3 *iface,
858 BSTR* nodeType )
860 domdoc *This = impl_from_IXMLDOMDocument3( iface );
861 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
865 static HRESULT WINAPI domdoc_get_text(
866 IXMLDOMDocument3 *iface,
867 BSTR* text )
869 domdoc *This = impl_from_IXMLDOMDocument3( iface );
870 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
874 static HRESULT WINAPI domdoc_put_text(
875 IXMLDOMDocument3 *iface,
876 BSTR text )
878 domdoc *This = impl_from_IXMLDOMDocument3( iface );
879 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
883 static HRESULT WINAPI domdoc_get_specified(
884 IXMLDOMDocument3 *iface,
885 VARIANT_BOOL* isSpecified )
887 domdoc *This = impl_from_IXMLDOMDocument3( iface );
888 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
892 static HRESULT WINAPI domdoc_get_definition(
893 IXMLDOMDocument3 *iface,
894 IXMLDOMNode** definitionNode )
896 domdoc *This = impl_from_IXMLDOMDocument3( iface );
897 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
901 static HRESULT WINAPI domdoc_get_nodeTypedValue(
902 IXMLDOMDocument3 *iface,
903 VARIANT* typedValue )
905 domdoc *This = impl_from_IXMLDOMDocument3( iface );
906 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
909 static HRESULT WINAPI domdoc_put_nodeTypedValue(
910 IXMLDOMDocument3 *iface,
911 VARIANT typedValue )
913 domdoc *This = impl_from_IXMLDOMDocument3( iface );
914 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
918 static HRESULT WINAPI domdoc_get_dataType(
919 IXMLDOMDocument3 *iface,
920 VARIANT* dataTypeName )
922 domdoc *This = impl_from_IXMLDOMDocument3( iface );
923 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
927 static HRESULT WINAPI domdoc_put_dataType(
928 IXMLDOMDocument3 *iface,
929 BSTR dataTypeName )
931 domdoc *This = impl_from_IXMLDOMDocument3( iface );
932 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
936 static HRESULT WINAPI domdoc_get_xml(
937 IXMLDOMDocument3 *iface,
938 BSTR* xmlString )
940 domdoc *This = impl_from_IXMLDOMDocument3( iface );
941 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
945 static HRESULT WINAPI domdoc_transformNode(
946 IXMLDOMDocument3 *iface,
947 IXMLDOMNode* styleSheet,
948 BSTR* xmlString )
950 domdoc *This = impl_from_IXMLDOMDocument3( iface );
951 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
955 static HRESULT WINAPI domdoc_selectNodes(
956 IXMLDOMDocument3 *iface,
957 BSTR queryString,
958 IXMLDOMNodeList** resultList )
960 domdoc *This = impl_from_IXMLDOMDocument3( iface );
961 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
965 static HRESULT WINAPI domdoc_selectSingleNode(
966 IXMLDOMDocument3 *iface,
967 BSTR queryString,
968 IXMLDOMNode** resultNode )
970 domdoc *This = impl_from_IXMLDOMDocument3( iface );
971 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
975 static HRESULT WINAPI domdoc_get_parsed(
976 IXMLDOMDocument3 *iface,
977 VARIANT_BOOL* isParsed )
979 domdoc *This = impl_from_IXMLDOMDocument3( iface );
980 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
984 static HRESULT WINAPI domdoc_get_namespaceURI(
985 IXMLDOMDocument3 *iface,
986 BSTR* namespaceURI )
988 domdoc *This = impl_from_IXMLDOMDocument3( iface );
989 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
993 static HRESULT WINAPI domdoc_get_prefix(
994 IXMLDOMDocument3 *iface,
995 BSTR* prefixString )
997 domdoc *This = impl_from_IXMLDOMDocument3( iface );
998 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
1002 static HRESULT WINAPI domdoc_get_baseName(
1003 IXMLDOMDocument3 *iface,
1004 BSTR* nameString )
1006 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1007 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
1011 static HRESULT WINAPI domdoc_transformNodeToObject(
1012 IXMLDOMDocument3 *iface,
1013 IXMLDOMNode* stylesheet,
1014 VARIANT outputObject)
1016 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1017 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
1021 static HRESULT WINAPI domdoc_get_doctype(
1022 IXMLDOMDocument3 *iface,
1023 IXMLDOMDocumentType** documentType )
1025 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1026 FIXME("(%p)\n", This);
1027 return E_NOTIMPL;
1031 static HRESULT WINAPI domdoc_get_implementation(
1032 IXMLDOMDocument3 *iface,
1033 IXMLDOMImplementation** impl )
1035 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1037 TRACE("(%p)->(%p)\n", This, impl);
1039 if(!impl)
1040 return E_INVALIDARG;
1042 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1044 return S_OK;
1047 static HRESULT WINAPI domdoc_get_documentElement(
1048 IXMLDOMDocument3 *iface,
1049 IXMLDOMElement** DOMElement )
1051 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1052 IXMLDOMNode *element_node;
1053 xmlNodePtr root;
1054 HRESULT hr;
1056 TRACE("(%p)->(%p)\n", This, DOMElement);
1058 if(!DOMElement)
1059 return E_INVALIDARG;
1061 *DOMElement = NULL;
1063 root = xmlDocGetRootElement( get_doc(This) );
1064 if ( !root )
1065 return S_FALSE;
1067 element_node = create_node( root );
1068 if(!element_node) return S_FALSE;
1070 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (void**)DOMElement);
1071 IXMLDOMNode_Release(element_node);
1073 return hr;
1077 static HRESULT WINAPI domdoc_put_documentElement(
1078 IXMLDOMDocument3 *iface,
1079 IXMLDOMElement* DOMElement )
1081 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1082 IXMLDOMNode *elementNode;
1083 xmlNodePtr oldRoot;
1084 xmlnode *xmlNode;
1085 HRESULT hr;
1087 TRACE("(%p)->(%p)\n", This, DOMElement);
1089 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1090 if(FAILED(hr))
1091 return hr;
1093 xmlNode = impl_from_IXMLDOMNode( elementNode );
1095 if(!xmlNode->node->parent)
1096 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1097 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1099 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1100 IXMLDOMNode_Release( elementNode );
1102 if(oldRoot)
1103 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1105 return S_OK;
1109 static HRESULT WINAPI domdoc_createElement(
1110 IXMLDOMDocument3 *iface,
1111 BSTR tagname,
1112 IXMLDOMElement** element )
1114 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1115 IXMLDOMNode *node;
1116 VARIANT type;
1117 HRESULT hr;
1119 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1121 if (!element || !tagname) return E_INVALIDARG;
1123 V_VT(&type) = VT_I1;
1124 V_I1(&type) = NODE_ELEMENT;
1126 hr = IXMLDOMDocument3_createNode(iface, type, tagname, NULL, &node);
1127 if (hr == S_OK)
1129 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1130 IXMLDOMNode_Release(node);
1133 return hr;
1137 static HRESULT WINAPI domdoc_createDocumentFragment(
1138 IXMLDOMDocument3 *iface,
1139 IXMLDOMDocumentFragment** frag )
1141 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1142 IXMLDOMNode *node;
1143 VARIANT type;
1144 HRESULT hr;
1146 TRACE("(%p)->(%p)\n", This, frag);
1148 if (!frag) return E_INVALIDARG;
1150 *frag = NULL;
1152 V_VT(&type) = VT_I1;
1153 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1155 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1156 if (hr == S_OK)
1158 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1159 IXMLDOMNode_Release(node);
1162 return hr;
1166 static HRESULT WINAPI domdoc_createTextNode(
1167 IXMLDOMDocument3 *iface,
1168 BSTR data,
1169 IXMLDOMText** text )
1171 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1172 IXMLDOMNode *node;
1173 VARIANT type;
1174 HRESULT hr;
1176 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1178 if (!text) return E_INVALIDARG;
1180 *text = NULL;
1182 V_VT(&type) = VT_I1;
1183 V_I1(&type) = NODE_TEXT;
1185 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1186 if (hr == S_OK)
1188 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1189 IXMLDOMNode_Release(node);
1190 hr = IXMLDOMText_put_data(*text, data);
1193 return hr;
1197 static HRESULT WINAPI domdoc_createComment(
1198 IXMLDOMDocument3 *iface,
1199 BSTR data,
1200 IXMLDOMComment** comment )
1202 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1203 VARIANT type;
1204 HRESULT hr;
1205 IXMLDOMNode *node;
1207 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1209 if (!comment) return E_INVALIDARG;
1211 *comment = NULL;
1213 V_VT(&type) = VT_I1;
1214 V_I1(&type) = NODE_COMMENT;
1216 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1217 if (hr == S_OK)
1219 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1220 IXMLDOMNode_Release(node);
1221 hr = IXMLDOMComment_put_data(*comment, data);
1224 return hr;
1228 static HRESULT WINAPI domdoc_createCDATASection(
1229 IXMLDOMDocument3 *iface,
1230 BSTR data,
1231 IXMLDOMCDATASection** cdata )
1233 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1234 IXMLDOMNode *node;
1235 VARIANT type;
1236 HRESULT hr;
1238 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1240 if (!cdata) return E_INVALIDARG;
1242 *cdata = NULL;
1244 V_VT(&type) = VT_I1;
1245 V_I1(&type) = NODE_CDATA_SECTION;
1247 hr = IXMLDOMDocument3_createNode(iface, type, NULL, NULL, &node);
1248 if (hr == S_OK)
1250 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1251 IXMLDOMNode_Release(node);
1252 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1255 return hr;
1259 static HRESULT WINAPI domdoc_createProcessingInstruction(
1260 IXMLDOMDocument3 *iface,
1261 BSTR target,
1262 BSTR data,
1263 IXMLDOMProcessingInstruction** pi )
1265 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1266 IXMLDOMNode *node;
1267 VARIANT type;
1268 HRESULT hr;
1270 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1272 if (!pi) return E_INVALIDARG;
1274 *pi = NULL;
1276 V_VT(&type) = VT_I1;
1277 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1279 hr = IXMLDOMDocument3_createNode(iface, type, target, NULL, &node);
1280 if (hr == S_OK)
1282 VARIANT v_data;
1284 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1285 V_VT(&v_data) = VT_BSTR;
1286 V_BSTR(&v_data) = data;
1288 hr = IXMLDOMNode_put_nodeValue( node, v_data );
1290 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1291 IXMLDOMNode_Release(node);
1294 return hr;
1298 static HRESULT WINAPI domdoc_createAttribute(
1299 IXMLDOMDocument3 *iface,
1300 BSTR name,
1301 IXMLDOMAttribute** attribute )
1303 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1304 IXMLDOMNode *node;
1305 VARIANT type;
1306 HRESULT hr;
1308 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1310 if (!attribute || !name) return E_INVALIDARG;
1312 V_VT(&type) = VT_I1;
1313 V_I1(&type) = NODE_ATTRIBUTE;
1315 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1316 if (hr == S_OK)
1318 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1319 IXMLDOMNode_Release(node);
1322 return hr;
1326 static HRESULT WINAPI domdoc_createEntityReference(
1327 IXMLDOMDocument3 *iface,
1328 BSTR name,
1329 IXMLDOMEntityReference** entityref )
1331 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1332 IXMLDOMNode *node;
1333 VARIANT type;
1334 HRESULT hr;
1336 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1338 if (!entityref) return E_INVALIDARG;
1340 *entityref = NULL;
1342 V_VT(&type) = VT_I1;
1343 V_I1(&type) = NODE_ENTITY_REFERENCE;
1345 hr = IXMLDOMDocument3_createNode(iface, type, name, NULL, &node);
1346 if (hr == S_OK)
1348 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1349 IXMLDOMNode_Release(node);
1352 return hr;
1356 static HRESULT WINAPI domdoc_getElementsByTagName(
1357 IXMLDOMDocument3 *iface,
1358 BSTR tagName,
1359 IXMLDOMNodeList** resultList )
1361 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1362 HRESULT hr;
1364 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1366 if (!tagName || !resultList) return E_INVALIDARG;
1368 if (tagName[0] == '*' && tagName[1] == 0)
1370 static const WCHAR formatallW[] = {'/','/','*',0};
1371 hr = queryresult_create((xmlNodePtr)get_doc(This), formatallW, resultList);
1373 else
1375 static const WCHAR xpathformat[] =
1376 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'' };
1377 static const WCHAR closeW[] = { '\'',']',0 };
1379 LPWSTR pattern;
1380 WCHAR *ptr;
1381 INT length;
1383 length = lstrlenW(tagName);
1385 /* without two WCHARs from format specifier */
1386 ptr = pattern = heap_alloc(sizeof(xpathformat) + length*sizeof(WCHAR) + sizeof(closeW));
1388 memcpy(ptr, xpathformat, sizeof(xpathformat));
1389 ptr += sizeof(xpathformat)/sizeof(WCHAR);
1390 memcpy(ptr, tagName, length*sizeof(WCHAR));
1391 ptr += length;
1392 memcpy(ptr, closeW, sizeof(closeW));
1394 hr = queryresult_create((xmlNodePtr)get_doc(This), pattern, resultList);
1395 heap_free(pattern);
1398 return hr;
1401 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1403 VARIANT tmp;
1404 HRESULT hr;
1406 VariantInit(&tmp);
1407 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1408 if(FAILED(hr))
1409 return E_INVALIDARG;
1411 *type = V_I4(&tmp);
1413 return S_OK;
1416 static HRESULT WINAPI domdoc_createNode(
1417 IXMLDOMDocument3 *iface,
1418 VARIANT Type,
1419 BSTR name,
1420 BSTR namespaceURI,
1421 IXMLDOMNode** node )
1423 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1424 DOMNodeType node_type;
1425 xmlNodePtr xmlnode;
1426 xmlChar *xml_name;
1427 HRESULT hr;
1429 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1431 if(!node) return E_INVALIDARG;
1433 if(namespaceURI && namespaceURI[0])
1434 FIXME("nodes with namespaces currently not supported.\n");
1436 hr = get_node_type(Type, &node_type);
1437 if(FAILED(hr)) return hr;
1439 TRACE("node_type %d\n", node_type);
1441 /* exit earlier for types that need name */
1442 switch(node_type)
1444 case NODE_ELEMENT:
1445 case NODE_ATTRIBUTE:
1446 case NODE_ENTITY_REFERENCE:
1447 case NODE_PROCESSING_INSTRUCTION:
1448 if (!name || *name == 0) return E_FAIL;
1449 default:
1450 break;
1453 xml_name = xmlChar_from_wchar(name);
1455 switch(node_type)
1457 case NODE_ELEMENT:
1458 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1459 break;
1460 case NODE_ATTRIBUTE:
1461 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1462 break;
1463 case NODE_TEXT:
1464 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1465 break;
1466 case NODE_CDATA_SECTION:
1467 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1468 break;
1469 case NODE_ENTITY_REFERENCE:
1470 xmlnode = xmlNewReference(get_doc(This), xml_name);
1471 break;
1472 case NODE_PROCESSING_INSTRUCTION:
1473 #ifdef HAVE_XMLNEWDOCPI
1474 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1475 #else
1476 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1477 xmlnode = NULL;
1478 #endif
1479 break;
1480 case NODE_COMMENT:
1481 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1482 break;
1483 case NODE_DOCUMENT_FRAGMENT:
1484 xmlnode = xmlNewDocFragment(get_doc(This));
1485 break;
1486 /* unsupported types */
1487 case NODE_DOCUMENT:
1488 case NODE_DOCUMENT_TYPE:
1489 case NODE_ENTITY:
1490 case NODE_NOTATION:
1491 heap_free(xml_name);
1492 return E_INVALIDARG;
1493 default:
1494 FIXME("unhandled node type %d\n", node_type);
1495 xmlnode = NULL;
1496 break;
1499 *node = create_node(xmlnode);
1500 heap_free(xml_name);
1502 if(*node)
1504 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1505 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1506 return S_OK;
1509 return E_FAIL;
1512 static HRESULT WINAPI domdoc_nodeFromID(
1513 IXMLDOMDocument3 *iface,
1514 BSTR idString,
1515 IXMLDOMNode** node )
1517 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1518 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1519 return E_NOTIMPL;
1522 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1524 domdoc *This = obj;
1525 xmlDocPtr xmldoc;
1527 xmldoc = doparse( ptr, len, NULL );
1528 if(xmldoc) {
1529 xmldoc->_private = create_priv();
1530 return attach_xmldoc(&This->node, xmldoc);
1533 return S_OK;
1536 static HRESULT doread( domdoc *This, LPWSTR filename )
1538 bsc_t *bsc;
1539 HRESULT hr;
1541 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1542 if(FAILED(hr))
1543 return hr;
1545 if(This->bsc)
1546 detach_bsc(This->bsc);
1548 This->bsc = bsc;
1549 return S_OK;
1552 static HRESULT WINAPI domdoc_load(
1553 IXMLDOMDocument3 *iface,
1554 VARIANT xmlSource,
1555 VARIANT_BOOL* isSuccessful )
1557 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1558 LPWSTR filename = NULL;
1559 HRESULT hr = S_FALSE;
1560 IXMLDOMDocument3 *pNewDoc = NULL;
1561 IStream *pStream = NULL;
1562 xmlDocPtr xmldoc;
1564 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1566 *isSuccessful = VARIANT_FALSE;
1568 assert( &This->node );
1570 switch( V_VT(&xmlSource) )
1572 case VT_BSTR:
1573 filename = V_BSTR(&xmlSource);
1574 break;
1575 case VT_UNKNOWN:
1576 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument3, (void**)&pNewDoc);
1577 if(hr == S_OK)
1579 if(pNewDoc)
1581 domdoc *newDoc = impl_from_IXMLDOMDocument3( pNewDoc );
1582 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1583 hr = attach_xmldoc(&This->node, xmldoc);
1585 if(SUCCEEDED(hr))
1586 *isSuccessful = VARIANT_TRUE;
1588 return hr;
1591 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1592 if(hr == S_OK)
1594 IPersistStream *pDocStream;
1595 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1596 if(hr == S_OK)
1598 hr = IPersistStream_Load(pDocStream, pStream);
1599 IStream_Release(pStream);
1600 if(hr == S_OK)
1602 *isSuccessful = VARIANT_TRUE;
1604 TRACE("Using IStream to load Document\n");
1605 return S_OK;
1607 else
1609 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1612 else
1614 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1617 else
1619 /* ISequentialStream */
1620 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1622 break;
1623 default:
1624 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1627 TRACE("filename (%s)\n", debugstr_w(filename));
1629 if ( filename )
1631 hr = doread( This, filename );
1633 if ( FAILED(hr) )
1634 This->error = E_FAIL;
1635 else
1637 hr = This->error = S_OK;
1638 *isSuccessful = VARIANT_TRUE;
1642 if(!filename || FAILED(hr)) {
1643 xmldoc = xmlNewDoc(NULL);
1644 xmldoc->_private = create_priv();
1645 hr = attach_xmldoc(&This->node, xmldoc);
1646 if(SUCCEEDED(hr))
1647 hr = S_FALSE;
1650 TRACE("ret (%d)\n", hr);
1652 return hr;
1656 static HRESULT WINAPI domdoc_get_readyState(
1657 IXMLDOMDocument3 *iface,
1658 LONG *value )
1660 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1661 FIXME("(%p)->(%p)\n", This, value);
1662 return E_NOTIMPL;
1666 static HRESULT WINAPI domdoc_get_parseError(
1667 IXMLDOMDocument3 *iface,
1668 IXMLDOMParseError** errorObj )
1670 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1671 static const WCHAR err[] = {'e','r','r','o','r',0};
1672 BSTR error_string = NULL;
1674 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1676 if(This->error)
1677 error_string = SysAllocString(err);
1679 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1680 if(!*errorObj) return E_OUTOFMEMORY;
1681 return S_OK;
1685 static HRESULT WINAPI domdoc_get_url(
1686 IXMLDOMDocument3 *iface,
1687 BSTR* urlString )
1689 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1690 FIXME("(%p)->(%p)\n", This, urlString);
1691 return E_NOTIMPL;
1695 static HRESULT WINAPI domdoc_get_async(
1696 IXMLDOMDocument3 *iface,
1697 VARIANT_BOOL* isAsync )
1699 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1701 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1702 *isAsync = This->async;
1703 return S_OK;
1707 static HRESULT WINAPI domdoc_put_async(
1708 IXMLDOMDocument3 *iface,
1709 VARIANT_BOOL isAsync )
1711 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1713 TRACE("(%p)->(%d)\n", This, isAsync);
1714 This->async = isAsync;
1715 return S_OK;
1719 static HRESULT WINAPI domdoc_abort(
1720 IXMLDOMDocument3 *iface )
1722 domdoc *This = impl_from_IXMLDOMDocument3(iface);
1723 FIXME("%p\n", This);
1724 return E_NOTIMPL;
1728 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1730 UINT len;
1731 LPSTR str;
1733 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
1734 str = heap_alloc( len );
1735 if ( !str )
1736 return FALSE;
1737 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
1738 *plen = len;
1739 *pstr = str;
1740 return TRUE;
1743 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
1744 static HRESULT WINAPI domdoc_loadXML(
1745 IXMLDOMDocument3 *iface,
1746 BSTR bstrXML,
1747 VARIANT_BOOL* isSuccessful )
1749 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1750 xmlDocPtr xmldoc = NULL;
1751 HRESULT hr = S_FALSE, hr2;
1752 char *str;
1753 int len;
1755 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
1757 assert ( &This->node );
1759 if ( isSuccessful )
1761 *isSuccessful = VARIANT_FALSE;
1763 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1765 xmldoc = doparse( str, len, "UTF-8" );
1766 heap_free( str );
1767 if ( !xmldoc )
1768 This->error = E_FAIL;
1769 else
1771 hr = This->error = S_OK;
1772 *isSuccessful = VARIANT_TRUE;
1773 TRACE("parsed document %p\n", xmldoc);
1777 if(!xmldoc)
1778 xmldoc = xmlNewDoc(NULL);
1780 xmldoc->_private = create_priv();
1781 hr2 = attach_xmldoc( &This->node, xmldoc );
1782 if( FAILED(hr2) )
1783 hr = hr2;
1785 return hr;
1788 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1789 int len)
1791 DWORD written = -1;
1793 if(!WriteFile(ctx, buffer, len, &written, NULL))
1795 WARN("write error\n");
1796 return -1;
1798 else
1799 return written;
1802 static int XMLCALL domdoc_save_closecallback(void *ctx)
1804 return CloseHandle(ctx) ? 0 : -1;
1807 static HRESULT WINAPI domdoc_save(
1808 IXMLDOMDocument3 *iface,
1809 VARIANT destination )
1811 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1812 HANDLE handle;
1813 xmlSaveCtxtPtr ctx;
1814 xmlNodePtr xmldecl;
1815 HRESULT ret = S_OK;
1817 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1818 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1820 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1822 FIXME("Unhandled vt %d\n", V_VT(&destination));
1823 return S_FALSE;
1826 if(V_VT(&destination) == VT_UNKNOWN)
1828 IUnknown *pUnk = V_UNKNOWN(&destination);
1829 IXMLDOMDocument2 *pDocument;
1831 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&pDocument);
1832 if(ret == S_OK)
1834 VARIANT_BOOL success;
1835 BSTR xml;
1837 ret = IXMLDOMDocument3_get_xml(iface, &xml);
1838 if(ret == S_OK)
1840 ret = IXMLDOMDocument3_loadXML(pDocument, xml, &success);
1841 SysFreeString(xml);
1844 IXMLDOMDocument3_Release(pDocument);
1847 TRACE("ret %d\n", ret);
1849 return ret;
1852 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1853 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1854 if( handle == INVALID_HANDLE_VALUE )
1856 WARN("failed to create file\n");
1857 return S_FALSE;
1860 /* disable top XML declaration */
1861 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1862 handle, NULL, XML_SAVE_NO_DECL);
1863 if (!ctx)
1865 CloseHandle(handle);
1866 return S_FALSE;
1869 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
1870 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1871 xmldoc_link_xmldecl(get_doc(This), xmldecl);
1873 /* will close file through close callback */
1874 xmlSaveClose(ctx);
1876 return ret;
1879 static HRESULT WINAPI domdoc_get_validateOnParse(
1880 IXMLDOMDocument3 *iface,
1881 VARIANT_BOOL* isValidating )
1883 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1884 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
1885 *isValidating = This->validating;
1886 return S_OK;
1890 static HRESULT WINAPI domdoc_put_validateOnParse(
1891 IXMLDOMDocument3 *iface,
1892 VARIANT_BOOL isValidating )
1894 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1895 TRACE("(%p)->(%d)\n", This, isValidating);
1896 This->validating = isValidating;
1897 return S_OK;
1901 static HRESULT WINAPI domdoc_get_resolveExternals(
1902 IXMLDOMDocument3 *iface,
1903 VARIANT_BOOL* isResolving )
1905 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1906 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
1907 *isResolving = This->resolving;
1908 return S_OK;
1912 static HRESULT WINAPI domdoc_put_resolveExternals(
1913 IXMLDOMDocument3 *iface,
1914 VARIANT_BOOL isResolving )
1916 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1917 TRACE("(%p)->(%d)\n", This, isResolving);
1918 This->resolving = isResolving;
1919 return S_OK;
1923 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1924 IXMLDOMDocument3 *iface,
1925 VARIANT_BOOL* isPreserving )
1927 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1928 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
1929 *isPreserving = This->preserving;
1930 return S_OK;
1934 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1935 IXMLDOMDocument3 *iface,
1936 VARIANT_BOOL isPreserving )
1938 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1939 TRACE("(%p)->(%d)\n", This, isPreserving);
1940 This->preserving = isPreserving;
1941 return S_OK;
1945 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1946 IXMLDOMDocument3 *iface,
1947 VARIANT readyStateChangeSink )
1949 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1950 FIXME("%p\n", This);
1951 return E_NOTIMPL;
1955 static HRESULT WINAPI domdoc_put_onDataAvailable(
1956 IXMLDOMDocument3 *iface,
1957 VARIANT onDataAvailableSink )
1959 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1960 FIXME("%p\n", This);
1961 return E_NOTIMPL;
1964 static HRESULT WINAPI domdoc_put_onTransformNode(
1965 IXMLDOMDocument3 *iface,
1966 VARIANT onTransformNodeSink )
1968 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1969 FIXME("%p\n", This);
1970 return E_NOTIMPL;
1973 static HRESULT WINAPI domdoc_get_namespaces(
1974 IXMLDOMDocument3* iface,
1975 IXMLDOMSchemaCollection** schemaCollection )
1977 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1978 FIXME("(%p)->(%p)\n", This, schemaCollection);
1979 return E_NOTIMPL;
1982 static HRESULT WINAPI domdoc_get_schemas(
1983 IXMLDOMDocument3* iface,
1984 VARIANT* var1 )
1986 domdoc *This = impl_from_IXMLDOMDocument3( iface );
1987 HRESULT hr = S_FALSE;
1988 IXMLDOMSchemaCollection *cur_schema = This->schema;
1990 TRACE("(%p)->(%p)\n", This, var1);
1992 VariantInit(var1); /* Test shows we don't call VariantClear here */
1993 V_VT(var1) = VT_NULL;
1995 if(cur_schema)
1997 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1998 if(SUCCEEDED(hr))
1999 V_VT(var1) = VT_DISPATCH;
2001 return hr;
2004 static HRESULT WINAPI domdoc_putref_schemas(
2005 IXMLDOMDocument3* iface,
2006 VARIANT var1)
2008 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2009 HRESULT hr = E_FAIL;
2010 IXMLDOMSchemaCollection *new_schema = NULL;
2012 FIXME("(%p): semi-stub\n", This);
2013 switch(V_VT(&var1))
2015 case VT_UNKNOWN:
2016 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2017 break;
2019 case VT_DISPATCH:
2020 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2021 break;
2023 case VT_NULL:
2024 case VT_EMPTY:
2025 hr = S_OK;
2026 break;
2028 default:
2029 WARN("Can't get schema from vt %x\n", V_VT(&var1));
2032 if(SUCCEEDED(hr))
2034 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
2035 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
2038 return hr;
2041 static HRESULT WINAPI domdoc_validate(
2042 IXMLDOMDocument3* iface,
2043 IXMLDOMParseError** err)
2045 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2046 FIXME("(%p)->(%p)\n", This, err);
2047 return E_NOTIMPL;
2050 static HRESULT WINAPI domdoc_setProperty(
2051 IXMLDOMDocument3* iface,
2052 BSTR p,
2053 VARIANT var)
2055 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2057 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
2059 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2061 VARIANT varStr;
2062 HRESULT hr;
2063 BSTR bstr;
2065 V_VT(&varStr) = VT_EMPTY;
2066 if (V_VT(&var) != VT_BSTR)
2068 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2069 return hr;
2070 bstr = V_BSTR(&varStr);
2072 else
2073 bstr = V_BSTR(&var);
2075 hr = S_OK;
2076 if (lstrcmpiW(bstr, PropValueXPathW) == 0)
2077 This->bUseXPath = TRUE;
2078 else if (lstrcmpiW(bstr, PropValueXSLPatternW) == 0)
2079 This->bUseXPath = FALSE;
2080 else
2081 hr = E_FAIL;
2083 VariantClear(&varStr);
2084 return hr;
2086 else if (lstrcmpiW(p, PropertyProhibitDTDW) == 0)
2088 /* Ignore */
2089 FIXME("Ignoring property ProhibitDTD, value %d\n", V_BOOL(&var));
2090 return S_OK;
2092 else if (lstrcmpiW(p, PropertySelectionNamespacesW) == 0)
2094 if (V_VT(&var) == VT_BSTR)
2095 FIXME("Unsupported SelectionNamespaces: %s\n", wine_dbgstr_w(V_BSTR(&var)));
2096 return E_FAIL;
2099 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2100 return E_FAIL;
2103 static HRESULT WINAPI domdoc_getProperty(
2104 IXMLDOMDocument3* iface,
2105 BSTR p,
2106 VARIANT* var)
2108 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2110 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2112 if (var == NULL)
2113 return E_INVALIDARG;
2115 if (lstrcmpiW(p, PropertySelectionLanguageW) == 0)
2117 V_VT(var) = VT_BSTR;
2118 if (This->bUseXPath)
2119 V_BSTR(var) = SysAllocString(PropValueXPathW);
2120 else
2121 V_BSTR(var) = SysAllocString(PropValueXSLPatternW);
2122 return S_OK;
2125 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2126 return E_FAIL;
2129 static HRESULT WINAPI domdoc_validateNode(
2130 IXMLDOMDocument3* iface,
2131 IXMLDOMNode* node,
2132 IXMLDOMParseError** error)
2134 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2135 FIXME("(%p)->(%p %p): stub\n", This, node, error);
2136 return E_NOTIMPL;
2139 static HRESULT WINAPI domdoc_importNode(
2140 IXMLDOMDocument3* iface,
2141 IXMLDOMNode* node,
2142 VARIANT_BOOL deep,
2143 IXMLDOMNode** clone)
2145 domdoc *This = impl_from_IXMLDOMDocument3( iface );
2146 FIXME("(%p)->(%p %d %p): stub\n", This, node, deep, clone);
2147 return E_NOTIMPL;
2150 static const struct IXMLDOMDocument3Vtbl domdoc_vtbl =
2152 domdoc_QueryInterface,
2153 domdoc_AddRef,
2154 domdoc_Release,
2155 domdoc_GetTypeInfoCount,
2156 domdoc_GetTypeInfo,
2157 domdoc_GetIDsOfNames,
2158 domdoc_Invoke,
2159 domdoc_get_nodeName,
2160 domdoc_get_nodeValue,
2161 domdoc_put_nodeValue,
2162 domdoc_get_nodeType,
2163 domdoc_get_parentNode,
2164 domdoc_get_childNodes,
2165 domdoc_get_firstChild,
2166 domdoc_get_lastChild,
2167 domdoc_get_previousSibling,
2168 domdoc_get_nextSibling,
2169 domdoc_get_attributes,
2170 domdoc_insertBefore,
2171 domdoc_replaceChild,
2172 domdoc_removeChild,
2173 domdoc_appendChild,
2174 domdoc_hasChildNodes,
2175 domdoc_get_ownerDocument,
2176 domdoc_cloneNode,
2177 domdoc_get_nodeTypeString,
2178 domdoc_get_text,
2179 domdoc_put_text,
2180 domdoc_get_specified,
2181 domdoc_get_definition,
2182 domdoc_get_nodeTypedValue,
2183 domdoc_put_nodeTypedValue,
2184 domdoc_get_dataType,
2185 domdoc_put_dataType,
2186 domdoc_get_xml,
2187 domdoc_transformNode,
2188 domdoc_selectNodes,
2189 domdoc_selectSingleNode,
2190 domdoc_get_parsed,
2191 domdoc_get_namespaceURI,
2192 domdoc_get_prefix,
2193 domdoc_get_baseName,
2194 domdoc_transformNodeToObject,
2195 domdoc_get_doctype,
2196 domdoc_get_implementation,
2197 domdoc_get_documentElement,
2198 domdoc_put_documentElement,
2199 domdoc_createElement,
2200 domdoc_createDocumentFragment,
2201 domdoc_createTextNode,
2202 domdoc_createComment,
2203 domdoc_createCDATASection,
2204 domdoc_createProcessingInstruction,
2205 domdoc_createAttribute,
2206 domdoc_createEntityReference,
2207 domdoc_getElementsByTagName,
2208 domdoc_createNode,
2209 domdoc_nodeFromID,
2210 domdoc_load,
2211 domdoc_get_readyState,
2212 domdoc_get_parseError,
2213 domdoc_get_url,
2214 domdoc_get_async,
2215 domdoc_put_async,
2216 domdoc_abort,
2217 domdoc_loadXML,
2218 domdoc_save,
2219 domdoc_get_validateOnParse,
2220 domdoc_put_validateOnParse,
2221 domdoc_get_resolveExternals,
2222 domdoc_put_resolveExternals,
2223 domdoc_get_preserveWhiteSpace,
2224 domdoc_put_preserveWhiteSpace,
2225 domdoc_put_onReadyStateChange,
2226 domdoc_put_onDataAvailable,
2227 domdoc_put_onTransformNode,
2228 domdoc_get_namespaces,
2229 domdoc_get_schemas,
2230 domdoc_putref_schemas,
2231 domdoc_validate,
2232 domdoc_setProperty,
2233 domdoc_getProperty,
2234 domdoc_validateNode,
2235 domdoc_importNode
2238 /* xmldoc implementation of IObjectWithSite */
2239 static HRESULT WINAPI
2240 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2242 domdoc *This = impl_from_IObjectWithSite(iface);
2243 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2246 static ULONG WINAPI
2247 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2249 domdoc *This = impl_from_IObjectWithSite(iface);
2250 return IXMLDocument_AddRef((IXMLDocument *)This);
2253 static ULONG WINAPI
2254 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2256 domdoc *This = impl_from_IObjectWithSite(iface);
2257 return IXMLDocument_Release((IXMLDocument *)This);
2260 static HRESULT WINAPI
2261 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2263 domdoc *This = impl_from_IObjectWithSite(iface);
2265 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2267 if ( !This->site )
2268 return E_FAIL;
2270 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2273 static HRESULT WINAPI
2274 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2276 domdoc *This = impl_from_IObjectWithSite(iface);
2278 TRACE("(%p)->(%p)\n", iface, punk);
2280 if(!punk)
2282 if(This->site)
2284 IUnknown_Release( This->site );
2285 This->site = NULL;
2288 return S_OK;
2291 IUnknown_AddRef( punk );
2293 if(This->site)
2294 IUnknown_Release( This->site );
2296 This->site = punk;
2298 return S_OK;
2301 static const IObjectWithSiteVtbl domdocObjectSite =
2303 xmldoc_ObjectWithSite_QueryInterface,
2304 xmldoc_ObjectWithSite_AddRef,
2305 xmldoc_ObjectWithSite_Release,
2306 xmldoc_SetSite,
2307 xmldoc_GetSite,
2310 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2312 domdoc *This = impl_from_IObjectSafety(iface);
2313 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2316 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2318 domdoc *This = impl_from_IObjectSafety(iface);
2319 return IXMLDocument_AddRef((IXMLDocument *)This);
2322 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2324 domdoc *This = impl_from_IObjectSafety(iface);
2325 return IXMLDocument_Release((IXMLDocument *)This);
2328 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2330 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2331 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2333 domdoc *This = impl_from_IObjectSafety(iface);
2335 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2337 if(!pdwSupportedOptions || !pdwEnabledOptions)
2338 return E_POINTER;
2340 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2341 *pdwEnabledOptions = This->safeopt;
2343 return S_OK;
2346 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2347 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2349 domdoc *This = impl_from_IObjectSafety(iface);
2350 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2352 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2353 return E_FAIL;
2355 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2356 return S_OK;
2359 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2360 xmldoc_Safety_QueryInterface,
2361 xmldoc_Safety_AddRef,
2362 xmldoc_Safety_Release,
2363 xmldoc_Safety_GetInterfaceSafetyOptions,
2364 xmldoc_Safety_SetInterfaceSafetyOptions
2368 static const tid_t domdoc_iface_tids[] = {
2369 IXMLDOMNode_tid,
2370 IXMLDOMDocument_tid,
2371 IXMLDOMDocument2_tid,
2374 static dispex_static_data_t domdoc_dispex = {
2375 NULL,
2376 IXMLDOMDocument2_tid,
2377 NULL,
2378 domdoc_iface_tids
2381 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document)
2383 domdoc *doc;
2385 doc = heap_alloc( sizeof (*doc) );
2386 if( !doc )
2387 return E_OUTOFMEMORY;
2389 doc->lpVtbl = &domdoc_vtbl;
2390 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
2391 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2392 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2393 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2394 doc->ref = 1;
2395 doc->async = VARIANT_TRUE;
2396 doc->validating = 0;
2397 doc->resolving = 0;
2398 doc->preserving = 0;
2399 doc->bUseXPath = FALSE;
2400 doc->error = S_OK;
2401 doc->schema = NULL;
2402 doc->stream = NULL;
2403 doc->site = NULL;
2404 doc->safeopt = 0;
2405 doc->bsc = NULL;
2407 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2409 *document = (IXMLDOMDocument3*)&doc->lpVtbl;
2411 TRACE("returning iface %p\n", *document);
2412 return S_OK;
2415 HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj)
2417 xmlDocPtr xmldoc;
2418 HRESULT hr;
2420 TRACE("(%p, %p)\n", pUnkOuter, ppObj);
2422 xmldoc = xmlNewDoc(NULL);
2423 if(!xmldoc)
2424 return E_OUTOFMEMORY;
2426 xmldoc->_private = create_priv();
2428 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument3**)ppObj);
2429 if(FAILED(hr))
2430 xmlFreeDoc(xmldoc);
2432 return hr;
2435 IUnknown* create_domdoc( xmlNodePtr document )
2437 void* pObj = NULL;
2438 HRESULT hr;
2440 TRACE("(%p)\n", document);
2442 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj);
2443 if (FAILED(hr))
2444 return NULL;
2446 return pObj;
2449 #else
2451 HRESULT DOMDocument_create(IUnknown *pUnkOuter, void **ppObj)
2453 MESSAGE("This program tried to use a DOMDocument object, but\n"
2454 "libxml2 support was not present at compile time.\n");
2455 return E_NOTIMPL;
2458 #endif