msxml3: Support more node types in IXMLDOMDocument_createNode().
[wine.git] / dlls / msxml3 / domdoc.c
blob6c808442c9874c2c90c35cd3673c3869d6f10732
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 xmlNodePtr xmlnode;
1042 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1043 xmlChar *xml_name;
1044 IUnknown *elem_unk;
1045 HRESULT hr;
1047 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1049 if (!element) return E_INVALIDARG;
1051 xml_name = xmlChar_from_wchar(tagname);
1052 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1053 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1055 TRACE("created xmlptr %p\n", xmlnode);
1056 elem_unk = create_element(xmlnode);
1057 heap_free(xml_name);
1059 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1060 IUnknown_Release(elem_unk);
1061 TRACE("returning %p\n", *element);
1062 return hr;
1066 static HRESULT WINAPI domdoc_createDocumentFragment(
1067 IXMLDOMDocument2 *iface,
1068 IXMLDOMDocumentFragment** docFrag )
1070 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1071 xmlNodePtr xmlnode;
1073 TRACE("%p\n", iface);
1075 if(!docFrag)
1076 return E_INVALIDARG;
1078 *docFrag = NULL;
1080 xmlnode = xmlNewDocFragment(get_doc( This ) );
1082 if(!xmlnode)
1083 return E_FAIL;
1085 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1086 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1088 return S_OK;
1092 static HRESULT WINAPI domdoc_createTextNode(
1093 IXMLDOMDocument2 *iface,
1094 BSTR data,
1095 IXMLDOMText** text )
1097 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1098 xmlNodePtr xmlnode;
1099 xmlChar *xml_content;
1101 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1103 if(!text)
1104 return E_INVALIDARG;
1106 *text = NULL;
1108 xml_content = xmlChar_from_wchar(data);
1109 xmlnode = xmlNewText(xml_content);
1110 heap_free(xml_content);
1112 if(!xmlnode)
1113 return E_FAIL;
1115 xmlnode->doc = get_doc( This );
1116 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1118 *text = (IXMLDOMText*)create_text(xmlnode);
1120 return S_OK;
1124 static HRESULT WINAPI domdoc_createComment(
1125 IXMLDOMDocument2 *iface,
1126 BSTR data,
1127 IXMLDOMComment** comment )
1129 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1130 xmlNodePtr xmlnode;
1131 xmlChar *xml_content;
1133 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1135 if(!comment)
1136 return E_INVALIDARG;
1138 *comment = NULL;
1140 xml_content = xmlChar_from_wchar(data);
1141 xmlnode = xmlNewComment(xml_content);
1142 heap_free(xml_content);
1144 if(!xmlnode)
1145 return E_FAIL;
1147 xmlnode->doc = get_doc( This );
1148 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1150 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1152 return S_OK;
1156 static HRESULT WINAPI domdoc_createCDATASection(
1157 IXMLDOMDocument2 *iface,
1158 BSTR data,
1159 IXMLDOMCDATASection** cdata )
1161 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1162 xmlNodePtr xmlnode;
1163 xmlChar *xml_content;
1165 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1167 if(!cdata)
1168 return E_INVALIDARG;
1170 *cdata = NULL;
1172 xml_content = xmlChar_from_wchar(data);
1173 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1174 heap_free(xml_content);
1176 if(!xmlnode)
1177 return E_FAIL;
1179 xmlnode->doc = get_doc( This );
1180 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1182 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1184 return S_OK;
1188 static HRESULT WINAPI domdoc_createProcessingInstruction(
1189 IXMLDOMDocument2 *iface,
1190 BSTR target,
1191 BSTR data,
1192 IXMLDOMProcessingInstruction** pi )
1194 #ifdef HAVE_XMLNEWDOCPI
1195 xmlNodePtr xmlnode;
1196 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1197 xmlChar *xml_target, *xml_content;
1199 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1201 if(!pi)
1202 return E_INVALIDARG;
1204 if(!target || lstrlenW(target) == 0)
1205 return E_FAIL;
1207 xml_target = xmlChar_from_wchar(target);
1208 xml_content = xmlChar_from_wchar(data);
1210 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1211 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1212 TRACE("created xmlptr %p\n", xmlnode);
1213 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1215 heap_free(xml_content);
1216 heap_free(xml_target);
1218 return S_OK;
1219 #else
1220 FIXME("Libxml 2.6.15 or greater required.\n");
1221 return E_NOTIMPL;
1222 #endif
1226 static HRESULT WINAPI domdoc_createAttribute(
1227 IXMLDOMDocument2 *iface,
1228 BSTR name,
1229 IXMLDOMAttribute** attribute )
1231 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1232 xmlNodePtr xmlnode;
1233 xmlChar *xml_name;
1235 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1237 if(!attribute)
1238 return E_INVALIDARG;
1240 *attribute = NULL;
1242 xml_name = xmlChar_from_wchar(name);
1243 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1244 heap_free(xml_name);
1246 if(!xmlnode)
1247 return E_FAIL;
1249 xmlnode->doc = get_doc( This );
1250 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1252 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1254 return S_OK;
1258 static HRESULT WINAPI domdoc_createEntityReference(
1259 IXMLDOMDocument2 *iface,
1260 BSTR name,
1261 IXMLDOMEntityReference** entityRef )
1263 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1264 xmlNodePtr xmlnode;
1265 xmlChar *xml_name;
1267 TRACE("%p\n", iface);
1269 if(!entityRef)
1270 return E_INVALIDARG;
1272 *entityRef = NULL;
1274 xml_name = xmlChar_from_wchar(name);
1275 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1276 heap_free(xml_name);
1278 if(!xmlnode)
1279 return E_FAIL;
1281 xmlnode->doc = get_doc( This );
1282 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1284 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1286 return S_OK;
1290 static HRESULT WINAPI domdoc_getElementsByTagName(
1291 IXMLDOMDocument2 *iface,
1292 BSTR tagName,
1293 IXMLDOMNodeList** resultList )
1295 static const WCHAR xpathformat[] =
1296 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1297 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1298 LPWSTR szPattern;
1299 HRESULT hr;
1300 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1302 if (tagName[0] == '*' && tagName[1] == 0)
1304 szPattern = heap_alloc(sizeof(WCHAR)*4);
1305 szPattern[0] = szPattern[1] = '/';
1306 szPattern[2] = '*';
1307 szPattern[3] = 0;
1309 else
1311 szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1312 wsprintfW(szPattern, xpathformat, tagName);
1315 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1316 heap_free(szPattern);
1318 return hr;
1321 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1323 VARIANT tmp;
1324 HRESULT hr;
1326 VariantInit(&tmp);
1327 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1328 if(FAILED(hr))
1329 return E_INVALIDARG;
1331 *type = V_I4(&tmp);
1333 return S_OK;
1336 static HRESULT WINAPI domdoc_createNode(
1337 IXMLDOMDocument2 *iface,
1338 VARIANT Type,
1339 BSTR name,
1340 BSTR namespaceURI,
1341 IXMLDOMNode** node )
1343 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1344 DOMNodeType node_type;
1345 xmlNodePtr xmlnode;
1346 xmlChar *xml_name;
1347 HRESULT hr;
1349 TRACE("(%p)->(%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1351 if(!node) return E_INVALIDARG;
1353 if(namespaceURI && namespaceURI[0])
1354 FIXME("nodes with namespaces currently not supported.\n");
1356 hr = get_node_type(Type, &node_type);
1357 if(FAILED(hr)) return hr;
1359 TRACE("node_type %d\n", node_type);
1361 xml_name = xmlChar_from_wchar(name);
1363 switch(node_type)
1365 case NODE_ELEMENT:
1366 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1367 break;
1368 case NODE_ATTRIBUTE:
1369 xmlnode = (xmlNodePtr)xmlNewDocProp(get_doc(This), xml_name, NULL);
1370 break;
1371 case NODE_TEXT:
1372 xmlnode = (xmlNodePtr)xmlNewDocText(get_doc(This), NULL);
1373 break;
1374 case NODE_CDATA_SECTION:
1375 xmlnode = xmlNewCDataBlock(get_doc(This), NULL, 0);
1376 break;
1377 case NODE_PROCESSING_INSTRUCTION:
1378 #ifdef HAVE_XMLNEWDOCPI
1379 xmlnode = xmlNewDocPI(get_doc(This), xml_name, NULL);
1380 #else
1381 FIXME("xmlNewDocPI() not supported, use libxml2 2.6.15 or greater\n");
1382 xmlnode = NULL;
1383 #endif
1384 break;
1385 case NODE_COMMENT:
1386 xmlnode = xmlNewDocComment(get_doc(This), NULL);
1387 break;
1388 case NODE_DOCUMENT_FRAGMENT:
1389 xmlnode = xmlNewDocFragment(get_doc(This));
1390 break;
1391 /* unsupported types */
1392 case NODE_DOCUMENT:
1393 case NODE_DOCUMENT_TYPE:
1394 case NODE_ENTITY:
1395 case NODE_NOTATION:
1396 heap_free(xml_name);
1397 return E_INVALIDARG;
1398 default:
1399 FIXME("unhandled node type %d\n", node_type);
1400 xmlnode = NULL;
1401 break;
1404 *node = create_node(xmlnode);
1405 heap_free(xml_name);
1407 if(*node)
1409 TRACE("created node (%d, %p, %p)\n", node_type, *node, xmlnode);
1410 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1411 return S_OK;
1414 return E_FAIL;
1417 static HRESULT WINAPI domdoc_nodeFromID(
1418 IXMLDOMDocument2 *iface,
1419 BSTR idString,
1420 IXMLDOMNode** node )
1422 FIXME("\n");
1423 return E_NOTIMPL;
1426 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1428 domdoc *This = obj;
1429 xmlDocPtr xmldoc;
1431 xmldoc = doparse( ptr, len );
1432 if(xmldoc) {
1433 xmldoc->_private = create_priv();
1434 return attach_xmldoc(&This->node, xmldoc);
1437 return S_OK;
1440 static HRESULT doread( domdoc *This, LPWSTR filename )
1442 bsc_t *bsc;
1443 HRESULT hr;
1445 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1446 if(FAILED(hr))
1447 return hr;
1449 if(This->bsc)
1450 detach_bsc(This->bsc);
1452 This->bsc = bsc;
1453 return S_OK;
1456 static HRESULT WINAPI domdoc_load(
1457 IXMLDOMDocument2 *iface,
1458 VARIANT xmlSource,
1459 VARIANT_BOOL* isSuccessful )
1461 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1462 LPWSTR filename = NULL;
1463 HRESULT hr = S_FALSE;
1464 IXMLDOMDocument2 *pNewDoc = NULL;
1465 IStream *pStream = NULL;
1466 xmlDocPtr xmldoc;
1468 TRACE("type %d\n", V_VT(&xmlSource) );
1470 *isSuccessful = VARIANT_FALSE;
1472 assert( &This->node );
1474 switch( V_VT(&xmlSource) )
1476 case VT_BSTR:
1477 filename = V_BSTR(&xmlSource);
1478 break;
1479 case VT_UNKNOWN:
1480 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1481 if(hr == S_OK)
1483 if(pNewDoc)
1485 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1486 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1487 hr = attach_xmldoc(&This->node, xmldoc);
1489 if(SUCCEEDED(hr))
1490 *isSuccessful = VARIANT_TRUE;
1492 return hr;
1495 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1496 if(hr == S_OK)
1498 IPersistStream *pDocStream;
1499 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1500 if(hr == S_OK)
1502 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1503 IStream_Release(pStream);
1504 if(hr == S_OK)
1506 *isSuccessful = VARIANT_TRUE;
1508 TRACE("Using ID_IStream to load Document\n");
1509 return S_OK;
1511 else
1513 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1516 else
1518 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1521 else
1523 /* ISequentialStream */
1524 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1526 break;
1527 default:
1528 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1531 TRACE("filename (%s)\n", debugstr_w(filename));
1533 if ( filename )
1535 hr = doread( This, filename );
1537 if ( FAILED(hr) )
1538 This->error = E_FAIL;
1539 else
1541 hr = This->error = S_OK;
1542 *isSuccessful = VARIANT_TRUE;
1546 if(!filename || FAILED(hr)) {
1547 xmldoc = xmlNewDoc(NULL);
1548 xmldoc->_private = create_priv();
1549 hr = attach_xmldoc(&This->node, xmldoc);
1550 if(SUCCEEDED(hr))
1551 hr = S_FALSE;
1554 TRACE("ret (%d)\n", hr);
1556 return hr;
1560 static HRESULT WINAPI domdoc_get_readyState(
1561 IXMLDOMDocument2 *iface,
1562 LONG *value )
1564 FIXME("\n");
1565 return E_NOTIMPL;
1569 static HRESULT WINAPI domdoc_get_parseError(
1570 IXMLDOMDocument2 *iface,
1571 IXMLDOMParseError** errorObj )
1573 BSTR error_string = NULL;
1574 static const WCHAR err[] = {'e','r','r','o','r',0};
1575 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1577 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1579 if(This->error)
1580 error_string = SysAllocString(err);
1582 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1583 if(!*errorObj) return E_OUTOFMEMORY;
1584 return S_OK;
1588 static HRESULT WINAPI domdoc_get_url(
1589 IXMLDOMDocument2 *iface,
1590 BSTR* urlString )
1592 FIXME("\n");
1593 return E_NOTIMPL;
1597 static HRESULT WINAPI domdoc_get_async(
1598 IXMLDOMDocument2 *iface,
1599 VARIANT_BOOL* isAsync )
1601 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1603 TRACE("%p <- %d\n", isAsync, This->async);
1604 *isAsync = This->async;
1605 return S_OK;
1609 static HRESULT WINAPI domdoc_put_async(
1610 IXMLDOMDocument2 *iface,
1611 VARIANT_BOOL isAsync )
1613 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1615 TRACE("%d\n", isAsync);
1616 This->async = isAsync;
1617 return S_OK;
1621 static HRESULT WINAPI domdoc_abort(
1622 IXMLDOMDocument2 *iface )
1624 FIXME("\n");
1625 return E_NOTIMPL;
1629 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1631 UINT len, blen = SysStringLen( bstr );
1632 LPSTR str;
1634 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1635 str = heap_alloc( len );
1636 if ( !str )
1637 return FALSE;
1638 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1639 *plen = len;
1640 *pstr = str;
1641 return TRUE;
1644 static HRESULT WINAPI domdoc_loadXML(
1645 IXMLDOMDocument2 *iface,
1646 BSTR bstrXML,
1647 VARIANT_BOOL* isSuccessful )
1649 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1650 xmlDocPtr xmldoc = NULL;
1651 char *str;
1652 int len;
1653 HRESULT hr = S_FALSE, hr2;
1655 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1657 assert ( &This->node );
1659 if ( isSuccessful )
1661 *isSuccessful = VARIANT_FALSE;
1663 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1665 xmldoc = doparse( str, len );
1666 heap_free( str );
1667 if ( !xmldoc )
1668 This->error = E_FAIL;
1669 else
1671 hr = This->error = S_OK;
1672 *isSuccessful = VARIANT_TRUE;
1676 if(!xmldoc)
1677 xmldoc = xmlNewDoc(NULL);
1679 xmldoc->_private = create_priv();
1680 hr2 = attach_xmldoc( &This->node, xmldoc );
1681 if( FAILED(hr2) )
1682 hr = hr2;
1684 return hr;
1687 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1688 int len)
1690 DWORD written = -1;
1692 if(!WriteFile(ctx, buffer, len, &written, NULL))
1694 WARN("write error\n");
1695 return -1;
1697 else
1698 return written;
1701 static int XMLCALL domdoc_save_closecallback(void *ctx)
1703 return CloseHandle(ctx) ? 0 : -1;
1706 static HRESULT WINAPI domdoc_save(
1707 IXMLDOMDocument2 *iface,
1708 VARIANT destination )
1710 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1711 HANDLE handle;
1712 xmlSaveCtxtPtr ctx;
1713 HRESULT ret = S_OK;
1715 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1716 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1718 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1720 FIXME("Unhandled vt %d\n", V_VT(&destination));
1721 return S_FALSE;
1724 if(V_VT(&destination) == VT_UNKNOWN)
1726 IUnknown *pUnk = V_UNKNOWN(&destination);
1727 IXMLDOMDocument *pDocument;
1729 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1730 if(ret == S_OK)
1732 BSTR bXML;
1733 VARIANT_BOOL bSuccessful;
1735 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1736 if(ret == S_OK)
1738 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1740 SysFreeString(bXML);
1743 IXMLDOMDocument_Release(pDocument);
1746 TRACE("ret %d\n", ret);
1748 return ret;
1751 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1752 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1753 if( handle == INVALID_HANDLE_VALUE )
1755 WARN("failed to create file\n");
1756 return S_FALSE;
1759 /* disable top XML declaration */
1760 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1761 handle, NULL, XML_SAVE_NO_DECL);
1762 if (!ctx)
1764 CloseHandle(handle);
1765 return S_FALSE;
1768 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1769 /* will close file through close callback */
1770 xmlSaveClose(ctx);
1772 return ret;
1775 static HRESULT WINAPI domdoc_get_validateOnParse(
1776 IXMLDOMDocument2 *iface,
1777 VARIANT_BOOL* isValidating )
1779 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1781 TRACE("%p <- %d\n", isValidating, This->validating);
1782 *isValidating = This->validating;
1783 return S_OK;
1787 static HRESULT WINAPI domdoc_put_validateOnParse(
1788 IXMLDOMDocument2 *iface,
1789 VARIANT_BOOL isValidating )
1791 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1793 TRACE("%d\n", isValidating);
1794 This->validating = isValidating;
1795 return S_OK;
1799 static HRESULT WINAPI domdoc_get_resolveExternals(
1800 IXMLDOMDocument2 *iface,
1801 VARIANT_BOOL* isResolving )
1803 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1805 TRACE("%p <- %d\n", isResolving, This->resolving);
1806 *isResolving = This->resolving;
1807 return S_OK;
1811 static HRESULT WINAPI domdoc_put_resolveExternals(
1812 IXMLDOMDocument2 *iface,
1813 VARIANT_BOOL isResolving )
1815 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1817 TRACE("%d\n", isResolving);
1818 This->resolving = isResolving;
1819 return S_OK;
1823 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1824 IXMLDOMDocument2 *iface,
1825 VARIANT_BOOL* isPreserving )
1827 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1829 TRACE("%p <- %d\n", isPreserving, This->preserving);
1830 *isPreserving = This->preserving;
1831 return S_OK;
1835 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1836 IXMLDOMDocument2 *iface,
1837 VARIANT_BOOL isPreserving )
1839 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1841 TRACE("%d\n", isPreserving);
1842 This->preserving = isPreserving;
1843 return S_OK;
1847 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1848 IXMLDOMDocument2 *iface,
1849 VARIANT readyStateChangeSink )
1851 FIXME("\n");
1852 return E_NOTIMPL;
1856 static HRESULT WINAPI domdoc_put_onDataAvailable(
1857 IXMLDOMDocument2 *iface,
1858 VARIANT onDataAvailableSink )
1860 FIXME("\n");
1861 return E_NOTIMPL;
1864 static HRESULT WINAPI domdoc_put_onTransformNode(
1865 IXMLDOMDocument2 *iface,
1866 VARIANT onTransformNodeSink )
1868 FIXME("\n");
1869 return E_NOTIMPL;
1872 static HRESULT WINAPI domdoc_get_namespaces(
1873 IXMLDOMDocument2* iface,
1874 IXMLDOMSchemaCollection** schemaCollection )
1876 FIXME("\n");
1877 return E_NOTIMPL;
1880 static HRESULT WINAPI domdoc_get_schemas(
1881 IXMLDOMDocument2* iface,
1882 VARIANT* var1 )
1884 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1885 HRESULT hr = S_FALSE;
1886 IXMLDOMSchemaCollection *cur_schema = This->schema;
1888 TRACE("(%p)->(%p)\n", This, var1);
1890 VariantInit(var1); /* Test shows we don't call VariantClear here */
1891 V_VT(var1) = VT_NULL;
1893 if(cur_schema)
1895 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1896 if(SUCCEEDED(hr))
1897 V_VT(var1) = VT_DISPATCH;
1899 return hr;
1902 static HRESULT WINAPI domdoc_putref_schemas(
1903 IXMLDOMDocument2* iface,
1904 VARIANT var1)
1906 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1907 HRESULT hr = E_FAIL;
1908 IXMLDOMSchemaCollection *new_schema = NULL;
1910 FIXME("(%p): semi-stub\n", This);
1911 switch(V_VT(&var1))
1913 case VT_UNKNOWN:
1914 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1915 break;
1917 case VT_DISPATCH:
1918 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1919 break;
1921 case VT_NULL:
1922 case VT_EMPTY:
1923 hr = S_OK;
1924 break;
1926 default:
1927 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1930 if(SUCCEEDED(hr))
1932 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1933 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1936 return hr;
1939 static HRESULT WINAPI domdoc_validate(
1940 IXMLDOMDocument2* iface,
1941 IXMLDOMParseError** err)
1943 FIXME("\n");
1944 return E_NOTIMPL;
1947 static HRESULT WINAPI domdoc_setProperty(
1948 IXMLDOMDocument2* iface,
1949 BSTR p,
1950 VARIANT var)
1952 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1954 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1956 VARIANT varStr;
1957 HRESULT hr;
1958 BSTR bstr;
1960 V_VT(&varStr) = VT_EMPTY;
1961 if (V_VT(&var) != VT_BSTR)
1963 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1964 return hr;
1965 bstr = V_BSTR(&varStr);
1967 else
1968 bstr = V_BSTR(&var);
1970 hr = S_OK;
1971 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1972 This->bUseXPath = TRUE;
1973 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1974 This->bUseXPath = FALSE;
1975 else
1976 hr = E_FAIL;
1978 VariantClear(&varStr);
1979 return hr;
1982 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1983 return E_FAIL;
1986 static HRESULT WINAPI domdoc_getProperty(
1987 IXMLDOMDocument2* iface,
1988 BSTR p,
1989 VARIANT* var)
1991 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1993 if (var == NULL)
1994 return E_INVALIDARG;
1995 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1997 V_VT(var) = VT_BSTR;
1998 if (This->bUseXPath)
1999 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
2000 else
2001 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
2002 return S_OK;
2005 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
2006 return E_FAIL;
2009 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
2011 domdoc_QueryInterface,
2012 domdoc_AddRef,
2013 domdoc_Release,
2014 domdoc_GetTypeInfoCount,
2015 domdoc_GetTypeInfo,
2016 domdoc_GetIDsOfNames,
2017 domdoc_Invoke,
2018 domdoc_get_nodeName,
2019 domdoc_get_nodeValue,
2020 domdoc_put_nodeValue,
2021 domdoc_get_nodeType,
2022 domdoc_get_parentNode,
2023 domdoc_get_childNodes,
2024 domdoc_get_firstChild,
2025 domdoc_get_lastChild,
2026 domdoc_get_previousSibling,
2027 domdoc_get_nextSibling,
2028 domdoc_get_attributes,
2029 domdoc_insertBefore,
2030 domdoc_replaceChild,
2031 domdoc_removeChild,
2032 domdoc_appendChild,
2033 domdoc_hasChildNodes,
2034 domdoc_get_ownerDocument,
2035 domdoc_cloneNode,
2036 domdoc_get_nodeTypeString,
2037 domdoc_get_text,
2038 domdoc_put_text,
2039 domdoc_get_specified,
2040 domdoc_get_definition,
2041 domdoc_get_nodeTypedValue,
2042 domdoc_put_nodeTypedValue,
2043 domdoc_get_dataType,
2044 domdoc_put_dataType,
2045 domdoc_get_xml,
2046 domdoc_transformNode,
2047 domdoc_selectNodes,
2048 domdoc_selectSingleNode,
2049 domdoc_get_parsed,
2050 domdoc_get_namespaceURI,
2051 domdoc_get_prefix,
2052 domdoc_get_baseName,
2053 domdoc_transformNodeToObject,
2054 domdoc_get_doctype,
2055 domdoc_get_implementation,
2056 domdoc_get_documentElement,
2057 domdoc_put_documentElement,
2058 domdoc_createElement,
2059 domdoc_createDocumentFragment,
2060 domdoc_createTextNode,
2061 domdoc_createComment,
2062 domdoc_createCDATASection,
2063 domdoc_createProcessingInstruction,
2064 domdoc_createAttribute,
2065 domdoc_createEntityReference,
2066 domdoc_getElementsByTagName,
2067 domdoc_createNode,
2068 domdoc_nodeFromID,
2069 domdoc_load,
2070 domdoc_get_readyState,
2071 domdoc_get_parseError,
2072 domdoc_get_url,
2073 domdoc_get_async,
2074 domdoc_put_async,
2075 domdoc_abort,
2076 domdoc_loadXML,
2077 domdoc_save,
2078 domdoc_get_validateOnParse,
2079 domdoc_put_validateOnParse,
2080 domdoc_get_resolveExternals,
2081 domdoc_put_resolveExternals,
2082 domdoc_get_preserveWhiteSpace,
2083 domdoc_put_preserveWhiteSpace,
2084 domdoc_put_onReadyStateChange,
2085 domdoc_put_onDataAvailable,
2086 domdoc_put_onTransformNode,
2087 domdoc_get_namespaces,
2088 domdoc_get_schemas,
2089 domdoc_putref_schemas,
2090 domdoc_validate,
2091 domdoc_setProperty,
2092 domdoc_getProperty
2095 /* xmldoc implementation of IObjectWithSite */
2096 static HRESULT WINAPI
2097 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2099 domdoc *This = impl_from_IObjectWithSite(iface);
2100 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2103 static ULONG WINAPI
2104 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2106 domdoc *This = impl_from_IObjectWithSite(iface);
2107 return IXMLDocument_AddRef((IXMLDocument *)This);
2110 static ULONG WINAPI
2111 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2113 domdoc *This = impl_from_IObjectWithSite(iface);
2114 return IXMLDocument_Release((IXMLDocument *)This);
2117 static HRESULT WINAPI
2118 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2120 domdoc *This = impl_from_IObjectWithSite(iface);
2122 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2124 if ( !This->site )
2125 return E_FAIL;
2127 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2130 static HRESULT WINAPI
2131 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2133 domdoc *This = impl_from_IObjectWithSite(iface);
2135 TRACE("%p %p\n", iface, punk);
2137 if(!punk)
2139 if(This->site)
2141 IUnknown_Release( This->site );
2142 This->site = NULL;
2145 return S_OK;
2148 if ( punk )
2149 IUnknown_AddRef( punk );
2151 if(This->site)
2152 IUnknown_Release( This->site );
2154 This->site = punk;
2156 return S_OK;
2159 static const IObjectWithSiteVtbl domdocObjectSite =
2161 xmldoc_ObjectWithSite_QueryInterface,
2162 xmldoc_ObjectWithSite_AddRef,
2163 xmldoc_ObjectWithSite_Release,
2164 xmldoc_SetSite,
2165 xmldoc_GetSite,
2168 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2170 domdoc *This = impl_from_IObjectSafety(iface);
2171 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2174 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2176 domdoc *This = impl_from_IObjectSafety(iface);
2177 return IXMLDocument_AddRef((IXMLDocument *)This);
2180 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2182 domdoc *This = impl_from_IObjectSafety(iface);
2183 return IXMLDocument_Release((IXMLDocument *)This);
2186 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2188 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2189 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2191 domdoc *This = impl_from_IObjectSafety(iface);
2193 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2195 if(!pdwSupportedOptions || !pdwEnabledOptions)
2196 return E_POINTER;
2198 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2199 *pdwEnabledOptions = This->safeopt;
2201 return S_OK;
2204 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2205 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2207 domdoc *This = impl_from_IObjectSafety(iface);
2209 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2211 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2212 return E_FAIL;
2214 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2215 return S_OK;
2218 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2219 xmldoc_Safety_QueryInterface,
2220 xmldoc_Safety_AddRef,
2221 xmldoc_Safety_Release,
2222 xmldoc_Safety_GetInterfaceSafetyOptions,
2223 xmldoc_Safety_SetInterfaceSafetyOptions
2227 static const tid_t domdoc_iface_tids[] = {
2228 IXMLDOMNode_tid,
2229 IXMLDOMDocument_tid,
2230 IXMLDOMDocument2_tid,
2233 static dispex_static_data_t domdoc_dispex = {
2234 NULL,
2235 IXMLDOMDocument2_tid,
2236 NULL,
2237 domdoc_iface_tids
2240 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2242 domdoc *doc;
2244 doc = heap_alloc( sizeof (*doc) );
2245 if( !doc )
2246 return E_OUTOFMEMORY;
2248 doc->lpVtbl = &domdoc_vtbl;
2249 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2250 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2251 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2252 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2253 doc->ref = 1;
2254 doc->async = VARIANT_TRUE;
2255 doc->validating = 0;
2256 doc->resolving = 0;
2257 doc->preserving = 0;
2258 doc->bUseXPath = FALSE;
2259 doc->error = S_OK;
2260 doc->schema = NULL;
2261 doc->stream = NULL;
2262 doc->site = NULL;
2263 doc->safeopt = 0;
2264 doc->bsc = NULL;
2266 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2268 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2270 TRACE("returning iface %p\n", *document);
2271 return S_OK;
2274 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2276 xmlDocPtr xmldoc;
2277 HRESULT hr;
2279 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2281 xmldoc = xmlNewDoc(NULL);
2282 if(!xmldoc)
2283 return E_OUTOFMEMORY;
2285 xmldoc->_private = create_priv();
2287 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2288 if(FAILED(hr))
2289 xmlFreeDoc(xmldoc);
2291 return hr;
2294 IUnknown* create_domdoc( xmlNodePtr document )
2296 HRESULT hr;
2297 LPVOID pObj = NULL;
2299 TRACE("(%p)\n", document);
2301 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2302 if (FAILED(hr))
2303 return NULL;
2305 return pObj;
2308 #else
2310 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2312 MESSAGE("This program tried to use a DOMDocument object, but\n"
2313 "libxml2 support was not present at compile time.\n");
2314 return E_NOTIMPL;
2317 #endif