configure: Print a warning when prelink isn't found.
[wine/hramrach.git] / dlls / msxml3 / domdoc.c
blobaff5b74d3a6980aa1d124c849ce176127e1e5050
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 "msxml2.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 SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
62 static const WCHAR SZ_PROPERTY_PROHIBIT_DTD[] = {'P','r','o','h','i','b','i','t','D','T','D',0};
63 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
64 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
66 typedef struct _domdoc
68 xmlnode node;
69 const struct IXMLDOMDocument2Vtbl *lpVtbl;
70 const struct IPersistStreamInitVtbl *lpvtblIPersistStreamInit;
71 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
72 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
73 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
74 LONG ref;
75 VARIANT_BOOL async;
76 VARIANT_BOOL validating;
77 VARIANT_BOOL resolving;
78 VARIANT_BOOL preserving;
79 BOOL bUseXPath;
80 IXMLDOMSchemaCollection *schema;
81 bsc_t *bsc;
82 HRESULT error;
84 /* IPersistStream */
85 IStream *stream;
87 /* IObjectWithSite*/
88 IUnknown *site;
90 /* IObjectSafety */
91 DWORD safeopt;
92 } domdoc;
95 In native windows, the whole lifetime management of XMLDOMNodes is
96 managed automatically using reference counts. Wine emulates that by
97 maintaining a reference count to the document that is increased for
98 each IXMLDOMNode pointer passed out for this document. If all these
99 pointers are gone, the document is unreachable and gets freed, that
100 is, all nodes in the tree of the document get freed.
102 You are able to create nodes that are associated to a document (in
103 fact, in msxml's XMLDOM model, all nodes are associated to a document),
104 but not in the tree of that document, for example using the createFoo
105 functions from IXMLDOMDocument. These nodes do not get cleaned up
106 by libxml, so we have to do it ourselves.
108 To catch these nodes, a list of "orphan nodes" is introduced.
109 It contains pointers to all roots of node trees that are
110 associated with the document without being part of the document
111 tree. All nodes with parent==NULL (except for the document root nodes)
112 should be in the orphan node list of their document. All orphan nodes
113 get freed together with the document itself.
116 typedef struct _xmldoc_priv {
117 LONG refs;
118 struct list orphans;
119 } xmldoc_priv;
121 typedef struct _orphan_entry {
122 struct list entry;
123 xmlNode * node;
124 } orphan_entry;
126 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
128 return doc->_private;
131 static xmldoc_priv * create_priv(void)
133 xmldoc_priv *priv;
134 priv = heap_alloc( sizeof (*priv) );
136 if(priv)
138 priv->refs = 0;
139 list_init( &priv->orphans );
142 return priv;
145 /* links a "<?xml" node as a first child */
146 void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
148 assert(doc != NULL);
149 if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
152 /* unlinks a first "<?xml" child if it was created */
153 xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
155 xmlNodePtr node;
157 assert(doc != NULL);
159 if (doc->standalone != -1)
161 node = doc->children;
162 xmlUnlinkNode( node );
164 else
165 node = NULL;
167 return node;
170 static xmlDocPtr doparse( char *ptr, int len, const char *encoding )
172 xmlDocPtr doc;
174 #ifdef HAVE_XMLREADMEMORY
176 * use xmlReadMemory if possible so we can suppress
177 * writing errors to stderr
179 doc = xmlReadMemory( ptr, len, NULL, encoding,
180 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
181 #else
182 doc = xmlParseMemory( ptr, len );
183 #endif
185 /* create first child as a <?xml...?> */
186 if (doc && doc->standalone != -1)
188 xmlNodePtr node;
189 char buff[30];
190 xmlChar *xmlbuff = (xmlChar*)buff;
192 node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL );
194 /* version attribute can't be omitted */
195 sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0");
196 xmlNodeAddContent( node, xmlbuff );
198 if (doc->encoding)
200 sprintf(buff, " encoding=\"%s\"", doc->encoding);
201 xmlNodeAddContent( node, xmlbuff );
204 if (doc->standalone != -2)
206 sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes");
207 xmlNodeAddContent( node, xmlbuff );
210 xmldoc_link_xmldecl( doc, node );
213 return doc;
216 LONG xmldoc_add_ref(xmlDocPtr doc)
218 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
219 TRACE("(%p)->(%d)\n", doc, ref);
220 return ref;
223 LONG xmldoc_release(xmlDocPtr doc)
225 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
226 LONG ref = InterlockedDecrement(&priv->refs);
227 TRACE("(%p)->(%d)\n", doc, ref);
228 if(ref == 0)
230 orphan_entry *orphan, *orphan2;
231 TRACE("freeing docptr %p\n", doc);
233 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
235 xmlFreeNode( orphan->node );
236 heap_free( orphan );
238 heap_free(doc->_private);
240 xmlFreeDoc(doc);
243 return ref;
246 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
248 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
249 orphan_entry *entry;
251 entry = heap_alloc( sizeof (*entry) );
252 if(!entry)
253 return E_OUTOFMEMORY;
255 entry->node = node;
256 list_add_head( &priv->orphans, &entry->entry );
257 return S_OK;
260 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
262 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
263 orphan_entry *entry, *entry2;
265 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
267 if( entry->node == node )
269 list_remove( &entry->entry );
270 heap_free( entry );
271 return S_OK;
275 return S_FALSE;
278 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
280 if(node->node)
281 xmldoc_release(node->node->doc);
283 node->node = (xmlNodePtr) xml;
284 if(node->node)
285 xmldoc_add_ref(node->node->doc);
287 return S_OK;
290 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
292 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
295 static inline xmlDocPtr get_doc( domdoc *This )
297 return (xmlDocPtr)This->node.node;
300 static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
302 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStreamInit));
305 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
307 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
310 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
312 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
315 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
317 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
320 /************************************************************************
321 * domdoc implementation of IPersistStream.
323 static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
324 IPersistStreamInit *iface, REFIID riid, void **ppvObj)
326 domdoc *this = impl_from_IPersistStreamInit(iface);
327 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
330 static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
331 IPersistStreamInit *iface)
333 domdoc *this = impl_from_IPersistStreamInit(iface);
334 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
337 static ULONG WINAPI domdoc_IPersistStreamInit_Release(
338 IPersistStreamInit *iface)
340 domdoc *this = impl_from_IPersistStreamInit(iface);
341 return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
344 static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
345 IPersistStreamInit *iface, CLSID *classid)
347 TRACE("(%p,%p): stub!\n", iface, classid);
349 if(!classid)
350 return E_POINTER;
352 *classid = CLSID_DOMDocument2;
354 return S_OK;
357 static HRESULT WINAPI domdoc_IPersistStreamInit_IsDirty(
358 IPersistStreamInit *iface)
360 domdoc *This = impl_from_IPersistStreamInit(iface);
361 FIXME("(%p): stub!\n", This);
362 return S_FALSE;
365 static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
366 IPersistStreamInit *iface, LPSTREAM pStm)
368 domdoc *This = impl_from_IPersistStreamInit(iface);
369 HRESULT hr;
370 HGLOBAL hglobal;
371 DWORD read, written, len;
372 BYTE buf[4096];
373 char *ptr;
374 xmlDocPtr xmldoc = NULL;
376 TRACE("(%p)->(%p)\n", This, pStm);
378 if (!pStm)
379 return E_INVALIDARG;
381 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
382 if (FAILED(hr))
383 return hr;
387 IStream_Read(pStm, buf, sizeof(buf), &read);
388 hr = IStream_Write(This->stream, buf, read, &written);
389 } while(SUCCEEDED(hr) && written != 0 && read != 0);
391 if (FAILED(hr))
393 ERR("Failed to copy stream\n");
394 return hr;
397 hr = GetHGlobalFromStream(This->stream, &hglobal);
398 if (FAILED(hr))
399 return hr;
401 len = GlobalSize(hglobal);
402 ptr = GlobalLock(hglobal);
403 if (len != 0)
404 xmldoc = doparse(ptr, len, NULL);
405 GlobalUnlock(hglobal);
407 if (!xmldoc)
409 ERR("Failed to parse xml\n");
410 return E_FAIL;
413 xmldoc->_private = create_priv();
415 return attach_xmldoc( &This->node, xmldoc );
418 static HRESULT WINAPI domdoc_IPersistStreamInit_Save(
419 IPersistStreamInit *iface, IStream *stream, BOOL clr_dirty)
421 domdoc *This = impl_from_IPersistStreamInit(iface);
422 BSTR xmlString;
423 HRESULT hr;
425 TRACE("(%p)->(%p %d)\n", This, stream, clr_dirty);
427 hr = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), &xmlString );
428 if(hr == S_OK)
430 DWORD len = SysStringLen(xmlString) * sizeof(WCHAR);
432 hr = IStream_Write( stream, xmlString, len, NULL );
433 SysFreeString(xmlString);
436 TRACE("ret 0x%08x\n", hr);
438 return hr;
441 static HRESULT WINAPI domdoc_IPersistStreamInit_GetSizeMax(
442 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
444 domdoc *This = impl_from_IPersistStreamInit(iface);
445 TRACE("(%p)->(%p): stub!\n", This, pcbSize);
446 return E_NOTIMPL;
449 static HRESULT WINAPI domdoc_IPersistStreamInit_InitNew(
450 IPersistStreamInit *iface)
452 domdoc *This = impl_from_IPersistStreamInit(iface);
453 TRACE("(%p)\n", This);
454 return S_OK;
457 static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
459 domdoc_IPersistStreamInit_QueryInterface,
460 domdoc_IPersistStreamInit_AddRef,
461 domdoc_IPersistStreamInit_Release,
462 domdoc_IPersistStreamInit_GetClassID,
463 domdoc_IPersistStreamInit_IsDirty,
464 domdoc_IPersistStreamInit_Load,
465 domdoc_IPersistStreamInit_Save,
466 domdoc_IPersistStreamInit_GetSizeMax,
467 domdoc_IPersistStreamInit_InitNew
470 /* ISupportErrorInfo interface */
471 static HRESULT WINAPI support_error_QueryInterface(
472 ISupportErrorInfo *iface,
473 REFIID riid, void** ppvObj )
475 domdoc *This = impl_from_ISupportErrorInfo(iface);
476 return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)This, riid, ppvObj);
479 static ULONG WINAPI support_error_AddRef(
480 ISupportErrorInfo *iface )
482 domdoc *This = impl_from_ISupportErrorInfo(iface);
483 return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)This);
486 static ULONG WINAPI support_error_Release(
487 ISupportErrorInfo *iface )
489 domdoc *This = impl_from_ISupportErrorInfo(iface);
490 return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)This);
493 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
494 ISupportErrorInfo *iface,
495 REFIID riid )
497 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
498 return S_FALSE;
501 static const struct ISupportErrorInfoVtbl support_error_vtbl =
503 support_error_QueryInterface,
504 support_error_AddRef,
505 support_error_Release,
506 support_error_InterfaceSupportsErrorInfo
509 /* IXMLDOMDocument2 interface */
510 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
512 domdoc *This = impl_from_IXMLDOMDocument2( iface );
514 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( riid ), ppvObject );
516 *ppvObject = NULL;
518 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
519 IsEqualGUID( riid, &IID_IDispatch ) ||
520 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
521 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
523 *ppvObject = iface;
525 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
527 *ppvObject = IXMLDOMNode_from_impl(&This->node);
529 else if (IsEqualGUID(&IID_IPersistStream, riid) ||
530 IsEqualGUID(&IID_IPersistStreamInit, riid))
532 *ppvObject = &(This->lpvtblIPersistStreamInit);
534 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
536 *ppvObject = &(This->lpvtblIObjectWithSite);
538 else if (IsEqualGUID(&IID_IObjectSafety, riid))
540 *ppvObject = &(This->lpvtblIObjectSafety);
542 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
544 *ppvObject = &This->lpvtblISupportErrorInfo;
546 else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
548 return *ppvObject ? S_OK : E_NOINTERFACE;
550 else if(IsEqualGUID(&IID_IRunnableObject, riid))
552 TRACE("IID_IRunnableObject not supported returning NULL\n");
553 return E_NOINTERFACE;
555 else
557 FIXME("interface %s not implemented\n", debugstr_guid(riid));
558 return E_NOINTERFACE;
561 IUnknown_AddRef((IUnknown*)*ppvObject);
563 return S_OK;
567 static ULONG WINAPI domdoc_AddRef(
568 IXMLDOMDocument2 *iface )
570 domdoc *This = impl_from_IXMLDOMDocument2( iface );
571 TRACE("%p\n", This );
572 return InterlockedIncrement( &This->ref );
576 static ULONG WINAPI domdoc_Release(
577 IXMLDOMDocument2 *iface )
579 domdoc *This = impl_from_IXMLDOMDocument2( iface );
580 LONG ref;
582 TRACE("%p\n", This );
584 ref = InterlockedDecrement( &This->ref );
585 if ( ref == 0 )
587 if(This->bsc)
588 detach_bsc(This->bsc);
590 if (This->site)
591 IUnknown_Release( This->site );
592 destroy_xmlnode(&This->node);
593 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
594 if (This->stream) IStream_Release(This->stream);
595 HeapFree( GetProcessHeap(), 0, This );
598 return ref;
601 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
603 domdoc *This = impl_from_IXMLDOMDocument2( iface );
605 TRACE("(%p)->(%p)\n", This, pctinfo);
607 *pctinfo = 1;
609 return S_OK;
612 static HRESULT WINAPI domdoc_GetTypeInfo(
613 IXMLDOMDocument2 *iface,
614 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
616 domdoc *This = impl_from_IXMLDOMDocument2( iface );
617 HRESULT hr;
619 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
621 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
623 return hr;
626 static HRESULT WINAPI domdoc_GetIDsOfNames(
627 IXMLDOMDocument2 *iface,
628 REFIID riid,
629 LPOLESTR* rgszNames,
630 UINT cNames,
631 LCID lcid,
632 DISPID* rgDispId)
634 domdoc *This = impl_from_IXMLDOMDocument2( iface );
635 ITypeInfo *typeinfo;
636 HRESULT hr;
638 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
639 lcid, rgDispId);
641 if(!rgszNames || cNames == 0 || !rgDispId)
642 return E_INVALIDARG;
644 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
645 if(SUCCEEDED(hr))
647 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
648 ITypeInfo_Release(typeinfo);
651 return hr;
655 static HRESULT WINAPI domdoc_Invoke(
656 IXMLDOMDocument2 *iface,
657 DISPID dispIdMember,
658 REFIID riid,
659 LCID lcid,
660 WORD wFlags,
661 DISPPARAMS* pDispParams,
662 VARIANT* pVarResult,
663 EXCEPINFO* pExcepInfo,
664 UINT* puArgErr)
666 domdoc *This = impl_from_IXMLDOMDocument2( iface );
667 ITypeInfo *typeinfo;
668 HRESULT hr;
670 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
671 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
673 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
674 if(SUCCEEDED(hr))
676 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
677 pVarResult, pExcepInfo, puArgErr);
678 ITypeInfo_Release(typeinfo);
681 return hr;
685 static HRESULT WINAPI domdoc_get_nodeName(
686 IXMLDOMDocument2 *iface,
687 BSTR* name )
689 domdoc *This = impl_from_IXMLDOMDocument2( iface );
690 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
694 static HRESULT WINAPI domdoc_get_nodeValue(
695 IXMLDOMDocument2 *iface,
696 VARIANT* value )
698 domdoc *This = impl_from_IXMLDOMDocument2( iface );
699 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
703 static HRESULT WINAPI domdoc_put_nodeValue(
704 IXMLDOMDocument2 *iface,
705 VARIANT value)
707 domdoc *This = impl_from_IXMLDOMDocument2( iface );
708 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
712 static HRESULT WINAPI domdoc_get_nodeType(
713 IXMLDOMDocument2 *iface,
714 DOMNodeType* type )
716 domdoc *This = impl_from_IXMLDOMDocument2( iface );
717 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
721 static HRESULT WINAPI domdoc_get_parentNode(
722 IXMLDOMDocument2 *iface,
723 IXMLDOMNode** parent )
725 domdoc *This = impl_from_IXMLDOMDocument2( iface );
726 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
730 static HRESULT WINAPI domdoc_get_childNodes(
731 IXMLDOMDocument2 *iface,
732 IXMLDOMNodeList** childList )
734 domdoc *This = impl_from_IXMLDOMDocument2( iface );
735 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
739 static HRESULT WINAPI domdoc_get_firstChild(
740 IXMLDOMDocument2 *iface,
741 IXMLDOMNode** firstChild )
743 domdoc *This = impl_from_IXMLDOMDocument2( iface );
744 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
748 static HRESULT WINAPI domdoc_get_lastChild(
749 IXMLDOMDocument2 *iface,
750 IXMLDOMNode** lastChild )
752 domdoc *This = impl_from_IXMLDOMDocument2( iface );
753 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
757 static HRESULT WINAPI domdoc_get_previousSibling(
758 IXMLDOMDocument2 *iface,
759 IXMLDOMNode** previousSibling )
761 domdoc *This = impl_from_IXMLDOMDocument2( iface );
762 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
766 static HRESULT WINAPI domdoc_get_nextSibling(
767 IXMLDOMDocument2 *iface,
768 IXMLDOMNode** nextSibling )
770 domdoc *This = impl_from_IXMLDOMDocument2( iface );
771 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
775 static HRESULT WINAPI domdoc_get_attributes(
776 IXMLDOMDocument2 *iface,
777 IXMLDOMNamedNodeMap** attributeMap )
779 domdoc *This = impl_from_IXMLDOMDocument2( iface );
780 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
784 static HRESULT WINAPI domdoc_insertBefore(
785 IXMLDOMDocument2 *iface,
786 IXMLDOMNode* newChild,
787 VARIANT refChild,
788 IXMLDOMNode** outNewChild )
790 domdoc *This = impl_from_IXMLDOMDocument2( iface );
791 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
795 static HRESULT WINAPI domdoc_replaceChild(
796 IXMLDOMDocument2 *iface,
797 IXMLDOMNode* newChild,
798 IXMLDOMNode* oldChild,
799 IXMLDOMNode** outOldChild)
801 domdoc *This = impl_from_IXMLDOMDocument2( iface );
802 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
806 static HRESULT WINAPI domdoc_removeChild(
807 IXMLDOMDocument2 *iface,
808 IXMLDOMNode* childNode,
809 IXMLDOMNode** oldChild)
811 domdoc *This = impl_from_IXMLDOMDocument2( iface );
812 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
816 static HRESULT WINAPI domdoc_appendChild(
817 IXMLDOMDocument2 *iface,
818 IXMLDOMNode* newChild,
819 IXMLDOMNode** outNewChild)
821 domdoc *This = impl_from_IXMLDOMDocument2( iface );
822 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
826 static HRESULT WINAPI domdoc_hasChildNodes(
827 IXMLDOMDocument2 *iface,
828 VARIANT_BOOL* hasChild)
830 domdoc *This = impl_from_IXMLDOMDocument2( iface );
831 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
835 static HRESULT WINAPI domdoc_get_ownerDocument(
836 IXMLDOMDocument2 *iface,
837 IXMLDOMDocument** DOMDocument)
839 domdoc *This = impl_from_IXMLDOMDocument2( iface );
840 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
844 static HRESULT WINAPI domdoc_cloneNode(
845 IXMLDOMDocument2 *iface,
846 VARIANT_BOOL deep,
847 IXMLDOMNode** cloneRoot)
849 domdoc *This = impl_from_IXMLDOMDocument2( iface );
850 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
854 static HRESULT WINAPI domdoc_get_nodeTypeString(
855 IXMLDOMDocument2 *iface,
856 BSTR* nodeType )
858 domdoc *This = impl_from_IXMLDOMDocument2( iface );
859 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
863 static HRESULT WINAPI domdoc_get_text(
864 IXMLDOMDocument2 *iface,
865 BSTR* text )
867 domdoc *This = impl_from_IXMLDOMDocument2( iface );
868 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
872 static HRESULT WINAPI domdoc_put_text(
873 IXMLDOMDocument2 *iface,
874 BSTR text )
876 domdoc *This = impl_from_IXMLDOMDocument2( iface );
877 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
881 static HRESULT WINAPI domdoc_get_specified(
882 IXMLDOMDocument2 *iface,
883 VARIANT_BOOL* isSpecified )
885 domdoc *This = impl_from_IXMLDOMDocument2( iface );
886 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
890 static HRESULT WINAPI domdoc_get_definition(
891 IXMLDOMDocument2 *iface,
892 IXMLDOMNode** definitionNode )
894 domdoc *This = impl_from_IXMLDOMDocument2( iface );
895 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
899 static HRESULT WINAPI domdoc_get_nodeTypedValue(
900 IXMLDOMDocument2 *iface,
901 VARIANT* typedValue )
903 domdoc *This = impl_from_IXMLDOMDocument2( iface );
904 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
907 static HRESULT WINAPI domdoc_put_nodeTypedValue(
908 IXMLDOMDocument2 *iface,
909 VARIANT typedValue )
911 domdoc *This = impl_from_IXMLDOMDocument2( iface );
912 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
916 static HRESULT WINAPI domdoc_get_dataType(
917 IXMLDOMDocument2 *iface,
918 VARIANT* dataTypeName )
920 domdoc *This = impl_from_IXMLDOMDocument2( iface );
921 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
925 static HRESULT WINAPI domdoc_put_dataType(
926 IXMLDOMDocument2 *iface,
927 BSTR dataTypeName )
929 domdoc *This = impl_from_IXMLDOMDocument2( iface );
930 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
934 static HRESULT WINAPI domdoc_get_xml(
935 IXMLDOMDocument2 *iface,
936 BSTR* xmlString )
938 domdoc *This = impl_from_IXMLDOMDocument2( iface );
939 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
943 static HRESULT WINAPI domdoc_transformNode(
944 IXMLDOMDocument2 *iface,
945 IXMLDOMNode* styleSheet,
946 BSTR* xmlString )
948 domdoc *This = impl_from_IXMLDOMDocument2( iface );
949 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
953 static HRESULT WINAPI domdoc_selectNodes(
954 IXMLDOMDocument2 *iface,
955 BSTR queryString,
956 IXMLDOMNodeList** resultList )
958 domdoc *This = impl_from_IXMLDOMDocument2( iface );
959 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
963 static HRESULT WINAPI domdoc_selectSingleNode(
964 IXMLDOMDocument2 *iface,
965 BSTR queryString,
966 IXMLDOMNode** resultNode )
968 domdoc *This = impl_from_IXMLDOMDocument2( iface );
969 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
973 static HRESULT WINAPI domdoc_get_parsed(
974 IXMLDOMDocument2 *iface,
975 VARIANT_BOOL* isParsed )
977 domdoc *This = impl_from_IXMLDOMDocument2( iface );
978 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
982 static HRESULT WINAPI domdoc_get_namespaceURI(
983 IXMLDOMDocument2 *iface,
984 BSTR* namespaceURI )
986 domdoc *This = impl_from_IXMLDOMDocument2( iface );
987 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
991 static HRESULT WINAPI domdoc_get_prefix(
992 IXMLDOMDocument2 *iface,
993 BSTR* prefixString )
995 domdoc *This = impl_from_IXMLDOMDocument2( iface );
996 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
1000 static HRESULT WINAPI domdoc_get_baseName(
1001 IXMLDOMDocument2 *iface,
1002 BSTR* nameString )
1004 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1005 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
1009 static HRESULT WINAPI domdoc_transformNodeToObject(
1010 IXMLDOMDocument2 *iface,
1011 IXMLDOMNode* stylesheet,
1012 VARIANT outputObject)
1014 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1015 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
1019 static HRESULT WINAPI domdoc_get_doctype(
1020 IXMLDOMDocument2 *iface,
1021 IXMLDOMDocumentType** documentType )
1023 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1024 FIXME("(%p)\n", This);
1025 return E_NOTIMPL;
1029 static HRESULT WINAPI domdoc_get_implementation(
1030 IXMLDOMDocument2 *iface,
1031 IXMLDOMImplementation** impl )
1033 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1035 TRACE("(%p)->(%p)\n", This, impl);
1037 if(!impl)
1038 return E_INVALIDARG;
1040 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
1042 return S_OK;
1045 static HRESULT WINAPI domdoc_get_documentElement(
1046 IXMLDOMDocument2 *iface,
1047 IXMLDOMElement** DOMElement )
1049 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1050 xmlDocPtr xmldoc = NULL;
1051 xmlNodePtr root = NULL;
1052 IXMLDOMNode *element_node;
1053 HRESULT hr;
1055 TRACE("(%p)->(%p)\n", This, DOMElement);
1057 if(!DOMElement)
1058 return E_INVALIDARG;
1060 *DOMElement = NULL;
1062 xmldoc = get_doc( This );
1064 root = xmlDocGetRootElement( xmldoc );
1065 if ( !root )
1066 return S_FALSE;
1068 element_node = create_node( root );
1069 if(!element_node) return S_FALSE;
1071 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
1072 IXMLDOMNode_Release(element_node);
1074 return hr;
1078 static HRESULT WINAPI domdoc_put_documentElement(
1079 IXMLDOMDocument2 *iface,
1080 IXMLDOMElement* DOMElement )
1082 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1083 IXMLDOMNode *elementNode;
1084 xmlNodePtr oldRoot;
1085 xmlnode *xmlNode;
1086 HRESULT hr;
1088 TRACE("(%p)->(%p)\n", This, DOMElement);
1090 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1091 if(FAILED(hr))
1092 return hr;
1094 xmlNode = impl_from_IXMLDOMNode( elementNode );
1096 if(!xmlNode->node->parent)
1097 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1098 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1100 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1101 IXMLDOMNode_Release( elementNode );
1103 if(oldRoot)
1104 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1106 return S_OK;
1110 static HRESULT WINAPI domdoc_createElement(
1111 IXMLDOMDocument2 *iface,
1112 BSTR tagname,
1113 IXMLDOMElement** element )
1115 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1116 IXMLDOMNode *node;
1117 VARIANT type;
1118 HRESULT hr;
1120 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagname), element);
1122 if (!element || !tagname) return E_INVALIDARG;
1124 V_VT(&type) = VT_I1;
1125 V_I1(&type) = NODE_ELEMENT;
1127 hr = IXMLDOMDocument2_createNode(iface, type, tagname, NULL, &node);
1128 if (hr == S_OK)
1130 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1131 IXMLDOMNode_Release(node);
1134 return hr;
1138 static HRESULT WINAPI domdoc_createDocumentFragment(
1139 IXMLDOMDocument2 *iface,
1140 IXMLDOMDocumentFragment** frag )
1142 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1143 IXMLDOMNode *node;
1144 VARIANT type;
1145 HRESULT hr;
1147 TRACE("(%p)->(%p)\n", This, frag);
1149 if (!frag) return E_INVALIDARG;
1151 *frag = NULL;
1153 V_VT(&type) = VT_I1;
1154 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1156 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1157 if (hr == S_OK)
1159 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1160 IXMLDOMNode_Release(node);
1163 return hr;
1167 static HRESULT WINAPI domdoc_createTextNode(
1168 IXMLDOMDocument2 *iface,
1169 BSTR data,
1170 IXMLDOMText** text )
1172 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1173 IXMLDOMNode *node;
1174 VARIANT type;
1175 HRESULT hr;
1177 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), text);
1179 if (!text) return E_INVALIDARG;
1181 *text = NULL;
1183 V_VT(&type) = VT_I1;
1184 V_I1(&type) = NODE_TEXT;
1186 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1187 if (hr == S_OK)
1189 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1190 IXMLDOMNode_Release(node);
1191 hr = IXMLDOMText_put_data(*text, data);
1194 return hr;
1198 static HRESULT WINAPI domdoc_createComment(
1199 IXMLDOMDocument2 *iface,
1200 BSTR data,
1201 IXMLDOMComment** comment )
1203 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1204 VARIANT type;
1205 HRESULT hr;
1206 IXMLDOMNode *node;
1208 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), comment);
1210 if (!comment) return E_INVALIDARG;
1212 *comment = NULL;
1214 V_VT(&type) = VT_I1;
1215 V_I1(&type) = NODE_COMMENT;
1217 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1218 if (hr == S_OK)
1220 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1221 IXMLDOMNode_Release(node);
1222 hr = IXMLDOMComment_put_data(*comment, data);
1225 return hr;
1229 static HRESULT WINAPI domdoc_createCDATASection(
1230 IXMLDOMDocument2 *iface,
1231 BSTR data,
1232 IXMLDOMCDATASection** cdata )
1234 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1235 IXMLDOMNode *node;
1236 VARIANT type;
1237 HRESULT hr;
1239 TRACE("(%p)->(%s %p)\n", This, debugstr_w(data), cdata);
1241 if (!cdata) return E_INVALIDARG;
1243 *cdata = NULL;
1245 V_VT(&type) = VT_I1;
1246 V_I1(&type) = NODE_CDATA_SECTION;
1248 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1249 if (hr == S_OK)
1251 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1252 IXMLDOMNode_Release(node);
1253 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1256 return hr;
1260 static HRESULT WINAPI domdoc_createProcessingInstruction(
1261 IXMLDOMDocument2 *iface,
1262 BSTR target,
1263 BSTR data,
1264 IXMLDOMProcessingInstruction** pi )
1266 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1267 IXMLDOMNode *node;
1268 VARIANT type;
1269 HRESULT hr;
1271 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1273 if (!pi) return E_INVALIDARG;
1275 *pi = NULL;
1277 V_VT(&type) = VT_I1;
1278 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1280 hr = IXMLDOMDocument2_createNode(iface, type, target, NULL, &node);
1281 if (hr == S_OK)
1283 VARIANT v_data;
1285 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1286 V_VT(&v_data) = VT_BSTR;
1287 V_BSTR(&v_data) = data;
1289 hr = IXMLDOMNode_put_nodeValue( node, v_data );
1291 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1292 IXMLDOMNode_Release(node);
1295 return hr;
1299 static HRESULT WINAPI domdoc_createAttribute(
1300 IXMLDOMDocument2 *iface,
1301 BSTR name,
1302 IXMLDOMAttribute** attribute )
1304 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1305 IXMLDOMNode *node;
1306 VARIANT type;
1307 HRESULT hr;
1309 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), attribute);
1311 if (!attribute || !name) return E_INVALIDARG;
1313 V_VT(&type) = VT_I1;
1314 V_I1(&type) = NODE_ATTRIBUTE;
1316 hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
1317 if (hr == S_OK)
1319 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1320 IXMLDOMNode_Release(node);
1323 return hr;
1327 static HRESULT WINAPI domdoc_createEntityReference(
1328 IXMLDOMDocument2 *iface,
1329 BSTR name,
1330 IXMLDOMEntityReference** entityref )
1332 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1333 IXMLDOMNode *node;
1334 VARIANT type;
1335 HRESULT hr;
1337 TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), entityref);
1339 if (!entityref) return E_INVALIDARG;
1341 *entityref = NULL;
1343 V_VT(&type) = VT_I1;
1344 V_I1(&type) = NODE_ENTITY_REFERENCE;
1346 hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
1347 if (hr == S_OK)
1349 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1350 IXMLDOMNode_Release(node);
1353 return hr;
1357 static HRESULT WINAPI domdoc_getElementsByTagName(
1358 IXMLDOMDocument2 *iface,
1359 BSTR tagName,
1360 IXMLDOMNodeList** resultList )
1362 static const WCHAR xpathformat[] =
1363 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1364 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1365 LPWSTR szPattern;
1366 HRESULT hr;
1367 TRACE("(%p)->(%s %p)\n", This, debugstr_w(tagName), resultList);
1369 if (tagName[0] == '*' && tagName[1] == 0)
1371 szPattern = heap_alloc(sizeof(WCHAR)*4);
1372 szPattern[0] = szPattern[1] = '/';
1373 szPattern[2] = '*';
1374 szPattern[3] = 0;
1376 else
1378 szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1379 wsprintfW(szPattern, xpathformat, tagName);
1382 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1383 heap_free(szPattern);
1385 return hr;
1388 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1390 VARIANT tmp;
1391 HRESULT hr;
1393 VariantInit(&tmp);
1394 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1395 if(FAILED(hr))
1396 return E_INVALIDARG;
1398 *type = V_I4(&tmp);
1400 return S_OK;
1403 static HRESULT WINAPI domdoc_createNode(
1404 IXMLDOMDocument2 *iface,
1405 VARIANT Type,
1406 BSTR name,
1407 BSTR namespaceURI,
1408 IXMLDOMNode** node )
1410 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1411 DOMNodeType node_type;
1412 xmlNodePtr xmlnode;
1413 xmlChar *xml_name;
1414 HRESULT hr;
1416 TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1418 if(!node) return E_INVALIDARG;
1420 if(namespaceURI && namespaceURI[0])
1421 FIXME("nodes with namespaces currently not supported.\n");
1423 hr = get_node_type(Type, &node_type);
1424 if(FAILED(hr)) return hr;
1426 TRACE("node_type %d\n", node_type);
1428 /* exit earlier for types that need name */
1429 switch(node_type)
1431 case NODE_ELEMENT:
1432 case NODE_ATTRIBUTE:
1433 case NODE_ENTITY_REFERENCE:
1434 case NODE_PROCESSING_INSTRUCTION:
1435 if (!name || *name == 0) return E_FAIL;
1436 default:
1437 break;
1440 xml_name = xmlChar_from_wchar(name);
1442 switch(node_type)
1444 case NODE_ELEMENT:
1445 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1446 break;
1447 case NODE_ATTRIBUTE:
1448 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1449 break;
1450 case NODE_TEXT:
1451 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1452 break;
1453 case NODE_CDATA_SECTION:
1454 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1455 break;
1456 case NODE_ENTITY_REFERENCE:
1457 xmlnode = xmlNewReference(get_doc(This), xml_name);
1458 break;
1459 case NODE_PROCESSING_INSTRUCTION:
1460 #ifdef HAVE_XMLNEWDOCPI
1461 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1462 #else
1463 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1464 xmlnode = NULL;
1465 #endif
1466 break;
1467 case NODE_COMMENT:
1468 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1469 break;
1470 case NODE_DOCUMENT_FRAGMENT:
1471 xmlnode = xmlNewDocFragment(get_doc(This));
1472 break;
1473 /* unsupported types */
1474 case NODE_DOCUMENT:
1475 case NODE_DOCUMENT_TYPE:
1476 case NODE_ENTITY:
1477 case NODE_NOTATION:
1478 heap_free(xml_name);
1479 return E_INVALIDARG;
1480 default:
1481 FIXME("unhandled node type %d\n", node_type);
1482 xmlnode = NULL;
1483 break;
1486 *node = create_node(xmlnode);
1487 heap_free(xml_name);
1489 if(*node)
1491 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1492 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1493 return S_OK;
1496 return E_FAIL;
1499 static HRESULT WINAPI domdoc_nodeFromID(
1500 IXMLDOMDocument2 *iface,
1501 BSTR idString,
1502 IXMLDOMNode** node )
1504 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1505 FIXME("(%p)->(%s %p)\n", This, debugstr_w(idString), node);
1506 return E_NOTIMPL;
1509 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1511 domdoc *This = obj;
1512 xmlDocPtr xmldoc;
1514 xmldoc = doparse( ptr, len, NULL );
1515 if(xmldoc) {
1516 xmldoc->_private = create_priv();
1517 return attach_xmldoc(&This->node, xmldoc);
1520 return S_OK;
1523 static HRESULT doread( domdoc *This, LPWSTR filename )
1525 bsc_t *bsc;
1526 HRESULT hr;
1528 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1529 if(FAILED(hr))
1530 return hr;
1532 if(This->bsc)
1533 detach_bsc(This->bsc);
1535 This->bsc = bsc;
1536 return S_OK;
1539 static HRESULT WINAPI domdoc_load(
1540 IXMLDOMDocument2 *iface,
1541 VARIANT xmlSource,
1542 VARIANT_BOOL* isSuccessful )
1544 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1545 LPWSTR filename = NULL;
1546 HRESULT hr = S_FALSE;
1547 IXMLDOMDocument2 *pNewDoc = NULL;
1548 IStream *pStream = NULL;
1549 xmlDocPtr xmldoc;
1551 TRACE("(%p)->type %d\n", This, V_VT(&xmlSource) );
1553 *isSuccessful = VARIANT_FALSE;
1555 assert( &This->node );
1557 switch( V_VT(&xmlSource) )
1559 case VT_BSTR:
1560 filename = V_BSTR(&xmlSource);
1561 break;
1562 case VT_UNKNOWN:
1563 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1564 if(hr == S_OK)
1566 if(pNewDoc)
1568 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1569 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1570 hr = attach_xmldoc(&This->node, xmldoc);
1572 if(SUCCEEDED(hr))
1573 *isSuccessful = VARIANT_TRUE;
1575 return hr;
1578 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1579 if(hr == S_OK)
1581 IPersistStream *pDocStream;
1582 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1583 if(hr == S_OK)
1585 hr = IPersistStream_Load(pDocStream, pStream);
1586 IStream_Release(pStream);
1587 if(hr == S_OK)
1589 *isSuccessful = VARIANT_TRUE;
1591 TRACE("Using IStream to load Document\n");
1592 return S_OK;
1594 else
1596 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1599 else
1601 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1604 else
1606 /* ISequentialStream */
1607 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1609 break;
1610 default:
1611 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1614 TRACE("filename (%s)\n", debugstr_w(filename));
1616 if ( filename )
1618 hr = doread( This, filename );
1620 if ( FAILED(hr) )
1621 This->error = E_FAIL;
1622 else
1624 hr = This->error = S_OK;
1625 *isSuccessful = VARIANT_TRUE;
1629 if(!filename || FAILED(hr)) {
1630 xmldoc = xmlNewDoc(NULL);
1631 xmldoc->_private = create_priv();
1632 hr = attach_xmldoc(&This->node, xmldoc);
1633 if(SUCCEEDED(hr))
1634 hr = S_FALSE;
1637 TRACE("ret (%d)\n", hr);
1639 return hr;
1643 static HRESULT WINAPI domdoc_get_readyState(
1644 IXMLDOMDocument2 *iface,
1645 LONG *value )
1647 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1648 FIXME("(%p)->(%p)\n", This, value);
1649 return E_NOTIMPL;
1653 static HRESULT WINAPI domdoc_get_parseError(
1654 IXMLDOMDocument2 *iface,
1655 IXMLDOMParseError** errorObj )
1657 BSTR error_string = NULL;
1658 static const WCHAR err[] = {'e','r','r','o','r',0};
1659 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1661 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1663 if(This->error)
1664 error_string = SysAllocString(err);
1666 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1667 if(!*errorObj) return E_OUTOFMEMORY;
1668 return S_OK;
1672 static HRESULT WINAPI domdoc_get_url(
1673 IXMLDOMDocument2 *iface,
1674 BSTR* urlString )
1676 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1677 FIXME("(%p)->(%p)\n", This, urlString);
1678 return E_NOTIMPL;
1682 static HRESULT WINAPI domdoc_get_async(
1683 IXMLDOMDocument2 *iface,
1684 VARIANT_BOOL* isAsync )
1686 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1688 TRACE("(%p)->(%p: %d)\n", This, isAsync, This->async);
1689 *isAsync = This->async;
1690 return S_OK;
1694 static HRESULT WINAPI domdoc_put_async(
1695 IXMLDOMDocument2 *iface,
1696 VARIANT_BOOL isAsync )
1698 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1700 TRACE("(%p)->(%d)\n", This, isAsync);
1701 This->async = isAsync;
1702 return S_OK;
1706 static HRESULT WINAPI domdoc_abort(
1707 IXMLDOMDocument2 *iface )
1709 domdoc *This = impl_from_IXMLDOMDocument2(iface);
1710 FIXME("%p\n", This);
1711 return E_NOTIMPL;
1715 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1717 UINT len;
1718 LPSTR str;
1720 len = WideCharToMultiByte( CP_UTF8, 0, bstr, -1, NULL, 0, NULL, NULL );
1721 str = heap_alloc( len );
1722 if ( !str )
1723 return FALSE;
1724 WideCharToMultiByte( CP_UTF8, 0, bstr, -1, str, len, NULL, NULL );
1725 *plen = len;
1726 *pstr = str;
1727 return TRUE;
1730 /* don't rely on data to be in BSTR format, treat it as WCHAR string */
1731 static HRESULT WINAPI domdoc_loadXML(
1732 IXMLDOMDocument2 *iface,
1733 BSTR bstrXML,
1734 VARIANT_BOOL* isSuccessful )
1736 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1737 xmlDocPtr xmldoc = NULL;
1738 char *str;
1739 int len;
1740 HRESULT hr = S_FALSE, hr2;
1742 TRACE("(%p)->(%s %p)\n", This, debugstr_w( bstrXML ), isSuccessful );
1744 assert ( &This->node );
1746 if ( isSuccessful )
1748 *isSuccessful = VARIANT_FALSE;
1750 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1752 xmldoc = doparse( str, len, "UTF-8" );
1753 heap_free( str );
1754 if ( !xmldoc )
1755 This->error = E_FAIL;
1756 else
1758 hr = This->error = S_OK;
1759 *isSuccessful = VARIANT_TRUE;
1763 if(!xmldoc)
1764 xmldoc = xmlNewDoc(NULL);
1766 xmldoc->_private = create_priv();
1767 hr2 = attach_xmldoc( &This->node, xmldoc );
1768 if( FAILED(hr2) )
1769 hr = hr2;
1771 return hr;
1774 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1775 int len)
1777 DWORD written = -1;
1779 if(!WriteFile(ctx, buffer, len, &written, NULL))
1781 WARN("write error\n");
1782 return -1;
1784 else
1785 return written;
1788 static int XMLCALL domdoc_save_closecallback(void *ctx)
1790 return CloseHandle(ctx) ? 0 : -1;
1793 static HRESULT WINAPI domdoc_save(
1794 IXMLDOMDocument2 *iface,
1795 VARIANT destination )
1797 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1798 HANDLE handle;
1799 xmlSaveCtxtPtr ctx;
1800 xmlNodePtr xmldecl;
1801 HRESULT ret = S_OK;
1803 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1804 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1806 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1808 FIXME("Unhandled vt %d\n", V_VT(&destination));
1809 return S_FALSE;
1812 if(V_VT(&destination) == VT_UNKNOWN)
1814 IUnknown *pUnk = V_UNKNOWN(&destination);
1815 IXMLDOMDocument2 *pDocument;
1817 ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1818 if(ret == S_OK)
1820 BSTR bXML;
1821 VARIANT_BOOL bSuccessful;
1823 ret = IXMLDOMDocument2_get_xml(iface, &bXML);
1824 if(ret == S_OK)
1826 ret = IXMLDOMDocument2_loadXML(pDocument, bXML, &bSuccessful);
1828 SysFreeString(bXML);
1831 IXMLDOMDocument2_Release(pDocument);
1834 TRACE("ret %d\n", ret);
1836 return ret;
1839 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1840 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1841 if( handle == INVALID_HANDLE_VALUE )
1843 WARN("failed to create file\n");
1844 return S_FALSE;
1847 /* disable top XML declaration */
1848 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1849 handle, NULL, XML_SAVE_NO_DECL);
1850 if (!ctx)
1852 CloseHandle(handle);
1853 return S_FALSE;
1856 xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
1857 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1858 xmldoc_link_xmldecl(get_doc(This), xmldecl);
1860 /* will close file through close callback */
1861 xmlSaveClose(ctx);
1863 return ret;
1866 static HRESULT WINAPI domdoc_get_validateOnParse(
1867 IXMLDOMDocument2 *iface,
1868 VARIANT_BOOL* isValidating )
1870 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1872 TRACE("(%p)->(%p: %d)\n", This, isValidating, This->validating);
1873 *isValidating = This->validating;
1874 return S_OK;
1878 static HRESULT WINAPI domdoc_put_validateOnParse(
1879 IXMLDOMDocument2 *iface,
1880 VARIANT_BOOL isValidating )
1882 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1884 TRACE("(%p)->(%d)\n", This, isValidating);
1885 This->validating = isValidating;
1886 return S_OK;
1890 static HRESULT WINAPI domdoc_get_resolveExternals(
1891 IXMLDOMDocument2 *iface,
1892 VARIANT_BOOL* isResolving )
1894 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1896 TRACE("(%p)->(%p: %d)\n", This, isResolving, This->resolving);
1897 *isResolving = This->resolving;
1898 return S_OK;
1902 static HRESULT WINAPI domdoc_put_resolveExternals(
1903 IXMLDOMDocument2 *iface,
1904 VARIANT_BOOL isResolving )
1906 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1908 TRACE("(%p)->(%d)\n", This, isResolving);
1909 This->resolving = isResolving;
1910 return S_OK;
1914 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1915 IXMLDOMDocument2 *iface,
1916 VARIANT_BOOL* isPreserving )
1918 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1920 TRACE("(%p)->(%p: %d)\n", This, isPreserving, This->preserving);
1921 *isPreserving = This->preserving;
1922 return S_OK;
1926 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1927 IXMLDOMDocument2 *iface,
1928 VARIANT_BOOL isPreserving )
1930 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1932 TRACE("(%p)->(%d)\n", This, isPreserving);
1933 This->preserving = isPreserving;
1934 return S_OK;
1938 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1939 IXMLDOMDocument2 *iface,
1940 VARIANT readyStateChangeSink )
1942 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1943 FIXME("%p\n", This);
1944 return E_NOTIMPL;
1948 static HRESULT WINAPI domdoc_put_onDataAvailable(
1949 IXMLDOMDocument2 *iface,
1950 VARIANT onDataAvailableSink )
1952 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1953 FIXME("%p\n", This);
1954 return E_NOTIMPL;
1957 static HRESULT WINAPI domdoc_put_onTransformNode(
1958 IXMLDOMDocument2 *iface,
1959 VARIANT onTransformNodeSink )
1961 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1962 FIXME("%p\n", This);
1963 return E_NOTIMPL;
1966 static HRESULT WINAPI domdoc_get_namespaces(
1967 IXMLDOMDocument2* iface,
1968 IXMLDOMSchemaCollection** schemaCollection )
1970 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1971 FIXME("(%p)->(%p)\n", This, schemaCollection);
1972 return E_NOTIMPL;
1975 static HRESULT WINAPI domdoc_get_schemas(
1976 IXMLDOMDocument2* iface,
1977 VARIANT* var1 )
1979 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1980 HRESULT hr = S_FALSE;
1981 IXMLDOMSchemaCollection *cur_schema = This->schema;
1983 TRACE("(%p)->(%p)\n", This, var1);
1985 VariantInit(var1); /* Test shows we don't call VariantClear here */
1986 V_VT(var1) = VT_NULL;
1988 if(cur_schema)
1990 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1991 if(SUCCEEDED(hr))
1992 V_VT(var1) = VT_DISPATCH;
1994 return hr;
1997 static HRESULT WINAPI domdoc_putref_schemas(
1998 IXMLDOMDocument2* iface,
1999 VARIANT var1)
2001 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2002 HRESULT hr = E_FAIL;
2003 IXMLDOMSchemaCollection *new_schema = NULL;
2005 FIXME("(%p): semi-stub\n", This);
2006 switch(V_VT(&var1))
2008 case VT_UNKNOWN:
2009 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2010 break;
2012 case VT_DISPATCH:
2013 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
2014 break;
2016 case VT_NULL:
2017 case VT_EMPTY:
2018 hr = S_OK;
2019 break;
2021 default:
2022 WARN("Can't get schema from vt %x\n", V_VT(&var1));
2025 if(SUCCEEDED(hr))
2027 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
2028 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
2031 return hr;
2034 static HRESULT WINAPI domdoc_validate(
2035 IXMLDOMDocument2* iface,
2036 IXMLDOMParseError** err)
2038 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2039 FIXME("(%p)->(%p)\n", This, err);
2040 return E_NOTIMPL;
2043 static HRESULT WINAPI domdoc_setProperty(
2044 IXMLDOMDocument2* iface,
2045 BSTR p,
2046 VARIANT var)
2048 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2050 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
2052 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
2054 VARIANT varStr;
2055 HRESULT hr;
2056 BSTR bstr;
2058 V_VT(&varStr) = VT_EMPTY;
2059 if (V_VT(&var) != VT_BSTR)
2061 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
2062 return hr;
2063 bstr = V_BSTR(&varStr);
2065 else
2066 bstr = V_BSTR(&var);
2068 hr = S_OK;
2069 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
2070 This->bUseXPath = TRUE;
2071 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
2072 This->bUseXPath = FALSE;
2073 else
2074 hr = E_FAIL;
2076 VariantClear(&varStr);
2077 return hr;
2079 else if (lstrcmpiW(p, SZ_PROPERTY_PROHIBIT_DTD) == 0)
2081 /* Ignore */
2082 FIXME("Ignoring property ProhibitDTD, value %d\n", V_BOOL(&var));
2083 return S_OK;
2086 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2087 return E_FAIL;
2090 static HRESULT WINAPI domdoc_getProperty(
2091 IXMLDOMDocument2* iface,
2092 BSTR p,
2093 VARIANT* var)
2095 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2097 TRACE("(%p)->(%p)\n", This, debugstr_w(p));
2099 if (var == NULL)
2100 return E_INVALIDARG;
2101 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
2103 V_VT(var) = VT_BSTR;
2104 if (This->bUseXPath)
2105 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
2106 else
2107 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
2108 return S_OK;
2111 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2112 return E_FAIL;
2115 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
2117 domdoc_QueryInterface,
2118 domdoc_AddRef,
2119 domdoc_Release,
2120 domdoc_GetTypeInfoCount,
2121 domdoc_GetTypeInfo,
2122 domdoc_GetIDsOfNames,
2123 domdoc_Invoke,
2124 domdoc_get_nodeName,
2125 domdoc_get_nodeValue,
2126 domdoc_put_nodeValue,
2127 domdoc_get_nodeType,
2128 domdoc_get_parentNode,
2129 domdoc_get_childNodes,
2130 domdoc_get_firstChild,
2131 domdoc_get_lastChild,
2132 domdoc_get_previousSibling,
2133 domdoc_get_nextSibling,
2134 domdoc_get_attributes,
2135 domdoc_insertBefore,
2136 domdoc_replaceChild,
2137 domdoc_removeChild,
2138 domdoc_appendChild,
2139 domdoc_hasChildNodes,
2140 domdoc_get_ownerDocument,
2141 domdoc_cloneNode,
2142 domdoc_get_nodeTypeString,
2143 domdoc_get_text,
2144 domdoc_put_text,
2145 domdoc_get_specified,
2146 domdoc_get_definition,
2147 domdoc_get_nodeTypedValue,
2148 domdoc_put_nodeTypedValue,
2149 domdoc_get_dataType,
2150 domdoc_put_dataType,
2151 domdoc_get_xml,
2152 domdoc_transformNode,
2153 domdoc_selectNodes,
2154 domdoc_selectSingleNode,
2155 domdoc_get_parsed,
2156 domdoc_get_namespaceURI,
2157 domdoc_get_prefix,
2158 domdoc_get_baseName,
2159 domdoc_transformNodeToObject,
2160 domdoc_get_doctype,
2161 domdoc_get_implementation,
2162 domdoc_get_documentElement,
2163 domdoc_put_documentElement,
2164 domdoc_createElement,
2165 domdoc_createDocumentFragment,
2166 domdoc_createTextNode,
2167 domdoc_createComment,
2168 domdoc_createCDATASection,
2169 domdoc_createProcessingInstruction,
2170 domdoc_createAttribute,
2171 domdoc_createEntityReference,
2172 domdoc_getElementsByTagName,
2173 domdoc_createNode,
2174 domdoc_nodeFromID,
2175 domdoc_load,
2176 domdoc_get_readyState,
2177 domdoc_get_parseError,
2178 domdoc_get_url,
2179 domdoc_get_async,
2180 domdoc_put_async,
2181 domdoc_abort,
2182 domdoc_loadXML,
2183 domdoc_save,
2184 domdoc_get_validateOnParse,
2185 domdoc_put_validateOnParse,
2186 domdoc_get_resolveExternals,
2187 domdoc_put_resolveExternals,
2188 domdoc_get_preserveWhiteSpace,
2189 domdoc_put_preserveWhiteSpace,
2190 domdoc_put_onReadyStateChange,
2191 domdoc_put_onDataAvailable,
2192 domdoc_put_onTransformNode,
2193 domdoc_get_namespaces,
2194 domdoc_get_schemas,
2195 domdoc_putref_schemas,
2196 domdoc_validate,
2197 domdoc_setProperty,
2198 domdoc_getProperty
2201 /* xmldoc implementation of IObjectWithSite */
2202 static HRESULT WINAPI
2203 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2205 domdoc *This = impl_from_IObjectWithSite(iface);
2206 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2209 static ULONG WINAPI
2210 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2212 domdoc *This = impl_from_IObjectWithSite(iface);
2213 return IXMLDocument_AddRef((IXMLDocument *)This);
2216 static ULONG WINAPI
2217 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2219 domdoc *This = impl_from_IObjectWithSite(iface);
2220 return IXMLDocument_Release((IXMLDocument *)This);
2223 static HRESULT WINAPI
2224 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2226 domdoc *This = impl_from_IObjectWithSite(iface);
2228 TRACE("(%p)->(%s %p)\n", This, debugstr_guid( iid ), ppvSite );
2230 if ( !This->site )
2231 return E_FAIL;
2233 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2236 static HRESULT WINAPI
2237 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2239 domdoc *This = impl_from_IObjectWithSite(iface);
2241 TRACE("(%p)->(%p)\n", iface, punk);
2243 if(!punk)
2245 if(This->site)
2247 IUnknown_Release( This->site );
2248 This->site = NULL;
2251 return S_OK;
2254 IUnknown_AddRef( punk );
2256 if(This->site)
2257 IUnknown_Release( This->site );
2259 This->site = punk;
2261 return S_OK;
2264 static const IObjectWithSiteVtbl domdocObjectSite =
2266 xmldoc_ObjectWithSite_QueryInterface,
2267 xmldoc_ObjectWithSite_AddRef,
2268 xmldoc_ObjectWithSite_Release,
2269 xmldoc_SetSite,
2270 xmldoc_GetSite,
2273 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2275 domdoc *This = impl_from_IObjectSafety(iface);
2276 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2279 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2281 domdoc *This = impl_from_IObjectSafety(iface);
2282 return IXMLDocument_AddRef((IXMLDocument *)This);
2285 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2287 domdoc *This = impl_from_IObjectSafety(iface);
2288 return IXMLDocument_Release((IXMLDocument *)This);
2291 #define SAFETY_SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2293 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2294 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2296 domdoc *This = impl_from_IObjectSafety(iface);
2298 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2300 if(!pdwSupportedOptions || !pdwEnabledOptions)
2301 return E_POINTER;
2303 *pdwSupportedOptions = SAFETY_SUPPORTED_OPTIONS;
2304 *pdwEnabledOptions = This->safeopt;
2306 return S_OK;
2309 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2310 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2312 domdoc *This = impl_from_IObjectSafety(iface);
2313 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2315 if ((dwOptionSetMask & ~SAFETY_SUPPORTED_OPTIONS) != 0)
2316 return E_FAIL;
2318 This->safeopt = dwEnabledOptions & dwOptionSetMask & SAFETY_SUPPORTED_OPTIONS;
2319 return S_OK;
2322 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2323 xmldoc_Safety_QueryInterface,
2324 xmldoc_Safety_AddRef,
2325 xmldoc_Safety_Release,
2326 xmldoc_Safety_GetInterfaceSafetyOptions,
2327 xmldoc_Safety_SetInterfaceSafetyOptions
2331 static const tid_t domdoc_iface_tids[] = {
2332 IXMLDOMNode_tid,
2333 IXMLDOMDocument_tid,
2334 IXMLDOMDocument2_tid,
2337 static dispex_static_data_t domdoc_dispex = {
2338 NULL,
2339 IXMLDOMDocument2_tid,
2340 NULL,
2341 domdoc_iface_tids
2344 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2346 domdoc *doc;
2348 doc = heap_alloc( sizeof (*doc) );
2349 if( !doc )
2350 return E_OUTOFMEMORY;
2352 doc->lpVtbl = &domdoc_vtbl;
2353 doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
2354 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2355 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2356 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2357 doc->ref = 1;
2358 doc->async = VARIANT_TRUE;
2359 doc->validating = 0;
2360 doc->resolving = 0;
2361 doc->preserving = 0;
2362 doc->bUseXPath = FALSE;
2363 doc->error = S_OK;
2364 doc->schema = NULL;
2365 doc->stream = NULL;
2366 doc->site = NULL;
2367 doc->safeopt = 0;
2368 doc->bsc = NULL;
2370 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2372 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2374 TRACE("returning iface %p\n", *document);
2375 return S_OK;
2378 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2380 xmlDocPtr xmldoc;
2381 HRESULT hr;
2383 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2385 xmldoc = xmlNewDoc(NULL);
2386 if(!xmldoc)
2387 return E_OUTOFMEMORY;
2389 xmldoc->_private = create_priv();
2391 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2392 if(FAILED(hr))
2393 xmlFreeDoc(xmldoc);
2395 return hr;
2398 IUnknown* create_domdoc( xmlNodePtr document )
2400 HRESULT hr;
2401 LPVOID pObj = NULL;
2403 TRACE("(%p)\n", document);
2405 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2406 if (FAILED(hr))
2407 return NULL;
2409 return pObj;
2412 #else
2414 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2416 MESSAGE("This program tried to use a DOMDocument object, but\n"
2417 "libxml2 support was not present at compile time.\n");
2418 return E_NOTIMPL;
2421 #endif