msxml3: Accept NODE_ENTITY_REFERENCE in ::createNode() and use it for ::createEntityR...
[wine/multimedia.git] / dlls / msxml3 / domdoc.c
blob3e732426d66ea35c281de80ea0506513d7616d42
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_VALUE_XPATH[] = {'X','P','a','t','h',0};
63 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
65 typedef struct _domdoc
67 xmlnode node;
68 const struct IXMLDOMDocument2Vtbl *lpVtbl;
69 const struct IPersistStreamVtbl *lpvtblIPersistStream;
70 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
71 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
72 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
73 LONG ref;
74 VARIANT_BOOL async;
75 VARIANT_BOOL validating;
76 VARIANT_BOOL resolving;
77 VARIANT_BOOL preserving;
78 BOOL bUseXPath;
79 IXMLDOMSchemaCollection *schema;
80 bsc_t *bsc;
81 HRESULT error;
83 /* IPersistStream */
84 IStream *stream;
86 /* IObjectWithSite*/
87 IUnknown *site;
89 /* IObjectSafety */
90 DWORD safeopt;
91 } domdoc;
94 In native windows, the whole lifetime management of XMLDOMNodes is
95 managed automatically using reference counts. Wine emulates that by
96 maintaining a reference count to the document that is increased for
97 each IXMLDOMNode pointer passed out for this document. If all these
98 pointers are gone, the document is unreachable and gets freed, that
99 is, all nodes in the tree of the document get freed.
101 You are able to create nodes that are associated to a document (in
102 fact, in msxml's XMLDOM model, all nodes are associated to a document),
103 but not in the tree of that document, for example using the createFoo
104 functions from IXMLDOMDocument. These nodes do not get cleaned up
105 by libxml, so we have to do it ourselves.
107 To catch these nodes, a list of "orphan nodes" is introduced.
108 It contains pointers to all roots of node trees that are
109 associated with the document without being part of the document
110 tree. All nodes with parent==NULL (except for the document root nodes)
111 should be in the orphan node list of their document. All orphan nodes
112 get freed together with the document itself.
115 typedef struct _xmldoc_priv {
116 LONG refs;
117 struct list orphans;
118 } xmldoc_priv;
120 typedef struct _orphan_entry {
121 struct list entry;
122 xmlNode * node;
123 } orphan_entry;
125 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
127 return doc->_private;
130 static xmldoc_priv * create_priv(void)
132 xmldoc_priv *priv;
133 priv = heap_alloc( sizeof (*priv) );
135 if(priv)
137 priv->refs = 0;
138 list_init( &priv->orphans );
141 return priv;
144 static xmlDocPtr doparse( char *ptr, int len )
146 #ifdef HAVE_XMLREADMEMORY
148 * use xmlReadMemory if possible so we can suppress
149 * writing errors to stderr
151 return xmlReadMemory( ptr, len, NULL, NULL,
152 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
153 #else
154 return xmlParseMemory( ptr, len );
155 #endif
158 LONG xmldoc_add_ref(xmlDocPtr doc)
160 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
161 TRACE("%d\n", ref);
162 return ref;
165 LONG xmldoc_release(xmlDocPtr doc)
167 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
168 LONG ref = InterlockedDecrement(&priv->refs);
169 TRACE("%d\n", ref);
170 if(ref == 0)
172 orphan_entry *orphan, *orphan2;
173 TRACE("freeing docptr %p\n", doc);
175 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
177 xmlFreeNode( orphan->node );
178 heap_free( orphan );
180 heap_free(doc->_private);
182 xmlFreeDoc(doc);
185 return ref;
188 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
190 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
191 orphan_entry *entry;
193 entry = heap_alloc( sizeof (*entry) );
194 if(!entry)
195 return E_OUTOFMEMORY;
197 entry->node = node;
198 list_add_head( &priv->orphans, &entry->entry );
199 return S_OK;
202 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
204 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
205 orphan_entry *entry, *entry2;
207 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
209 if( entry->node == node )
211 list_remove( &entry->entry );
212 heap_free( entry );
213 return S_OK;
217 return S_FALSE;
220 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
222 if(node->node)
223 xmldoc_release(node->node->doc);
225 node->node = (xmlNodePtr) xml;
226 if(node->node)
227 xmldoc_add_ref(node->node->doc);
229 return S_OK;
232 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
234 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
237 static inline xmlDocPtr get_doc( domdoc *This )
239 return (xmlDocPtr)This->node.node;
242 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
244 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
247 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
249 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
252 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
254 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
257 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
259 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
262 /************************************************************************
263 * xmldoc implementation of IPersistStream.
265 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
266 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
268 domdoc *this = impl_from_IPersistStream(iface);
269 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
272 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
273 IPersistStream *iface)
275 domdoc *this = impl_from_IPersistStream(iface);
276 return IXMLDocument_AddRef((IXMLDocument *)this);
279 static ULONG WINAPI xmldoc_IPersistStream_Release(
280 IPersistStream *iface)
282 domdoc *this = impl_from_IPersistStream(iface);
283 return IXMLDocument_Release((IXMLDocument *)this);
286 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
287 IPersistStream *iface, CLSID *classid)
289 TRACE("(%p,%p): stub!\n", iface, classid);
291 if(!classid)
292 return E_POINTER;
294 *classid = CLSID_DOMDocument2;
296 return S_OK;
299 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
300 IPersistStream *iface)
302 domdoc *This = impl_from_IPersistStream(iface);
304 FIXME("(%p->%p): stub!\n", iface, This);
306 return S_FALSE;
309 static HRESULT WINAPI xmldoc_IPersistStream_Load(
310 IPersistStream *iface, LPSTREAM pStm)
312 domdoc *This = impl_from_IPersistStream(iface);
313 HRESULT hr;
314 HGLOBAL hglobal;
315 DWORD read, written, len;
316 BYTE buf[4096];
317 char *ptr;
318 xmlDocPtr xmldoc = NULL;
320 TRACE("(%p, %p)\n", iface, pStm);
322 if (!pStm)
323 return E_INVALIDARG;
325 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
326 if (FAILED(hr))
327 return hr;
331 IStream_Read(pStm, buf, sizeof(buf), &read);
332 hr = IStream_Write(This->stream, buf, read, &written);
333 } while(SUCCEEDED(hr) && written != 0 && read != 0);
335 if (FAILED(hr))
337 ERR("Failed to copy stream\n");
338 return hr;
341 hr = GetHGlobalFromStream(This->stream, &hglobal);
342 if (FAILED(hr))
343 return hr;
345 len = GlobalSize(hglobal);
346 ptr = GlobalLock(hglobal);
347 if (len != 0)
348 xmldoc = parse_xml(ptr, len);
349 GlobalUnlock(hglobal);
351 if (!xmldoc)
353 ERR("Failed to parse xml\n");
354 return E_FAIL;
357 xmldoc->_private = create_priv();
359 return attach_xmldoc( &This->node, xmldoc );
362 static HRESULT WINAPI xmldoc_IPersistStream_Save(
363 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
365 domdoc *This = impl_from_IPersistStream(iface);
366 HRESULT hr;
367 BSTR xmlString;
369 TRACE("(%p, %p, %d)\n", iface, pStm, fClearDirty);
371 hr = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), &xmlString );
372 if(hr == S_OK)
374 DWORD count;
375 DWORD len = strlenW(xmlString) * sizeof(WCHAR);
377 hr = IStream_Write( pStm, xmlString, len, &count );
379 SysFreeString(xmlString);
382 TRACE("ret 0x%08x\n", hr);
384 return hr;
387 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
388 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
390 TRACE("(%p, %p): stub!\n", iface, pcbSize);
391 return E_NOTIMPL;
394 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
396 xmldoc_IPersistStream_QueryInterface,
397 xmldoc_IPersistStream_AddRef,
398 xmldoc_IPersistStream_Release,
399 xmldoc_IPersistStream_GetClassID,
400 xmldoc_IPersistStream_IsDirty,
401 xmldoc_IPersistStream_Load,
402 xmldoc_IPersistStream_Save,
403 xmldoc_IPersistStream_GetSizeMax,
406 /* ISupportErrorInfo interface */
407 static HRESULT WINAPI support_error_QueryInterface(
408 ISupportErrorInfo *iface,
409 REFIID riid, void** ppvObj )
411 domdoc *This = impl_from_ISupportErrorInfo(iface);
412 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
415 static ULONG WINAPI support_error_AddRef(
416 ISupportErrorInfo *iface )
418 domdoc *This = impl_from_ISupportErrorInfo(iface);
419 return IXMLDocument_AddRef((IXMLDocument *)This);
422 static ULONG WINAPI support_error_Release(
423 ISupportErrorInfo *iface )
425 domdoc *This = impl_from_ISupportErrorInfo(iface);
426 return IXMLDocument_Release((IXMLDocument *)This);
429 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
430 ISupportErrorInfo *iface,
431 REFIID riid )
433 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
434 return S_FALSE;
437 static const struct ISupportErrorInfoVtbl support_error_vtbl =
439 support_error_QueryInterface,
440 support_error_AddRef,
441 support_error_Release,
442 support_error_InterfaceSupportsErrorInfo
445 /* IXMLDOMDocument2 interface */
446 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
448 domdoc *This = impl_from_IXMLDOMDocument2( iface );
450 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
452 *ppvObject = NULL;
454 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
455 IsEqualGUID( riid, &IID_IDispatch ) ||
456 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
457 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
459 *ppvObject = iface;
461 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
463 *ppvObject = IXMLDOMNode_from_impl(&This->node);
465 else if (IsEqualGUID(&IID_IPersistStream, riid))
467 *ppvObject = &(This->lpvtblIPersistStream);
469 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
471 *ppvObject = &(This->lpvtblIObjectWithSite);
473 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
475 *ppvObject = &This->lpvtblISupportErrorInfo;
477 else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
479 return *ppvObject ? S_OK : E_NOINTERFACE;
481 else if(IsEqualGUID(&IID_IRunnableObject, riid))
483 TRACE("IID_IRunnableObject not supported returning NULL\n");
484 return E_NOINTERFACE;
486 else
488 FIXME("interface %s not implemented\n", debugstr_guid(riid));
489 return E_NOINTERFACE;
492 IUnknown_AddRef((IUnknown*)*ppvObject);
494 return S_OK;
498 static ULONG WINAPI domdoc_AddRef(
499 IXMLDOMDocument2 *iface )
501 domdoc *This = impl_from_IXMLDOMDocument2( iface );
502 TRACE("%p\n", This );
503 return InterlockedIncrement( &This->ref );
507 static ULONG WINAPI domdoc_Release(
508 IXMLDOMDocument2 *iface )
510 domdoc *This = impl_from_IXMLDOMDocument2( iface );
511 LONG ref;
513 TRACE("%p\n", This );
515 ref = InterlockedDecrement( &This->ref );
516 if ( ref == 0 )
518 if(This->bsc)
519 detach_bsc(This->bsc);
521 if (This->site)
522 IUnknown_Release( This->site );
523 destroy_xmlnode(&This->node);
524 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
525 if (This->stream) IStream_Release(This->stream);
526 HeapFree( GetProcessHeap(), 0, This );
529 return ref;
532 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
534 domdoc *This = impl_from_IXMLDOMDocument2( iface );
536 TRACE("(%p)->(%p)\n", This, pctinfo);
538 *pctinfo = 1;
540 return S_OK;
543 static HRESULT WINAPI domdoc_GetTypeInfo(
544 IXMLDOMDocument2 *iface,
545 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
547 domdoc *This = impl_from_IXMLDOMDocument2( iface );
548 HRESULT hr;
550 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
552 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
554 return hr;
557 static HRESULT WINAPI domdoc_GetIDsOfNames(
558 IXMLDOMDocument2 *iface,
559 REFIID riid,
560 LPOLESTR* rgszNames,
561 UINT cNames,
562 LCID lcid,
563 DISPID* rgDispId)
565 domdoc *This = impl_from_IXMLDOMDocument2( iface );
566 ITypeInfo *typeinfo;
567 HRESULT hr;
569 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
570 lcid, rgDispId);
572 if(!rgszNames || cNames == 0 || !rgDispId)
573 return E_INVALIDARG;
575 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
576 if(SUCCEEDED(hr))
578 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
579 ITypeInfo_Release(typeinfo);
582 return hr;
586 static HRESULT WINAPI domdoc_Invoke(
587 IXMLDOMDocument2 *iface,
588 DISPID dispIdMember,
589 REFIID riid,
590 LCID lcid,
591 WORD wFlags,
592 DISPPARAMS* pDispParams,
593 VARIANT* pVarResult,
594 EXCEPINFO* pExcepInfo,
595 UINT* puArgErr)
597 domdoc *This = impl_from_IXMLDOMDocument2( iface );
598 ITypeInfo *typeinfo;
599 HRESULT hr;
601 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
602 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
604 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
605 if(SUCCEEDED(hr))
607 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
608 pVarResult, pExcepInfo, puArgErr);
609 ITypeInfo_Release(typeinfo);
612 return hr;
616 static HRESULT WINAPI domdoc_get_nodeName(
617 IXMLDOMDocument2 *iface,
618 BSTR* name )
620 domdoc *This = impl_from_IXMLDOMDocument2( iface );
621 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
625 static HRESULT WINAPI domdoc_get_nodeValue(
626 IXMLDOMDocument2 *iface,
627 VARIANT* value )
629 domdoc *This = impl_from_IXMLDOMDocument2( iface );
630 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
634 static HRESULT WINAPI domdoc_put_nodeValue(
635 IXMLDOMDocument2 *iface,
636 VARIANT value)
638 domdoc *This = impl_from_IXMLDOMDocument2( iface );
639 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
643 static HRESULT WINAPI domdoc_get_nodeType(
644 IXMLDOMDocument2 *iface,
645 DOMNodeType* type )
647 domdoc *This = impl_from_IXMLDOMDocument2( iface );
648 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
652 static HRESULT WINAPI domdoc_get_parentNode(
653 IXMLDOMDocument2 *iface,
654 IXMLDOMNode** parent )
656 domdoc *This = impl_from_IXMLDOMDocument2( iface );
657 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
661 static HRESULT WINAPI domdoc_get_childNodes(
662 IXMLDOMDocument2 *iface,
663 IXMLDOMNodeList** childList )
665 domdoc *This = impl_from_IXMLDOMDocument2( iface );
666 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
670 static HRESULT WINAPI domdoc_get_firstChild(
671 IXMLDOMDocument2 *iface,
672 IXMLDOMNode** firstChild )
674 domdoc *This = impl_from_IXMLDOMDocument2( iface );
675 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
679 static HRESULT WINAPI domdoc_get_lastChild(
680 IXMLDOMDocument2 *iface,
681 IXMLDOMNode** lastChild )
683 domdoc *This = impl_from_IXMLDOMDocument2( iface );
684 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
688 static HRESULT WINAPI domdoc_get_previousSibling(
689 IXMLDOMDocument2 *iface,
690 IXMLDOMNode** previousSibling )
692 domdoc *This = impl_from_IXMLDOMDocument2( iface );
693 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
697 static HRESULT WINAPI domdoc_get_nextSibling(
698 IXMLDOMDocument2 *iface,
699 IXMLDOMNode** nextSibling )
701 domdoc *This = impl_from_IXMLDOMDocument2( iface );
702 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
706 static HRESULT WINAPI domdoc_get_attributes(
707 IXMLDOMDocument2 *iface,
708 IXMLDOMNamedNodeMap** attributeMap )
710 domdoc *This = impl_from_IXMLDOMDocument2( iface );
711 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
715 static HRESULT WINAPI domdoc_insertBefore(
716 IXMLDOMDocument2 *iface,
717 IXMLDOMNode* newChild,
718 VARIANT refChild,
719 IXMLDOMNode** outNewChild )
721 domdoc *This = impl_from_IXMLDOMDocument2( iface );
722 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
726 static HRESULT WINAPI domdoc_replaceChild(
727 IXMLDOMDocument2 *iface,
728 IXMLDOMNode* newChild,
729 IXMLDOMNode* oldChild,
730 IXMLDOMNode** outOldChild)
732 domdoc *This = impl_from_IXMLDOMDocument2( iface );
733 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
737 static HRESULT WINAPI domdoc_removeChild(
738 IXMLDOMDocument2 *iface,
739 IXMLDOMNode* childNode,
740 IXMLDOMNode** oldChild)
742 domdoc *This = impl_from_IXMLDOMDocument2( iface );
743 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
747 static HRESULT WINAPI domdoc_appendChild(
748 IXMLDOMDocument2 *iface,
749 IXMLDOMNode* newChild,
750 IXMLDOMNode** outNewChild)
752 domdoc *This = impl_from_IXMLDOMDocument2( iface );
753 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
757 static HRESULT WINAPI domdoc_hasChildNodes(
758 IXMLDOMDocument2 *iface,
759 VARIANT_BOOL* hasChild)
761 domdoc *This = impl_from_IXMLDOMDocument2( iface );
762 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
766 static HRESULT WINAPI domdoc_get_ownerDocument(
767 IXMLDOMDocument2 *iface,
768 IXMLDOMDocument** DOMDocument)
770 domdoc *This = impl_from_IXMLDOMDocument2( iface );
771 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
775 static HRESULT WINAPI domdoc_cloneNode(
776 IXMLDOMDocument2 *iface,
777 VARIANT_BOOL deep,
778 IXMLDOMNode** cloneRoot)
780 domdoc *This = impl_from_IXMLDOMDocument2( iface );
781 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
785 static HRESULT WINAPI domdoc_get_nodeTypeString(
786 IXMLDOMDocument2 *iface,
787 BSTR* nodeType )
789 domdoc *This = impl_from_IXMLDOMDocument2( iface );
790 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
794 static HRESULT WINAPI domdoc_get_text(
795 IXMLDOMDocument2 *iface,
796 BSTR* text )
798 domdoc *This = impl_from_IXMLDOMDocument2( iface );
799 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
803 static HRESULT WINAPI domdoc_put_text(
804 IXMLDOMDocument2 *iface,
805 BSTR text )
807 domdoc *This = impl_from_IXMLDOMDocument2( iface );
808 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
812 static HRESULT WINAPI domdoc_get_specified(
813 IXMLDOMDocument2 *iface,
814 VARIANT_BOOL* isSpecified )
816 domdoc *This = impl_from_IXMLDOMDocument2( iface );
817 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
821 static HRESULT WINAPI domdoc_get_definition(
822 IXMLDOMDocument2 *iface,
823 IXMLDOMNode** definitionNode )
825 domdoc *This = impl_from_IXMLDOMDocument2( iface );
826 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
830 static HRESULT WINAPI domdoc_get_nodeTypedValue(
831 IXMLDOMDocument2 *iface,
832 VARIANT* typedValue )
834 domdoc *This = impl_from_IXMLDOMDocument2( iface );
835 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
838 static HRESULT WINAPI domdoc_put_nodeTypedValue(
839 IXMLDOMDocument2 *iface,
840 VARIANT typedValue )
842 domdoc *This = impl_from_IXMLDOMDocument2( iface );
843 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
847 static HRESULT WINAPI domdoc_get_dataType(
848 IXMLDOMDocument2 *iface,
849 VARIANT* dataTypeName )
851 domdoc *This = impl_from_IXMLDOMDocument2( iface );
852 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
856 static HRESULT WINAPI domdoc_put_dataType(
857 IXMLDOMDocument2 *iface,
858 BSTR dataTypeName )
860 domdoc *This = impl_from_IXMLDOMDocument2( iface );
861 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
865 static HRESULT WINAPI domdoc_get_xml(
866 IXMLDOMDocument2 *iface,
867 BSTR* xmlString )
869 domdoc *This = impl_from_IXMLDOMDocument2( iface );
870 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
874 static HRESULT WINAPI domdoc_transformNode(
875 IXMLDOMDocument2 *iface,
876 IXMLDOMNode* styleSheet,
877 BSTR* xmlString )
879 domdoc *This = impl_from_IXMLDOMDocument2( iface );
880 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
884 static HRESULT WINAPI domdoc_selectNodes(
885 IXMLDOMDocument2 *iface,
886 BSTR queryString,
887 IXMLDOMNodeList** resultList )
889 domdoc *This = impl_from_IXMLDOMDocument2( iface );
890 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
894 static HRESULT WINAPI domdoc_selectSingleNode(
895 IXMLDOMDocument2 *iface,
896 BSTR queryString,
897 IXMLDOMNode** resultNode )
899 domdoc *This = impl_from_IXMLDOMDocument2( iface );
900 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
904 static HRESULT WINAPI domdoc_get_parsed(
905 IXMLDOMDocument2 *iface,
906 VARIANT_BOOL* isParsed )
908 domdoc *This = impl_from_IXMLDOMDocument2( iface );
909 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
913 static HRESULT WINAPI domdoc_get_namespaceURI(
914 IXMLDOMDocument2 *iface,
915 BSTR* namespaceURI )
917 domdoc *This = impl_from_IXMLDOMDocument2( iface );
918 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
922 static HRESULT WINAPI domdoc_get_prefix(
923 IXMLDOMDocument2 *iface,
924 BSTR* prefixString )
926 domdoc *This = impl_from_IXMLDOMDocument2( iface );
927 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
931 static HRESULT WINAPI domdoc_get_baseName(
932 IXMLDOMDocument2 *iface,
933 BSTR* nameString )
935 domdoc *This = impl_from_IXMLDOMDocument2( iface );
936 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
940 static HRESULT WINAPI domdoc_transformNodeToObject(
941 IXMLDOMDocument2 *iface,
942 IXMLDOMNode* stylesheet,
943 VARIANT outputObject)
945 domdoc *This = impl_from_IXMLDOMDocument2( iface );
946 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
950 static HRESULT WINAPI domdoc_get_doctype(
951 IXMLDOMDocument2 *iface,
952 IXMLDOMDocumentType** documentType )
954 FIXME("\n");
955 return E_NOTIMPL;
959 static HRESULT WINAPI domdoc_get_implementation(
960 IXMLDOMDocument2 *iface,
961 IXMLDOMImplementation** impl )
963 if(!impl)
964 return E_INVALIDARG;
966 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
968 return S_OK;
971 static HRESULT WINAPI domdoc_get_documentElement(
972 IXMLDOMDocument2 *iface,
973 IXMLDOMElement** DOMElement )
975 domdoc *This = impl_from_IXMLDOMDocument2( iface );
976 xmlDocPtr xmldoc = NULL;
977 xmlNodePtr root = NULL;
978 IXMLDOMNode *element_node;
979 HRESULT hr;
981 TRACE("%p\n", This);
983 if(!DOMElement)
984 return E_INVALIDARG;
986 *DOMElement = NULL;
988 xmldoc = get_doc( This );
990 root = xmlDocGetRootElement( xmldoc );
991 if ( !root )
992 return S_FALSE;
994 element_node = create_node( root );
995 if(!element_node) return S_FALSE;
997 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
998 IXMLDOMNode_Release(element_node);
1000 return hr;
1004 static HRESULT WINAPI domdoc_put_documentElement(
1005 IXMLDOMDocument2 *iface,
1006 IXMLDOMElement* DOMElement )
1008 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1009 IXMLDOMNode *elementNode;
1010 xmlNodePtr oldRoot;
1011 xmlnode *xmlNode;
1012 HRESULT hr;
1014 TRACE("(%p)->(%p)\n", This, DOMElement);
1016 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1017 if(FAILED(hr))
1018 return hr;
1020 xmlNode = impl_from_IXMLDOMNode( elementNode );
1022 if(!xmlNode->node->parent)
1023 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1024 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1026 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1027 IXMLDOMNode_Release( elementNode );
1029 if(oldRoot)
1030 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1032 return S_OK;
1036 static HRESULT WINAPI domdoc_createElement(
1037 IXMLDOMDocument2 *iface,
1038 BSTR tagname,
1039 IXMLDOMElement** element )
1041 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1042 IXMLDOMNode *node;
1043 VARIANT type;
1044 HRESULT hr;
1046 TRACE("(%p)->(%s,%p)\n", This, debugstr_w(tagname), element);
1048 if (!element || !tagname) return E_INVALIDARG;
1050 V_VT(&type) = VT_I1;
1051 V_I1(&type) = NODE_ELEMENT;
1053 hr = IXMLDOMDocument_createNode(iface, type, tagname, NULL, &node);
1054 if (hr == S_OK)
1056 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
1057 IXMLDOMNode_Release(node);
1060 return hr;
1064 static HRESULT WINAPI domdoc_createDocumentFragment(
1065 IXMLDOMDocument2 *iface,
1066 IXMLDOMDocumentFragment** frag )
1068 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1069 IXMLDOMNode *node;
1070 VARIANT type;
1071 HRESULT hr;
1073 TRACE("(%p)->(%p)\n", This, frag);
1075 if (!frag) return E_INVALIDARG;
1077 *frag = NULL;
1079 V_VT(&type) = VT_I1;
1080 V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
1082 hr = IXMLDOMDocument_createNode(iface, type, NULL, NULL, &node);
1083 if (hr == S_OK)
1085 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
1086 IXMLDOMNode_Release(node);
1089 return hr;
1093 static HRESULT WINAPI domdoc_createTextNode(
1094 IXMLDOMDocument2 *iface,
1095 BSTR data,
1096 IXMLDOMText** text )
1098 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1099 IXMLDOMNode *node;
1100 VARIANT type;
1101 HRESULT hr;
1103 TRACE("%p->(%s %p)\n", This, debugstr_w(data), text);
1105 if (!text) return E_INVALIDARG;
1107 *text = NULL;
1109 V_VT(&type) = VT_I1;
1110 V_I1(&type) = NODE_TEXT;
1112 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1113 if (hr == S_OK)
1115 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMText, (void**)text);
1116 IXMLDOMNode_Release(node);
1117 hr = IXMLDOMText_put_data(*text, data);
1120 return hr;
1124 static HRESULT WINAPI domdoc_createComment(
1125 IXMLDOMDocument2 *iface,
1126 BSTR data,
1127 IXMLDOMComment** comment )
1129 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1130 VARIANT type;
1131 HRESULT hr;
1132 IXMLDOMNode *node;
1134 TRACE("%p->(%s %p)\n", This, debugstr_w(data), comment);
1136 if (!comment) return E_INVALIDARG;
1138 *comment = NULL;
1140 V_VT(&type) = VT_I1;
1141 V_I1(&type) = NODE_COMMENT;
1143 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1144 if (hr == S_OK)
1146 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMComment, (void**)comment);
1147 IXMLDOMNode_Release(node);
1148 hr = IXMLDOMComment_put_data(*comment, data);
1151 return hr;
1155 static HRESULT WINAPI domdoc_createCDATASection(
1156 IXMLDOMDocument2 *iface,
1157 BSTR data,
1158 IXMLDOMCDATASection** cdata )
1160 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1161 IXMLDOMNode *node;
1162 VARIANT type;
1163 HRESULT hr;
1165 TRACE("%p->(%s %p)\n", This, debugstr_w(data), cdata);
1167 if (!cdata) return E_INVALIDARG;
1169 *cdata = NULL;
1171 V_VT(&type) = VT_I1;
1172 V_I1(&type) = NODE_CDATA_SECTION;
1174 hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
1175 if (hr == S_OK)
1177 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMCDATASection, (void**)cdata);
1178 IXMLDOMNode_Release(node);
1179 hr = IXMLDOMCDATASection_put_data(*cdata, data);
1182 return hr;
1186 static HRESULT WINAPI domdoc_createProcessingInstruction(
1187 IXMLDOMDocument2 *iface,
1188 BSTR target,
1189 BSTR data,
1190 IXMLDOMProcessingInstruction** pi )
1192 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1193 IXMLDOMNode *node;
1194 VARIANT type;
1195 HRESULT hr;
1197 TRACE("%p->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), pi);
1199 if (!pi) return E_INVALIDARG;
1201 *pi = NULL;
1203 V_VT(&type) = VT_I1;
1204 V_I1(&type) = NODE_PROCESSING_INSTRUCTION;
1206 hr = IXMLDOMDocument2_createNode(iface, type, target, NULL, &node);
1207 if (hr == S_OK)
1209 VARIANT v_data;
1211 /* this is to bypass check in ::put_data() that blocks "<?xml" PIs */
1212 V_VT(&v_data) = VT_BSTR;
1213 V_BSTR(&v_data) = data;
1215 hr = IXMLDOMNode_put_nodeValue( node, v_data );
1217 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMProcessingInstruction, (void**)pi);
1218 IXMLDOMNode_Release(node);
1221 return hr;
1225 static HRESULT WINAPI domdoc_createAttribute(
1226 IXMLDOMDocument2 *iface,
1227 BSTR name,
1228 IXMLDOMAttribute** attribute )
1230 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1231 IXMLDOMNode *node;
1232 VARIANT type;
1233 HRESULT hr;
1235 TRACE("%p->(%s %p)\n", This, debugstr_w(name), attribute);
1237 if (!attribute || !name) return E_INVALIDARG;
1239 V_VT(&type) = VT_I1;
1240 V_I1(&type) = NODE_ATTRIBUTE;
1242 hr = IXMLDOMDocument_createNode(iface, type, name, NULL, &node);
1243 if (hr == S_OK)
1245 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
1246 IXMLDOMNode_Release(node);
1249 return hr;
1253 static HRESULT WINAPI domdoc_createEntityReference(
1254 IXMLDOMDocument2 *iface,
1255 BSTR name,
1256 IXMLDOMEntityReference** entityref )
1258 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1259 IXMLDOMNode *node;
1260 VARIANT type;
1261 HRESULT hr;
1263 TRACE("%p->(%s %p)\n", This, debugstr_w(name), entityref);
1265 if (!entityref) return E_INVALIDARG;
1267 *entityref = NULL;
1269 V_VT(&type) = VT_I1;
1270 V_I1(&type) = NODE_ENTITY_REFERENCE;
1272 hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
1273 if (hr == S_OK)
1275 IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMEntityReference, (void**)entityref);
1276 IXMLDOMNode_Release(node);
1279 return hr;
1283 static HRESULT WINAPI domdoc_getElementsByTagName(
1284 IXMLDOMDocument2 *iface,
1285 BSTR tagName,
1286 IXMLDOMNodeList** resultList )
1288 static const WCHAR xpathformat[] =
1289 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1290 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1291 LPWSTR szPattern;
1292 HRESULT hr;
1293 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1295 if (tagName[0] == '*' && tagName[1] == 0)
1297 szPattern = heap_alloc(sizeof(WCHAR)*4);
1298 szPattern[0] = szPattern[1] = '/';
1299 szPattern[2] = '*';
1300 szPattern[3] = 0;
1302 else
1304 szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1305 wsprintfW(szPattern, xpathformat, tagName);
1308 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1309 heap_free(szPattern);
1311 return hr;
1314 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1316 VARIANT tmp;
1317 HRESULT hr;
1319 VariantInit(&tmp);
1320 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1321 if(FAILED(hr))
1322 return E_INVALIDARG;
1324 *type = V_I4(&tmp);
1326 return S_OK;
1329 static HRESULT WINAPI domdoc_createNode(
1330 IXMLDOMDocument2 *iface,
1331 VARIANT Type,
1332 BSTR name,
1333 BSTR namespaceURI,
1334 IXMLDOMNode** node )
1336 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1337 DOMNodeType node_type;
1338 xmlNodePtr xmlnode;
1339 xmlChar *xml_name;
1340 HRESULT hr;
1342 TRACE("(%p)->(%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1344 if(!node) return E_INVALIDARG;
1346 if(namespaceURI && namespaceURI[0])
1347 FIXME("nodes with namespaces currently not supported.\n");
1349 hr = get_node_type(Type, &node_type);
1350 if(FAILED(hr)) return hr;
1352 TRACE("node_type %d\n", node_type);
1354 /* exit earlier for types that need name */
1355 switch(node_type)
1357 case NODE_ELEMENT:
1358 case NODE_ATTRIBUTE:
1359 case NODE_ENTITY_REFERENCE:
1360 case NODE_PROCESSING_INSTRUCTION:
1361 if (!name || SysStringLen(name) == 0) return E_FAIL;
1362 default:
1363 break;
1366 xml_name = xmlChar_from_wchar(name);
1368 switch(node_type)
1370 case NODE_ELEMENT:
1371 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1372 break;
1373 case NODE_ATTRIBUTE:
1374 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1375 break;
1376 case NODE_TEXT:
1377 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1378 break;
1379 case NODE_CDATA_SECTION:
1380 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1381 break;
1382 case NODE_ENTITY_REFERENCE:
1383 xmlnode = xmlNewReference(get_doc(This), xml_name);
1384 break;
1385 case NODE_PROCESSING_INSTRUCTION:
1386 #ifdef HAVE_XMLNEWDOCPI
1387 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1388 #else
1389 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1390 xmlnode = NULL;
1391 #endif
1392 break;
1393 case NODE_COMMENT:
1394 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1395 break;
1396 case NODE_DOCUMENT_FRAGMENT:
1397 xmlnode = xmlNewDocFragment(get_doc(This));
1398 break;
1399 /* unsupported types */
1400 case NODE_DOCUMENT:
1401 case NODE_DOCUMENT_TYPE:
1402 case NODE_ENTITY:
1403 case NODE_NOTATION:
1404 heap_free(xml_name);
1405 return E_INVALIDARG;
1406 default:
1407 FIXME("unhandled node type %d\n", node_type);
1408 xmlnode = NULL;
1409 break;
1412 *node = create_node(xmlnode);
1413 heap_free(xml_name);
1415 if(*node)
1417 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1418 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1419 return S_OK;
1422 return E_FAIL;
1425 static HRESULT WINAPI domdoc_nodeFromID(
1426 IXMLDOMDocument2 *iface,
1427 BSTR idString,
1428 IXMLDOMNode** node )
1430 FIXME("\n");
1431 return E_NOTIMPL;
1434 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1436 domdoc *This = obj;
1437 xmlDocPtr xmldoc;
1439 xmldoc = doparse( ptr, len );
1440 if(xmldoc) {
1441 xmldoc->_private = create_priv();
1442 return attach_xmldoc(&This->node, xmldoc);
1445 return S_OK;
1448 static HRESULT doread( domdoc *This, LPWSTR filename )
1450 bsc_t *bsc;
1451 HRESULT hr;
1453 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1454 if(FAILED(hr))
1455 return hr;
1457 if(This->bsc)
1458 detach_bsc(This->bsc);
1460 This->bsc = bsc;
1461 return S_OK;
1464 static HRESULT WINAPI domdoc_load(
1465 IXMLDOMDocument2 *iface,
1466 VARIANT xmlSource,
1467 VARIANT_BOOL* isSuccessful )
1469 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1470 LPWSTR filename = NULL;
1471 HRESULT hr = S_FALSE;
1472 IXMLDOMDocument2 *pNewDoc = NULL;
1473 IStream *pStream = NULL;
1474 xmlDocPtr xmldoc;
1476 TRACE("type %d\n", V_VT(&xmlSource) );
1478 *isSuccessful = VARIANT_FALSE;
1480 assert( &This->node );
1482 switch( V_VT(&xmlSource) )
1484 case VT_BSTR:
1485 filename = V_BSTR(&xmlSource);
1486 break;
1487 case VT_UNKNOWN:
1488 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1489 if(hr == S_OK)
1491 if(pNewDoc)
1493 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1494 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1495 hr = attach_xmldoc(&This->node, xmldoc);
1497 if(SUCCEEDED(hr))
1498 *isSuccessful = VARIANT_TRUE;
1500 return hr;
1503 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1504 if(hr == S_OK)
1506 IPersistStream *pDocStream;
1507 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1508 if(hr == S_OK)
1510 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1511 IStream_Release(pStream);
1512 if(hr == S_OK)
1514 *isSuccessful = VARIANT_TRUE;
1516 TRACE("Using ID_IStream to load Document\n");
1517 return S_OK;
1519 else
1521 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1524 else
1526 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1529 else
1531 /* ISequentialStream */
1532 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1534 break;
1535 default:
1536 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1539 TRACE("filename (%s)\n", debugstr_w(filename));
1541 if ( filename )
1543 hr = doread( This, filename );
1545 if ( FAILED(hr) )
1546 This->error = E_FAIL;
1547 else
1549 hr = This->error = S_OK;
1550 *isSuccessful = VARIANT_TRUE;
1554 if(!filename || FAILED(hr)) {
1555 xmldoc = xmlNewDoc(NULL);
1556 xmldoc->_private = create_priv();
1557 hr = attach_xmldoc(&This->node, xmldoc);
1558 if(SUCCEEDED(hr))
1559 hr = S_FALSE;
1562 TRACE("ret (%d)\n", hr);
1564 return hr;
1568 static HRESULT WINAPI domdoc_get_readyState(
1569 IXMLDOMDocument2 *iface,
1570 LONG *value )
1572 FIXME("\n");
1573 return E_NOTIMPL;
1577 static HRESULT WINAPI domdoc_get_parseError(
1578 IXMLDOMDocument2 *iface,
1579 IXMLDOMParseError** errorObj )
1581 BSTR error_string = NULL;
1582 static const WCHAR err[] = {'e','r','r','o','r',0};
1583 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1585 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1587 if(This->error)
1588 error_string = SysAllocString(err);
1590 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1591 if(!*errorObj) return E_OUTOFMEMORY;
1592 return S_OK;
1596 static HRESULT WINAPI domdoc_get_url(
1597 IXMLDOMDocument2 *iface,
1598 BSTR* urlString )
1600 FIXME("\n");
1601 return E_NOTIMPL;
1605 static HRESULT WINAPI domdoc_get_async(
1606 IXMLDOMDocument2 *iface,
1607 VARIANT_BOOL* isAsync )
1609 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1611 TRACE("%p <- %d\n", isAsync, This->async);
1612 *isAsync = This->async;
1613 return S_OK;
1617 static HRESULT WINAPI domdoc_put_async(
1618 IXMLDOMDocument2 *iface,
1619 VARIANT_BOOL isAsync )
1621 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1623 TRACE("%d\n", isAsync);
1624 This->async = isAsync;
1625 return S_OK;
1629 static HRESULT WINAPI domdoc_abort(
1630 IXMLDOMDocument2 *iface )
1632 FIXME("\n");
1633 return E_NOTIMPL;
1637 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1639 UINT len, blen = SysStringLen( bstr );
1640 LPSTR str;
1642 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1643 str = heap_alloc( len );
1644 if ( !str )
1645 return FALSE;
1646 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1647 *plen = len;
1648 *pstr = str;
1649 return TRUE;
1652 static HRESULT WINAPI domdoc_loadXML(
1653 IXMLDOMDocument2 *iface,
1654 BSTR bstrXML,
1655 VARIANT_BOOL* isSuccessful )
1657 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1658 xmlDocPtr xmldoc = NULL;
1659 char *str;
1660 int len;
1661 HRESULT hr = S_FALSE, hr2;
1663 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1665 assert ( &This->node );
1667 if ( isSuccessful )
1669 *isSuccessful = VARIANT_FALSE;
1671 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1673 xmldoc = doparse( str, len );
1674 heap_free( str );
1675 if ( !xmldoc )
1676 This->error = E_FAIL;
1677 else
1679 hr = This->error = S_OK;
1680 *isSuccessful = VARIANT_TRUE;
1684 if(!xmldoc)
1685 xmldoc = xmlNewDoc(NULL);
1687 xmldoc->_private = create_priv();
1688 hr2 = attach_xmldoc( &This->node, xmldoc );
1689 if( FAILED(hr2) )
1690 hr = hr2;
1692 return hr;
1695 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1696 int len)
1698 DWORD written = -1;
1700 if(!WriteFile(ctx, buffer, len, &written, NULL))
1702 WARN("write error\n");
1703 return -1;
1705 else
1706 return written;
1709 static int XMLCALL domdoc_save_closecallback(void *ctx)
1711 return CloseHandle(ctx) ? 0 : -1;
1714 static HRESULT WINAPI domdoc_save(
1715 IXMLDOMDocument2 *iface,
1716 VARIANT destination )
1718 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1719 HANDLE handle;
1720 xmlSaveCtxtPtr ctx;
1721 HRESULT ret = S_OK;
1723 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1724 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1726 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1728 FIXME("Unhandled vt %d\n", V_VT(&destination));
1729 return S_FALSE;
1732 if(V_VT(&destination) == VT_UNKNOWN)
1734 IUnknown *pUnk = V_UNKNOWN(&destination);
1735 IXMLDOMDocument *pDocument;
1737 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1738 if(ret == S_OK)
1740 BSTR bXML;
1741 VARIANT_BOOL bSuccessful;
1743 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1744 if(ret == S_OK)
1746 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1748 SysFreeString(bXML);
1751 IXMLDOMDocument_Release(pDocument);
1754 TRACE("ret %d\n", ret);
1756 return ret;
1759 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1760 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1761 if( handle == INVALID_HANDLE_VALUE )
1763 WARN("failed to create file\n");
1764 return S_FALSE;
1767 /* disable top XML declaration */
1768 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1769 handle, NULL, XML_SAVE_NO_DECL);
1770 if (!ctx)
1772 CloseHandle(handle);
1773 return S_FALSE;
1776 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1777 /* will close file through close callback */
1778 xmlSaveClose(ctx);
1780 return ret;
1783 static HRESULT WINAPI domdoc_get_validateOnParse(
1784 IXMLDOMDocument2 *iface,
1785 VARIANT_BOOL* isValidating )
1787 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1789 TRACE("%p <- %d\n", isValidating, This->validating);
1790 *isValidating = This->validating;
1791 return S_OK;
1795 static HRESULT WINAPI domdoc_put_validateOnParse(
1796 IXMLDOMDocument2 *iface,
1797 VARIANT_BOOL isValidating )
1799 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1801 TRACE("%d\n", isValidating);
1802 This->validating = isValidating;
1803 return S_OK;
1807 static HRESULT WINAPI domdoc_get_resolveExternals(
1808 IXMLDOMDocument2 *iface,
1809 VARIANT_BOOL* isResolving )
1811 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1813 TRACE("%p <- %d\n", isResolving, This->resolving);
1814 *isResolving = This->resolving;
1815 return S_OK;
1819 static HRESULT WINAPI domdoc_put_resolveExternals(
1820 IXMLDOMDocument2 *iface,
1821 VARIANT_BOOL isResolving )
1823 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1825 TRACE("%d\n", isResolving);
1826 This->resolving = isResolving;
1827 return S_OK;
1831 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1832 IXMLDOMDocument2 *iface,
1833 VARIANT_BOOL* isPreserving )
1835 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1837 TRACE("%p <- %d\n", isPreserving, This->preserving);
1838 *isPreserving = This->preserving;
1839 return S_OK;
1843 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1844 IXMLDOMDocument2 *iface,
1845 VARIANT_BOOL isPreserving )
1847 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1849 TRACE("%d\n", isPreserving);
1850 This->preserving = isPreserving;
1851 return S_OK;
1855 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1856 IXMLDOMDocument2 *iface,
1857 VARIANT readyStateChangeSink )
1859 FIXME("\n");
1860 return E_NOTIMPL;
1864 static HRESULT WINAPI domdoc_put_onDataAvailable(
1865 IXMLDOMDocument2 *iface,
1866 VARIANT onDataAvailableSink )
1868 FIXME("\n");
1869 return E_NOTIMPL;
1872 static HRESULT WINAPI domdoc_put_onTransformNode(
1873 IXMLDOMDocument2 *iface,
1874 VARIANT onTransformNodeSink )
1876 FIXME("\n");
1877 return E_NOTIMPL;
1880 static HRESULT WINAPI domdoc_get_namespaces(
1881 IXMLDOMDocument2* iface,
1882 IXMLDOMSchemaCollection** schemaCollection )
1884 FIXME("\n");
1885 return E_NOTIMPL;
1888 static HRESULT WINAPI domdoc_get_schemas(
1889 IXMLDOMDocument2* iface,
1890 VARIANT* var1 )
1892 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1893 HRESULT hr = S_FALSE;
1894 IXMLDOMSchemaCollection *cur_schema = This->schema;
1896 TRACE("(%p)->(%p)\n", This, var1);
1898 VariantInit(var1); /* Test shows we don't call VariantClear here */
1899 V_VT(var1) = VT_NULL;
1901 if(cur_schema)
1903 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1904 if(SUCCEEDED(hr))
1905 V_VT(var1) = VT_DISPATCH;
1907 return hr;
1910 static HRESULT WINAPI domdoc_putref_schemas(
1911 IXMLDOMDocument2* iface,
1912 VARIANT var1)
1914 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1915 HRESULT hr = E_FAIL;
1916 IXMLDOMSchemaCollection *new_schema = NULL;
1918 FIXME("(%p): semi-stub\n", This);
1919 switch(V_VT(&var1))
1921 case VT_UNKNOWN:
1922 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1923 break;
1925 case VT_DISPATCH:
1926 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1927 break;
1929 case VT_NULL:
1930 case VT_EMPTY:
1931 hr = S_OK;
1932 break;
1934 default:
1935 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1938 if(SUCCEEDED(hr))
1940 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1941 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1944 return hr;
1947 static HRESULT WINAPI domdoc_validate(
1948 IXMLDOMDocument2* iface,
1949 IXMLDOMParseError** err)
1951 FIXME("\n");
1952 return E_NOTIMPL;
1955 static HRESULT WINAPI domdoc_setProperty(
1956 IXMLDOMDocument2* iface,
1957 BSTR p,
1958 VARIANT var)
1960 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1962 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1964 VARIANT varStr;
1965 HRESULT hr;
1966 BSTR bstr;
1968 V_VT(&varStr) = VT_EMPTY;
1969 if (V_VT(&var) != VT_BSTR)
1971 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1972 return hr;
1973 bstr = V_BSTR(&varStr);
1975 else
1976 bstr = V_BSTR(&var);
1978 hr = S_OK;
1979 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1980 This->bUseXPath = TRUE;
1981 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1982 This->bUseXPath = FALSE;
1983 else
1984 hr = E_FAIL;
1986 VariantClear(&varStr);
1987 return hr;
1990 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1991 return E_FAIL;
1994 static HRESULT WINAPI domdoc_getProperty(
1995 IXMLDOMDocument2* iface,
1996 BSTR p,
1997 VARIANT* var)
1999 domdoc *This = impl_from_IXMLDOMDocument2( iface );
2001 if (var == NULL)
2002 return E_INVALIDARG;
2003 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
2005 V_VT(var) = VT_BSTR;
2006 if (This->bUseXPath)
2007 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
2008 else
2009 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
2010 return S_OK;
2013 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2014 return E_FAIL;
2017 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
2019 domdoc_QueryInterface,
2020 domdoc_AddRef,
2021 domdoc_Release,
2022 domdoc_GetTypeInfoCount,
2023 domdoc_GetTypeInfo,
2024 domdoc_GetIDsOfNames,
2025 domdoc_Invoke,
2026 domdoc_get_nodeName,
2027 domdoc_get_nodeValue,
2028 domdoc_put_nodeValue,
2029 domdoc_get_nodeType,
2030 domdoc_get_parentNode,
2031 domdoc_get_childNodes,
2032 domdoc_get_firstChild,
2033 domdoc_get_lastChild,
2034 domdoc_get_previousSibling,
2035 domdoc_get_nextSibling,
2036 domdoc_get_attributes,
2037 domdoc_insertBefore,
2038 domdoc_replaceChild,
2039 domdoc_removeChild,
2040 domdoc_appendChild,
2041 domdoc_hasChildNodes,
2042 domdoc_get_ownerDocument,
2043 domdoc_cloneNode,
2044 domdoc_get_nodeTypeString,
2045 domdoc_get_text,
2046 domdoc_put_text,
2047 domdoc_get_specified,
2048 domdoc_get_definition,
2049 domdoc_get_nodeTypedValue,
2050 domdoc_put_nodeTypedValue,
2051 domdoc_get_dataType,
2052 domdoc_put_dataType,
2053 domdoc_get_xml,
2054 domdoc_transformNode,
2055 domdoc_selectNodes,
2056 domdoc_selectSingleNode,
2057 domdoc_get_parsed,
2058 domdoc_get_namespaceURI,
2059 domdoc_get_prefix,
2060 domdoc_get_baseName,
2061 domdoc_transformNodeToObject,
2062 domdoc_get_doctype,
2063 domdoc_get_implementation,
2064 domdoc_get_documentElement,
2065 domdoc_put_documentElement,
2066 domdoc_createElement,
2067 domdoc_createDocumentFragment,
2068 domdoc_createTextNode,
2069 domdoc_createComment,
2070 domdoc_createCDATASection,
2071 domdoc_createProcessingInstruction,
2072 domdoc_createAttribute,
2073 domdoc_createEntityReference,
2074 domdoc_getElementsByTagName,
2075 domdoc_createNode,
2076 domdoc_nodeFromID,
2077 domdoc_load,
2078 domdoc_get_readyState,
2079 domdoc_get_parseError,
2080 domdoc_get_url,
2081 domdoc_get_async,
2082 domdoc_put_async,
2083 domdoc_abort,
2084 domdoc_loadXML,
2085 domdoc_save,
2086 domdoc_get_validateOnParse,
2087 domdoc_put_validateOnParse,
2088 domdoc_get_resolveExternals,
2089 domdoc_put_resolveExternals,
2090 domdoc_get_preserveWhiteSpace,
2091 domdoc_put_preserveWhiteSpace,
2092 domdoc_put_onReadyStateChange,
2093 domdoc_put_onDataAvailable,
2094 domdoc_put_onTransformNode,
2095 domdoc_get_namespaces,
2096 domdoc_get_schemas,
2097 domdoc_putref_schemas,
2098 domdoc_validate,
2099 domdoc_setProperty,
2100 domdoc_getProperty
2103 /* xmldoc implementation of IObjectWithSite */
2104 static HRESULT WINAPI
2105 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2107 domdoc *This = impl_from_IObjectWithSite(iface);
2108 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2111 static ULONG WINAPI
2112 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2114 domdoc *This = impl_from_IObjectWithSite(iface);
2115 return IXMLDocument_AddRef((IXMLDocument *)This);
2118 static ULONG WINAPI
2119 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2121 domdoc *This = impl_from_IObjectWithSite(iface);
2122 return IXMLDocument_Release((IXMLDocument *)This);
2125 static HRESULT WINAPI
2126 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2128 domdoc *This = impl_from_IObjectWithSite(iface);
2130 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2132 if ( !This->site )
2133 return E_FAIL;
2135 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2138 static HRESULT WINAPI
2139 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2141 domdoc *This = impl_from_IObjectWithSite(iface);
2143 TRACE("%p %p\n", iface, punk);
2145 if(!punk)
2147 if(This->site)
2149 IUnknown_Release( This->site );
2150 This->site = NULL;
2153 return S_OK;
2156 if ( punk )
2157 IUnknown_AddRef( punk );
2159 if(This->site)
2160 IUnknown_Release( This->site );
2162 This->site = punk;
2164 return S_OK;
2167 static const IObjectWithSiteVtbl domdocObjectSite =
2169 xmldoc_ObjectWithSite_QueryInterface,
2170 xmldoc_ObjectWithSite_AddRef,
2171 xmldoc_ObjectWithSite_Release,
2172 xmldoc_SetSite,
2173 xmldoc_GetSite,
2176 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2178 domdoc *This = impl_from_IObjectSafety(iface);
2179 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2182 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2184 domdoc *This = impl_from_IObjectSafety(iface);
2185 return IXMLDocument_AddRef((IXMLDocument *)This);
2188 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2190 domdoc *This = impl_from_IObjectSafety(iface);
2191 return IXMLDocument_Release((IXMLDocument *)This);
2194 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2196 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2197 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2199 domdoc *This = impl_from_IObjectSafety(iface);
2201 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2203 if(!pdwSupportedOptions || !pdwEnabledOptions)
2204 return E_POINTER;
2206 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2207 *pdwEnabledOptions = This->safeopt;
2209 return S_OK;
2212 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2213 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2215 domdoc *This = impl_from_IObjectSafety(iface);
2217 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2219 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2220 return E_FAIL;
2222 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2223 return S_OK;
2226 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2227 xmldoc_Safety_QueryInterface,
2228 xmldoc_Safety_AddRef,
2229 xmldoc_Safety_Release,
2230 xmldoc_Safety_GetInterfaceSafetyOptions,
2231 xmldoc_Safety_SetInterfaceSafetyOptions
2235 static const tid_t domdoc_iface_tids[] = {
2236 IXMLDOMNode_tid,
2237 IXMLDOMDocument_tid,
2238 IXMLDOMDocument2_tid,
2241 static dispex_static_data_t domdoc_dispex = {
2242 NULL,
2243 IXMLDOMDocument2_tid,
2244 NULL,
2245 domdoc_iface_tids
2248 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2250 domdoc *doc;
2252 doc = heap_alloc( sizeof (*doc) );
2253 if( !doc )
2254 return E_OUTOFMEMORY;
2256 doc->lpVtbl = &domdoc_vtbl;
2257 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2258 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2259 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2260 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2261 doc->ref = 1;
2262 doc->async = VARIANT_TRUE;
2263 doc->validating = 0;
2264 doc->resolving = 0;
2265 doc->preserving = 0;
2266 doc->bUseXPath = FALSE;
2267 doc->error = S_OK;
2268 doc->schema = NULL;
2269 doc->stream = NULL;
2270 doc->site = NULL;
2271 doc->safeopt = 0;
2272 doc->bsc = NULL;
2274 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2276 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2278 TRACE("returning iface %p\n", *document);
2279 return S_OK;
2282 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2284 xmlDocPtr xmldoc;
2285 HRESULT hr;
2287 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2289 xmldoc = xmlNewDoc(NULL);
2290 if(!xmldoc)
2291 return E_OUTOFMEMORY;
2293 xmldoc->_private = create_priv();
2295 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2296 if(FAILED(hr))
2297 xmlFreeDoc(xmldoc);
2299 return hr;
2302 IUnknown* create_domdoc( xmlNodePtr document )
2304 HRESULT hr;
2305 LPVOID pObj = NULL;
2307 TRACE("(%p)\n", document);
2309 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2310 if (FAILED(hr))
2311 return NULL;
2313 return pObj;
2316 #else
2318 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2320 MESSAGE("This program tried to use a DOMDocument object, but\n"
2321 "libxml2 support was not present at compile time.\n");
2322 return E_NOTIMPL;
2325 #endif