Release 1.1.37.
[wine/gsoc-2012-control.git] / dlls / msxml3 / domdoc.c
blobe75537f0c55e95bf92721818eee071d530b98141
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 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};
51 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
52 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
54 typedef struct _domdoc
56 xmlnode node;
57 const struct IXMLDOMDocument2Vtbl *lpVtbl;
58 const struct IPersistStreamVtbl *lpvtblIPersistStream;
59 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
60 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
61 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
62 LONG ref;
63 VARIANT_BOOL async;
64 VARIANT_BOOL validating;
65 VARIANT_BOOL resolving;
66 VARIANT_BOOL preserving;
67 BOOL bUseXPath;
68 IXMLDOMSchemaCollection *schema;
69 bsc_t *bsc;
70 HRESULT error;
72 /* IPersistStream */
73 IStream *stream;
75 /* IObjectWithSite*/
76 IUnknown *site;
78 /* IObjectSafety */
79 DWORD safeopt;
80 } domdoc;
83 In native windows, the whole lifetime management of XMLDOMNodes is
84 managed automatically using reference counts. Wine emulates that by
85 maintaining a reference count to the document that is increased for
86 each IXMLDOMNode pointer passed out for this document. If all these
87 pointers are gone, the document is unreachable and gets freed, that
88 is, all nodes in the tree of the document get freed.
90 You are able to create nodes that are associated to a document (in
91 fact, in msxml's XMLDOM model, all nodes are associated to a document),
92 but not in the tree of that document, for example using the createFoo
93 functions from IXMLDOMDocument. These nodes do not get cleaned up
94 by libxml, so we have to do it ourselves.
96 To catch these nodes, a list of "orphan nodes" is introduced.
97 It contains pointers to all roots of node trees that are
98 associated with the document without being part of the document
99 tree. All nodes with parent==NULL (except for the document root nodes)
100 should be in the orphan node list of their document. All orphan nodes
101 get freed together with the document itself.
104 typedef struct _xmldoc_priv {
105 LONG refs;
106 struct list orphans;
107 } xmldoc_priv;
109 typedef struct _orphan_entry {
110 struct list entry;
111 xmlNode * node;
112 } orphan_entry;
114 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
116 return doc->_private;
119 static xmldoc_priv * create_priv(void)
121 xmldoc_priv *priv;
122 priv = HeapAlloc( GetProcessHeap(), 0, sizeof (*priv) );
124 if(priv)
126 priv->refs = 0;
127 list_init( &priv->orphans );
130 return priv;
133 static xmlDocPtr doparse( char *ptr, int len )
135 #ifdef HAVE_XMLREADMEMORY
137 * use xmlReadMemory if possible so we can suppress
138 * writing errors to stderr
140 return xmlReadMemory( ptr, len, NULL, NULL,
141 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
142 #else
143 return xmlParseMemory( ptr, len );
144 #endif
147 LONG xmldoc_add_ref(xmlDocPtr doc)
149 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
150 TRACE("%d\n", ref);
151 return ref;
154 LONG xmldoc_release(xmlDocPtr doc)
156 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
157 LONG ref = InterlockedDecrement(&priv->refs);
158 TRACE("%d\n", ref);
159 if(ref == 0)
161 orphan_entry *orphan, *orphan2;
162 TRACE("freeing docptr %p\n", doc);
164 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
166 xmlFreeNode( orphan->node );
167 HeapFree( GetProcessHeap(), 0, orphan );
169 HeapFree(GetProcessHeap(), 0, doc->_private);
171 xmlFreeDoc(doc);
174 return ref;
177 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
179 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
180 orphan_entry *entry;
182 entry = HeapAlloc( GetProcessHeap(), 0, sizeof (*entry) );
183 if(!entry)
184 return E_OUTOFMEMORY;
186 entry->node = node;
187 list_add_head( &priv->orphans, &entry->entry );
188 return S_OK;
191 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
193 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
194 orphan_entry *entry, *entry2;
196 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
198 if( entry->node == node )
200 list_remove( &entry->entry );
201 HeapFree( GetProcessHeap(), 0, entry );
202 return S_OK;
206 return S_FALSE;
209 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
211 if(node->node)
212 xmldoc_release(node->node->doc);
214 node->node = (xmlNodePtr) xml;
215 if(node->node)
216 xmldoc_add_ref(node->node->doc);
218 return S_OK;
221 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
223 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
226 static inline xmlDocPtr get_doc( domdoc *This )
228 return (xmlDocPtr)This->node.node;
231 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
233 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
236 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
238 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
241 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
243 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
246 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
248 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
251 /************************************************************************
252 * xmldoc implementation of IPersistStream.
254 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
255 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
257 domdoc *this = impl_from_IPersistStream(iface);
258 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
261 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
262 IPersistStream *iface)
264 domdoc *this = impl_from_IPersistStream(iface);
265 return IXMLDocument_AddRef((IXMLDocument *)this);
268 static ULONG WINAPI xmldoc_IPersistStream_Release(
269 IPersistStream *iface)
271 domdoc *this = impl_from_IPersistStream(iface);
272 return IXMLDocument_Release((IXMLDocument *)this);
275 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
276 IPersistStream *iface, CLSID *classid)
278 TRACE("(%p,%p): stub!\n", iface, classid);
280 if(!classid)
281 return E_POINTER;
283 *classid = CLSID_DOMDocument2;
285 return S_OK;
288 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
289 IPersistStream *iface)
291 domdoc *This = impl_from_IPersistStream(iface);
293 FIXME("(%p->%p): stub!\n", iface, This);
295 return S_FALSE;
298 static HRESULT WINAPI xmldoc_IPersistStream_Load(
299 IPersistStream *iface, LPSTREAM pStm)
301 domdoc *This = impl_from_IPersistStream(iface);
302 HRESULT hr;
303 HGLOBAL hglobal;
304 DWORD read, written, len;
305 BYTE buf[4096];
306 char *ptr;
307 xmlDocPtr xmldoc = NULL;
309 TRACE("(%p, %p)\n", iface, pStm);
311 if (!pStm)
312 return E_INVALIDARG;
314 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
315 if (FAILED(hr))
316 return hr;
320 IStream_Read(pStm, buf, sizeof(buf), &read);
321 hr = IStream_Write(This->stream, buf, read, &written);
322 } while(SUCCEEDED(hr) && written != 0 && read != 0);
324 if (FAILED(hr))
326 ERR("Failed to copy stream\n");
327 return hr;
330 hr = GetHGlobalFromStream(This->stream, &hglobal);
331 if (FAILED(hr))
332 return hr;
334 len = GlobalSize(hglobal);
335 ptr = GlobalLock(hglobal);
336 if (len != 0)
337 xmldoc = parse_xml(ptr, len);
338 GlobalUnlock(hglobal);
340 if (!xmldoc)
342 ERR("Failed to parse xml\n");
343 return E_FAIL;
346 xmldoc->_private = create_priv();
348 return attach_xmldoc( &This->node, xmldoc );
351 static HRESULT WINAPI xmldoc_IPersistStream_Save(
352 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
354 domdoc *This = impl_from_IPersistStream(iface);
355 HRESULT hr;
356 BSTR xmlString;
358 TRACE("(%p, %p, %d)\n", iface, pStm, fClearDirty);
360 hr = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), &xmlString );
361 if(hr == S_OK)
363 DWORD count;
364 DWORD len = strlenW(xmlString) * sizeof(WCHAR);
366 hr = IStream_Write( pStm, xmlString, len, &count );
368 SysFreeString(xmlString);
371 TRACE("ret 0x%08x\n", hr);
373 return hr;
376 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
377 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
379 TRACE("(%p, %p): stub!\n", iface, pcbSize);
380 return E_NOTIMPL;
383 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
385 xmldoc_IPersistStream_QueryInterface,
386 xmldoc_IPersistStream_AddRef,
387 xmldoc_IPersistStream_Release,
388 xmldoc_IPersistStream_GetClassID,
389 xmldoc_IPersistStream_IsDirty,
390 xmldoc_IPersistStream_Load,
391 xmldoc_IPersistStream_Save,
392 xmldoc_IPersistStream_GetSizeMax,
395 /* ISupportErrorInfo interface */
396 static HRESULT WINAPI support_error_QueryInterface(
397 ISupportErrorInfo *iface,
398 REFIID riid, void** ppvObj )
400 domdoc *This = impl_from_ISupportErrorInfo(iface);
401 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
404 static ULONG WINAPI support_error_AddRef(
405 ISupportErrorInfo *iface )
407 domdoc *This = impl_from_ISupportErrorInfo(iface);
408 return IXMLDocument_AddRef((IXMLDocument *)This);
411 static ULONG WINAPI support_error_Release(
412 ISupportErrorInfo *iface )
414 domdoc *This = impl_from_ISupportErrorInfo(iface);
415 return IXMLDocument_Release((IXMLDocument *)This);
418 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
419 ISupportErrorInfo *iface,
420 REFIID riid )
422 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
423 return S_FALSE;
426 static const struct ISupportErrorInfoVtbl support_error_vtbl =
428 support_error_QueryInterface,
429 support_error_AddRef,
430 support_error_Release,
431 support_error_InterfaceSupportsErrorInfo
434 /* IXMLDOMDocument2 interface */
435 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
437 domdoc *This = impl_from_IXMLDOMDocument2( iface );
439 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
441 *ppvObject = NULL;
443 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
444 IsEqualGUID( riid, &IID_IDispatch ) ||
445 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
446 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
448 *ppvObject = iface;
450 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
452 *ppvObject = IXMLDOMNode_from_impl(&This->node);
454 else if (IsEqualGUID(&IID_IPersistStream, riid))
456 *ppvObject = &(This->lpvtblIPersistStream);
458 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
460 *ppvObject = &(This->lpvtblIObjectWithSite);
462 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
464 *ppvObject = &This->lpvtblISupportErrorInfo;
466 else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
468 return *ppvObject ? S_OK : E_NOINTERFACE;
470 else if(IsEqualGUID(&IID_IRunnableObject, riid))
472 TRACE("IID_IRunnableObject not supported returning NULL\n");
473 return E_NOINTERFACE;
475 else
477 FIXME("interface %s not implemented\n", debugstr_guid(riid));
478 return E_NOINTERFACE;
481 IUnknown_AddRef((IUnknown*)*ppvObject);
483 return S_OK;
487 static ULONG WINAPI domdoc_AddRef(
488 IXMLDOMDocument2 *iface )
490 domdoc *This = impl_from_IXMLDOMDocument2( iface );
491 TRACE("%p\n", This );
492 return InterlockedIncrement( &This->ref );
496 static ULONG WINAPI domdoc_Release(
497 IXMLDOMDocument2 *iface )
499 domdoc *This = impl_from_IXMLDOMDocument2( iface );
500 LONG ref;
502 TRACE("%p\n", This );
504 ref = InterlockedDecrement( &This->ref );
505 if ( ref == 0 )
507 if(This->bsc)
508 detach_bsc(This->bsc);
510 if (This->site)
511 IUnknown_Release( This->site );
512 destroy_xmlnode(&This->node);
513 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
514 if (This->stream) IStream_Release(This->stream);
515 HeapFree( GetProcessHeap(), 0, This );
518 return ref;
521 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
523 domdoc *This = impl_from_IXMLDOMDocument2( iface );
525 TRACE("(%p)->(%p)\n", This, pctinfo);
527 *pctinfo = 1;
529 return S_OK;
532 static HRESULT WINAPI domdoc_GetTypeInfo(
533 IXMLDOMDocument2 *iface,
534 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
536 domdoc *This = impl_from_IXMLDOMDocument2( iface );
537 HRESULT hr;
539 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
541 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
543 return hr;
546 static HRESULT WINAPI domdoc_GetIDsOfNames(
547 IXMLDOMDocument2 *iface,
548 REFIID riid,
549 LPOLESTR* rgszNames,
550 UINT cNames,
551 LCID lcid,
552 DISPID* rgDispId)
554 domdoc *This = impl_from_IXMLDOMDocument2( iface );
555 ITypeInfo *typeinfo;
556 HRESULT hr;
558 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
559 lcid, rgDispId);
561 if(!rgszNames || cNames == 0 || !rgDispId)
562 return E_INVALIDARG;
564 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
565 if(SUCCEEDED(hr))
567 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
568 ITypeInfo_Release(typeinfo);
571 return hr;
575 static HRESULT WINAPI domdoc_Invoke(
576 IXMLDOMDocument2 *iface,
577 DISPID dispIdMember,
578 REFIID riid,
579 LCID lcid,
580 WORD wFlags,
581 DISPPARAMS* pDispParams,
582 VARIANT* pVarResult,
583 EXCEPINFO* pExcepInfo,
584 UINT* puArgErr)
586 domdoc *This = impl_from_IXMLDOMDocument2( iface );
587 ITypeInfo *typeinfo;
588 HRESULT hr;
590 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
591 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
593 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
594 if(SUCCEEDED(hr))
596 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
597 pVarResult, pExcepInfo, puArgErr);
598 ITypeInfo_Release(typeinfo);
601 return hr;
605 static HRESULT WINAPI domdoc_get_nodeName(
606 IXMLDOMDocument2 *iface,
607 BSTR* name )
609 domdoc *This = impl_from_IXMLDOMDocument2( iface );
610 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
614 static HRESULT WINAPI domdoc_get_nodeValue(
615 IXMLDOMDocument2 *iface,
616 VARIANT* value )
618 domdoc *This = impl_from_IXMLDOMDocument2( iface );
619 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
623 static HRESULT WINAPI domdoc_put_nodeValue(
624 IXMLDOMDocument2 *iface,
625 VARIANT value)
627 domdoc *This = impl_from_IXMLDOMDocument2( iface );
628 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
632 static HRESULT WINAPI domdoc_get_nodeType(
633 IXMLDOMDocument2 *iface,
634 DOMNodeType* type )
636 domdoc *This = impl_from_IXMLDOMDocument2( iface );
637 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
641 static HRESULT WINAPI domdoc_get_parentNode(
642 IXMLDOMDocument2 *iface,
643 IXMLDOMNode** parent )
645 domdoc *This = impl_from_IXMLDOMDocument2( iface );
646 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
650 static HRESULT WINAPI domdoc_get_childNodes(
651 IXMLDOMDocument2 *iface,
652 IXMLDOMNodeList** childList )
654 domdoc *This = impl_from_IXMLDOMDocument2( iface );
655 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
659 static HRESULT WINAPI domdoc_get_firstChild(
660 IXMLDOMDocument2 *iface,
661 IXMLDOMNode** firstChild )
663 domdoc *This = impl_from_IXMLDOMDocument2( iface );
664 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
668 static HRESULT WINAPI domdoc_get_lastChild(
669 IXMLDOMDocument2 *iface,
670 IXMLDOMNode** lastChild )
672 domdoc *This = impl_from_IXMLDOMDocument2( iface );
673 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
677 static HRESULT WINAPI domdoc_get_previousSibling(
678 IXMLDOMDocument2 *iface,
679 IXMLDOMNode** previousSibling )
681 domdoc *This = impl_from_IXMLDOMDocument2( iface );
682 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
686 static HRESULT WINAPI domdoc_get_nextSibling(
687 IXMLDOMDocument2 *iface,
688 IXMLDOMNode** nextSibling )
690 domdoc *This = impl_from_IXMLDOMDocument2( iface );
691 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
695 static HRESULT WINAPI domdoc_get_attributes(
696 IXMLDOMDocument2 *iface,
697 IXMLDOMNamedNodeMap** attributeMap )
699 domdoc *This = impl_from_IXMLDOMDocument2( iface );
700 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
704 static HRESULT WINAPI domdoc_insertBefore(
705 IXMLDOMDocument2 *iface,
706 IXMLDOMNode* newChild,
707 VARIANT refChild,
708 IXMLDOMNode** outNewChild )
710 domdoc *This = impl_from_IXMLDOMDocument2( iface );
711 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
715 static HRESULT WINAPI domdoc_replaceChild(
716 IXMLDOMDocument2 *iface,
717 IXMLDOMNode* newChild,
718 IXMLDOMNode* oldChild,
719 IXMLDOMNode** outOldChild)
721 domdoc *This = impl_from_IXMLDOMDocument2( iface );
722 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
726 static HRESULT WINAPI domdoc_removeChild(
727 IXMLDOMDocument2 *iface,
728 IXMLDOMNode* childNode,
729 IXMLDOMNode** oldChild)
731 domdoc *This = impl_from_IXMLDOMDocument2( iface );
732 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
736 static HRESULT WINAPI domdoc_appendChild(
737 IXMLDOMDocument2 *iface,
738 IXMLDOMNode* newChild,
739 IXMLDOMNode** outNewChild)
741 domdoc *This = impl_from_IXMLDOMDocument2( iface );
742 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
746 static HRESULT WINAPI domdoc_hasChildNodes(
747 IXMLDOMDocument2 *iface,
748 VARIANT_BOOL* hasChild)
750 domdoc *This = impl_from_IXMLDOMDocument2( iface );
751 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
755 static HRESULT WINAPI domdoc_get_ownerDocument(
756 IXMLDOMDocument2 *iface,
757 IXMLDOMDocument** DOMDocument)
759 domdoc *This = impl_from_IXMLDOMDocument2( iface );
760 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
764 static HRESULT WINAPI domdoc_cloneNode(
765 IXMLDOMDocument2 *iface,
766 VARIANT_BOOL deep,
767 IXMLDOMNode** cloneRoot)
769 domdoc *This = impl_from_IXMLDOMDocument2( iface );
770 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
774 static HRESULT WINAPI domdoc_get_nodeTypeString(
775 IXMLDOMDocument2 *iface,
776 BSTR* nodeType )
778 domdoc *This = impl_from_IXMLDOMDocument2( iface );
779 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
783 static HRESULT WINAPI domdoc_get_text(
784 IXMLDOMDocument2 *iface,
785 BSTR* text )
787 domdoc *This = impl_from_IXMLDOMDocument2( iface );
788 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
792 static HRESULT WINAPI domdoc_put_text(
793 IXMLDOMDocument2 *iface,
794 BSTR text )
796 domdoc *This = impl_from_IXMLDOMDocument2( iface );
797 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
801 static HRESULT WINAPI domdoc_get_specified(
802 IXMLDOMDocument2 *iface,
803 VARIANT_BOOL* isSpecified )
805 domdoc *This = impl_from_IXMLDOMDocument2( iface );
806 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
810 static HRESULT WINAPI domdoc_get_definition(
811 IXMLDOMDocument2 *iface,
812 IXMLDOMNode** definitionNode )
814 domdoc *This = impl_from_IXMLDOMDocument2( iface );
815 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
819 static HRESULT WINAPI domdoc_get_nodeTypedValue(
820 IXMLDOMDocument2 *iface,
821 VARIANT* typedValue )
823 domdoc *This = impl_from_IXMLDOMDocument2( iface );
824 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
827 static HRESULT WINAPI domdoc_put_nodeTypedValue(
828 IXMLDOMDocument2 *iface,
829 VARIANT typedValue )
831 domdoc *This = impl_from_IXMLDOMDocument2( iface );
832 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
836 static HRESULT WINAPI domdoc_get_dataType(
837 IXMLDOMDocument2 *iface,
838 VARIANT* dataTypeName )
840 domdoc *This = impl_from_IXMLDOMDocument2( iface );
841 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
845 static HRESULT WINAPI domdoc_put_dataType(
846 IXMLDOMDocument2 *iface,
847 BSTR dataTypeName )
849 domdoc *This = impl_from_IXMLDOMDocument2( iface );
850 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
854 static HRESULT WINAPI domdoc_get_xml(
855 IXMLDOMDocument2 *iface,
856 BSTR* xmlString )
858 domdoc *This = impl_from_IXMLDOMDocument2( iface );
859 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
863 static HRESULT WINAPI domdoc_transformNode(
864 IXMLDOMDocument2 *iface,
865 IXMLDOMNode* styleSheet,
866 BSTR* xmlString )
868 domdoc *This = impl_from_IXMLDOMDocument2( iface );
869 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
873 static HRESULT WINAPI domdoc_selectNodes(
874 IXMLDOMDocument2 *iface,
875 BSTR queryString,
876 IXMLDOMNodeList** resultList )
878 domdoc *This = impl_from_IXMLDOMDocument2( iface );
879 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
883 static HRESULT WINAPI domdoc_selectSingleNode(
884 IXMLDOMDocument2 *iface,
885 BSTR queryString,
886 IXMLDOMNode** resultNode )
888 domdoc *This = impl_from_IXMLDOMDocument2( iface );
889 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
893 static HRESULT WINAPI domdoc_get_parsed(
894 IXMLDOMDocument2 *iface,
895 VARIANT_BOOL* isParsed )
897 domdoc *This = impl_from_IXMLDOMDocument2( iface );
898 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
902 static HRESULT WINAPI domdoc_get_namespaceURI(
903 IXMLDOMDocument2 *iface,
904 BSTR* namespaceURI )
906 domdoc *This = impl_from_IXMLDOMDocument2( iface );
907 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
911 static HRESULT WINAPI domdoc_get_prefix(
912 IXMLDOMDocument2 *iface,
913 BSTR* prefixString )
915 domdoc *This = impl_from_IXMLDOMDocument2( iface );
916 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
920 static HRESULT WINAPI domdoc_get_baseName(
921 IXMLDOMDocument2 *iface,
922 BSTR* nameString )
924 domdoc *This = impl_from_IXMLDOMDocument2( iface );
925 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
929 static HRESULT WINAPI domdoc_transformNodeToObject(
930 IXMLDOMDocument2 *iface,
931 IXMLDOMNode* stylesheet,
932 VARIANT outputObject)
934 domdoc *This = impl_from_IXMLDOMDocument2( iface );
935 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
939 static HRESULT WINAPI domdoc_get_doctype(
940 IXMLDOMDocument2 *iface,
941 IXMLDOMDocumentType** documentType )
943 FIXME("\n");
944 return E_NOTIMPL;
948 static HRESULT WINAPI domdoc_get_implementation(
949 IXMLDOMDocument2 *iface,
950 IXMLDOMImplementation** impl )
952 if(!impl)
953 return E_INVALIDARG;
955 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
957 return S_OK;
960 static HRESULT WINAPI domdoc_get_documentElement(
961 IXMLDOMDocument2 *iface,
962 IXMLDOMElement** DOMElement )
964 domdoc *This = impl_from_IXMLDOMDocument2( iface );
965 xmlDocPtr xmldoc = NULL;
966 xmlNodePtr root = NULL;
967 IXMLDOMNode *element_node;
968 HRESULT hr;
970 TRACE("%p\n", This);
972 if(!DOMElement)
973 return E_INVALIDARG;
975 *DOMElement = NULL;
977 xmldoc = get_doc( This );
979 root = xmlDocGetRootElement( xmldoc );
980 if ( !root )
981 return S_FALSE;
983 element_node = create_node( root );
984 if(!element_node) return S_FALSE;
986 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
987 IXMLDOMNode_Release(element_node);
989 return hr;
993 static HRESULT WINAPI domdoc_put_documentElement(
994 IXMLDOMDocument2 *iface,
995 IXMLDOMElement* DOMElement )
997 domdoc *This = impl_from_IXMLDOMDocument2( iface );
998 IXMLDOMNode *elementNode;
999 xmlNodePtr oldRoot;
1000 xmlnode *xmlNode;
1001 HRESULT hr;
1003 TRACE("(%p)->(%p)\n", This, DOMElement);
1005 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1006 if(FAILED(hr))
1007 return hr;
1009 xmlNode = impl_from_IXMLDOMNode( elementNode );
1011 if(!xmlNode->node->parent)
1012 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1013 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1015 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1016 IXMLDOMNode_Release( elementNode );
1018 if(oldRoot)
1019 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1021 return S_OK;
1025 static HRESULT WINAPI domdoc_createElement(
1026 IXMLDOMDocument2 *iface,
1027 BSTR tagname,
1028 IXMLDOMElement** element )
1030 xmlNodePtr xmlnode;
1031 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1032 xmlChar *xml_name;
1033 IUnknown *elem_unk;
1034 HRESULT hr;
1036 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1038 xml_name = xmlChar_from_wchar(tagname);
1039 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1040 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1042 TRACE("created xmlptr %p\n", xmlnode);
1043 elem_unk = create_element(xmlnode);
1044 HeapFree(GetProcessHeap(), 0, xml_name);
1046 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1047 IUnknown_Release(elem_unk);
1048 TRACE("returning %p\n", *element);
1049 return hr;
1053 static HRESULT WINAPI domdoc_createDocumentFragment(
1054 IXMLDOMDocument2 *iface,
1055 IXMLDOMDocumentFragment** docFrag )
1057 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1058 xmlNodePtr xmlnode;
1060 TRACE("%p\n", iface);
1062 if(!docFrag)
1063 return E_INVALIDARG;
1065 *docFrag = NULL;
1067 xmlnode = xmlNewDocFragment(get_doc( This ) );
1069 if(!xmlnode)
1070 return E_FAIL;
1072 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1073 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1075 return S_OK;
1079 static HRESULT WINAPI domdoc_createTextNode(
1080 IXMLDOMDocument2 *iface,
1081 BSTR data,
1082 IXMLDOMText** text )
1084 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1085 xmlNodePtr xmlnode;
1086 xmlChar *xml_content;
1088 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1090 if(!text)
1091 return E_INVALIDARG;
1093 *text = NULL;
1095 xml_content = xmlChar_from_wchar(data);
1096 xmlnode = xmlNewText(xml_content);
1097 HeapFree(GetProcessHeap(), 0, xml_content);
1099 if(!xmlnode)
1100 return E_FAIL;
1102 xmlnode->doc = get_doc( This );
1103 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1105 *text = (IXMLDOMText*)create_text(xmlnode);
1107 return S_OK;
1111 static HRESULT WINAPI domdoc_createComment(
1112 IXMLDOMDocument2 *iface,
1113 BSTR data,
1114 IXMLDOMComment** comment )
1116 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1117 xmlNodePtr xmlnode;
1118 xmlChar *xml_content;
1120 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1122 if(!comment)
1123 return E_INVALIDARG;
1125 *comment = NULL;
1127 xml_content = xmlChar_from_wchar(data);
1128 xmlnode = xmlNewComment(xml_content);
1129 HeapFree(GetProcessHeap(), 0, xml_content);
1131 if(!xmlnode)
1132 return E_FAIL;
1134 xmlnode->doc = get_doc( This );
1135 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1137 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1139 return S_OK;
1143 static HRESULT WINAPI domdoc_createCDATASection(
1144 IXMLDOMDocument2 *iface,
1145 BSTR data,
1146 IXMLDOMCDATASection** cdata )
1148 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1149 xmlNodePtr xmlnode;
1150 xmlChar *xml_content;
1152 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1154 if(!cdata)
1155 return E_INVALIDARG;
1157 *cdata = NULL;
1159 xml_content = xmlChar_from_wchar(data);
1160 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1161 HeapFree(GetProcessHeap(), 0, xml_content);
1163 if(!xmlnode)
1164 return E_FAIL;
1166 xmlnode->doc = get_doc( This );
1167 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1169 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1171 return S_OK;
1175 static HRESULT WINAPI domdoc_createProcessingInstruction(
1176 IXMLDOMDocument2 *iface,
1177 BSTR target,
1178 BSTR data,
1179 IXMLDOMProcessingInstruction** pi )
1181 #ifdef HAVE_XMLNEWDOCPI
1182 xmlNodePtr xmlnode;
1183 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1184 xmlChar *xml_target, *xml_content;
1186 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1188 if(!pi)
1189 return E_INVALIDARG;
1191 if(!target || lstrlenW(target) == 0)
1192 return E_FAIL;
1194 xml_target = xmlChar_from_wchar(target);
1195 xml_content = xmlChar_from_wchar(data);
1197 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1198 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1199 TRACE("created xmlptr %p\n", xmlnode);
1200 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1202 HeapFree(GetProcessHeap(), 0, xml_content);
1203 HeapFree(GetProcessHeap(), 0, xml_target);
1205 return S_OK;
1206 #else
1207 FIXME("Libxml 2.6.15 or greater required.\n");
1208 return E_NOTIMPL;
1209 #endif
1213 static HRESULT WINAPI domdoc_createAttribute(
1214 IXMLDOMDocument2 *iface,
1215 BSTR name,
1216 IXMLDOMAttribute** attribute )
1218 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1219 xmlNodePtr xmlnode;
1220 xmlChar *xml_name;
1222 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1224 if(!attribute)
1225 return E_INVALIDARG;
1227 *attribute = NULL;
1229 xml_name = xmlChar_from_wchar(name);
1230 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1231 HeapFree(GetProcessHeap(), 0, xml_name);
1233 if(!xmlnode)
1234 return E_FAIL;
1236 xmlnode->doc = get_doc( This );
1237 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1239 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1241 return S_OK;
1245 static HRESULT WINAPI domdoc_createEntityReference(
1246 IXMLDOMDocument2 *iface,
1247 BSTR name,
1248 IXMLDOMEntityReference** entityRef )
1250 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1251 xmlNodePtr xmlnode;
1252 xmlChar *xml_name;
1254 TRACE("%p\n", iface);
1256 if(!entityRef)
1257 return E_INVALIDARG;
1259 *entityRef = NULL;
1261 xml_name = xmlChar_from_wchar(name);
1262 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1263 HeapFree(GetProcessHeap(), 0, xml_name);
1265 if(!xmlnode)
1266 return E_FAIL;
1268 xmlnode->doc = get_doc( This );
1269 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1271 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1273 return S_OK;
1277 static HRESULT WINAPI domdoc_getElementsByTagName(
1278 IXMLDOMDocument2 *iface,
1279 BSTR tagName,
1280 IXMLDOMNodeList** resultList )
1282 static const WCHAR xpathformat[] =
1283 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1284 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1285 LPWSTR szPattern;
1286 HRESULT hr;
1287 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1289 if (tagName[0] == '*' && tagName[1] == 0)
1291 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*4);
1292 szPattern[0] = szPattern[1] = '/';
1293 szPattern[2] = '*';
1294 szPattern[3] = 0;
1296 else
1298 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1299 wsprintfW(szPattern, xpathformat, tagName);
1302 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1303 HeapFree(GetProcessHeap(), 0, szPattern);
1305 return hr;
1308 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1310 VARIANT tmp;
1311 HRESULT hr;
1313 VariantInit(&tmp);
1314 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1315 if(FAILED(hr))
1316 return E_INVALIDARG;
1318 *type = V_I4(&tmp);
1320 return S_OK;
1323 static HRESULT WINAPI domdoc_createNode(
1324 IXMLDOMDocument2 *iface,
1325 VARIANT Type,
1326 BSTR name,
1327 BSTR namespaceURI,
1328 IXMLDOMNode** node )
1330 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1331 DOMNodeType node_type;
1332 xmlNodePtr xmlnode = NULL;
1333 xmlChar *xml_name;
1334 HRESULT hr;
1336 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1338 if(namespaceURI && namespaceURI[0])
1339 FIXME("nodes with namespaces currently not supported.\n");
1341 hr = get_node_type(Type, &node_type);
1342 if(FAILED(hr))
1343 return hr;
1345 TRACE("node_type %d\n", node_type);
1347 xml_name = xmlChar_from_wchar(name);
1349 switch(node_type)
1351 case NODE_ELEMENT:
1352 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1353 *node = create_node(xmlnode);
1354 TRACE("created %p\n", xmlnode);
1355 break;
1356 case NODE_ATTRIBUTE:
1357 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1358 if(xmlnode)
1360 xmlnode->doc = get_doc( This );
1362 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1365 TRACE("created %p\n", xmlnode);
1366 break;
1368 default:
1369 FIXME("unhandled node type %d\n", node_type);
1370 break;
1373 HeapFree(GetProcessHeap(), 0, xml_name);
1375 if(xmlnode && *node)
1377 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1378 return S_OK;
1381 return E_FAIL;
1384 static HRESULT WINAPI domdoc_nodeFromID(
1385 IXMLDOMDocument2 *iface,
1386 BSTR idString,
1387 IXMLDOMNode** node )
1389 FIXME("\n");
1390 return E_NOTIMPL;
1393 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1395 domdoc *This = obj;
1396 xmlDocPtr xmldoc;
1398 xmldoc = doparse( ptr, len );
1399 if(xmldoc) {
1400 xmldoc->_private = create_priv();
1401 return attach_xmldoc(&This->node, xmldoc);
1404 return S_OK;
1407 static HRESULT doread( domdoc *This, LPWSTR filename )
1409 bsc_t *bsc;
1410 HRESULT hr;
1412 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1413 if(FAILED(hr))
1414 return hr;
1416 if(This->bsc)
1417 detach_bsc(This->bsc);
1419 This->bsc = bsc;
1420 return S_OK;
1423 static HRESULT WINAPI domdoc_load(
1424 IXMLDOMDocument2 *iface,
1425 VARIANT xmlSource,
1426 VARIANT_BOOL* isSuccessful )
1428 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1429 LPWSTR filename = NULL;
1430 HRESULT hr = S_FALSE;
1431 IXMLDOMDocument2 *pNewDoc = NULL;
1432 IStream *pStream = NULL;
1433 xmlDocPtr xmldoc;
1435 TRACE("type %d\n", V_VT(&xmlSource) );
1437 *isSuccessful = VARIANT_FALSE;
1439 assert( &This->node );
1441 switch( V_VT(&xmlSource) )
1443 case VT_BSTR:
1444 filename = V_BSTR(&xmlSource);
1445 break;
1446 case VT_UNKNOWN:
1447 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1448 if(hr == S_OK)
1450 if(pNewDoc)
1452 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1453 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1454 hr = attach_xmldoc(&This->node, xmldoc);
1456 if(SUCCEEDED(hr))
1457 *isSuccessful = VARIANT_TRUE;
1459 return hr;
1462 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1463 if(hr == S_OK)
1465 IPersistStream *pDocStream;
1466 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1467 if(hr == S_OK)
1469 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1470 IStream_Release(pStream);
1471 if(hr == S_OK)
1473 *isSuccessful = VARIANT_TRUE;
1475 TRACE("Using ID_IStream to load Document\n");
1476 return S_OK;
1478 else
1480 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1483 else
1485 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1488 else
1490 /* ISequentialStream */
1491 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1493 break;
1494 default:
1495 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1498 TRACE("filename (%s)\n", debugstr_w(filename));
1500 if ( filename )
1502 hr = doread( This, filename );
1504 if ( FAILED(hr) )
1505 This->error = E_FAIL;
1506 else
1508 hr = This->error = S_OK;
1509 *isSuccessful = VARIANT_TRUE;
1513 if(!filename || FAILED(hr)) {
1514 xmldoc = xmlNewDoc(NULL);
1515 xmldoc->_private = create_priv();
1516 hr = attach_xmldoc(&This->node, xmldoc);
1517 if(SUCCEEDED(hr))
1518 hr = S_FALSE;
1521 TRACE("ret (%d)\n", hr);
1523 return hr;
1527 static HRESULT WINAPI domdoc_get_readyState(
1528 IXMLDOMDocument2 *iface,
1529 LONG *value )
1531 FIXME("\n");
1532 return E_NOTIMPL;
1536 static HRESULT WINAPI domdoc_get_parseError(
1537 IXMLDOMDocument2 *iface,
1538 IXMLDOMParseError** errorObj )
1540 BSTR error_string = NULL;
1541 static const WCHAR err[] = {'e','r','r','o','r',0};
1542 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1544 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1546 if(This->error)
1547 error_string = SysAllocString(err);
1549 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1550 if(!*errorObj) return E_OUTOFMEMORY;
1551 return S_OK;
1555 static HRESULT WINAPI domdoc_get_url(
1556 IXMLDOMDocument2 *iface,
1557 BSTR* urlString )
1559 FIXME("\n");
1560 return E_NOTIMPL;
1564 static HRESULT WINAPI domdoc_get_async(
1565 IXMLDOMDocument2 *iface,
1566 VARIANT_BOOL* isAsync )
1568 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1570 TRACE("%p <- %d\n", isAsync, This->async);
1571 *isAsync = This->async;
1572 return S_OK;
1576 static HRESULT WINAPI domdoc_put_async(
1577 IXMLDOMDocument2 *iface,
1578 VARIANT_BOOL isAsync )
1580 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1582 TRACE("%d\n", isAsync);
1583 This->async = isAsync;
1584 return S_OK;
1588 static HRESULT WINAPI domdoc_abort(
1589 IXMLDOMDocument2 *iface )
1591 FIXME("\n");
1592 return E_NOTIMPL;
1596 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1598 UINT len, blen = SysStringLen( bstr );
1599 LPSTR str;
1601 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1602 str = HeapAlloc( GetProcessHeap(), 0, len );
1603 if ( !str )
1604 return FALSE;
1605 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1606 *plen = len;
1607 *pstr = str;
1608 return TRUE;
1611 static HRESULT WINAPI domdoc_loadXML(
1612 IXMLDOMDocument2 *iface,
1613 BSTR bstrXML,
1614 VARIANT_BOOL* isSuccessful )
1616 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1617 xmlDocPtr xmldoc = NULL;
1618 char *str;
1619 int len;
1620 HRESULT hr = S_FALSE, hr2;
1622 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1624 assert ( &This->node );
1626 if ( isSuccessful )
1628 *isSuccessful = VARIANT_FALSE;
1630 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1632 xmldoc = doparse( str, len );
1633 HeapFree( GetProcessHeap(), 0, str );
1634 if ( !xmldoc )
1635 This->error = E_FAIL;
1636 else
1638 hr = This->error = S_OK;
1639 *isSuccessful = VARIANT_TRUE;
1643 if(!xmldoc)
1644 xmldoc = xmlNewDoc(NULL);
1646 xmldoc->_private = create_priv();
1647 hr2 = attach_xmldoc( &This->node, xmldoc );
1648 if( FAILED(hr2) )
1649 hr = hr2;
1651 return hr;
1655 static HRESULT WINAPI domdoc_save(
1656 IXMLDOMDocument2 *iface,
1657 VARIANT destination )
1659 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1660 HANDLE handle;
1661 xmlChar *mem, *p;
1662 int size;
1663 HRESULT ret = S_OK;
1664 DWORD written;
1666 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1667 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1669 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1671 FIXME("Unhandled vt %d\n", V_VT(&destination));
1672 return S_FALSE;
1675 if(V_VT(&destination) == VT_UNKNOWN)
1677 IUnknown *pUnk = V_UNKNOWN(&destination);
1678 IXMLDOMDocument *pDocument;
1680 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1681 if(ret == S_OK)
1683 BSTR bXML;
1684 VARIANT_BOOL bSuccessful;
1686 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1687 if(ret == S_OK)
1689 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1691 SysFreeString(bXML);
1694 IXMLDOMDocument_Release(pDocument);
1697 TRACE("ret %d\n", ret);
1699 return ret;
1702 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1703 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1704 if( handle == INVALID_HANDLE_VALUE )
1706 WARN("failed to create file\n");
1707 return S_FALSE;
1710 xmlDocDumpMemory(get_doc(This), &mem, &size);
1713 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1714 * MSXML adds XML declaration only for processing instruction nodes.
1715 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1717 p = mem;
1718 if(size > 2 && p[0] == '<' && p[1] == '?') {
1719 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1720 p++;
1721 p += 2;
1722 while(p < mem+size && isspace(*p))
1723 p++;
1724 size -= p-mem;
1727 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1729 WARN("write error\n");
1730 ret = S_FALSE;
1733 xmlFree(mem);
1734 CloseHandle(handle);
1735 return ret;
1738 static HRESULT WINAPI domdoc_get_validateOnParse(
1739 IXMLDOMDocument2 *iface,
1740 VARIANT_BOOL* isValidating )
1742 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1744 TRACE("%p <- %d\n", isValidating, This->validating);
1745 *isValidating = This->validating;
1746 return S_OK;
1750 static HRESULT WINAPI domdoc_put_validateOnParse(
1751 IXMLDOMDocument2 *iface,
1752 VARIANT_BOOL isValidating )
1754 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1756 TRACE("%d\n", isValidating);
1757 This->validating = isValidating;
1758 return S_OK;
1762 static HRESULT WINAPI domdoc_get_resolveExternals(
1763 IXMLDOMDocument2 *iface,
1764 VARIANT_BOOL* isResolving )
1766 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1768 TRACE("%p <- %d\n", isResolving, This->resolving);
1769 *isResolving = This->resolving;
1770 return S_OK;
1774 static HRESULT WINAPI domdoc_put_resolveExternals(
1775 IXMLDOMDocument2 *iface,
1776 VARIANT_BOOL isResolving )
1778 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1780 TRACE("%d\n", isResolving);
1781 This->resolving = isResolving;
1782 return S_OK;
1786 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1787 IXMLDOMDocument2 *iface,
1788 VARIANT_BOOL* isPreserving )
1790 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1792 TRACE("%p <- %d\n", isPreserving, This->preserving);
1793 *isPreserving = This->preserving;
1794 return S_OK;
1798 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1799 IXMLDOMDocument2 *iface,
1800 VARIANT_BOOL isPreserving )
1802 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1804 TRACE("%d\n", isPreserving);
1805 This->preserving = isPreserving;
1806 return S_OK;
1810 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1811 IXMLDOMDocument2 *iface,
1812 VARIANT readyStateChangeSink )
1814 FIXME("\n");
1815 return E_NOTIMPL;
1819 static HRESULT WINAPI domdoc_put_onDataAvailable(
1820 IXMLDOMDocument2 *iface,
1821 VARIANT onDataAvailableSink )
1823 FIXME("\n");
1824 return E_NOTIMPL;
1827 static HRESULT WINAPI domdoc_put_onTransformNode(
1828 IXMLDOMDocument2 *iface,
1829 VARIANT onTransformNodeSink )
1831 FIXME("\n");
1832 return E_NOTIMPL;
1835 static HRESULT WINAPI domdoc_get_namespaces(
1836 IXMLDOMDocument2* iface,
1837 IXMLDOMSchemaCollection** schemaCollection )
1839 FIXME("\n");
1840 return E_NOTIMPL;
1843 static HRESULT WINAPI domdoc_get_schemas(
1844 IXMLDOMDocument2* iface,
1845 VARIANT* var1 )
1847 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1848 HRESULT hr = S_FALSE;
1849 IXMLDOMSchemaCollection *cur_schema = This->schema;
1851 TRACE("(%p)->(%p)\n", This, var1);
1853 VariantInit(var1); /* Test shows we don't call VariantClear here */
1854 V_VT(var1) = VT_NULL;
1856 if(cur_schema)
1858 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1859 if(SUCCEEDED(hr))
1860 V_VT(var1) = VT_DISPATCH;
1862 return hr;
1865 static HRESULT WINAPI domdoc_putref_schemas(
1866 IXMLDOMDocument2* iface,
1867 VARIANT var1)
1869 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1870 HRESULT hr = E_FAIL;
1871 IXMLDOMSchemaCollection *new_schema = NULL;
1873 FIXME("(%p): semi-stub\n", This);
1874 switch(V_VT(&var1))
1876 case VT_UNKNOWN:
1877 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1878 break;
1880 case VT_DISPATCH:
1881 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1882 break;
1884 case VT_NULL:
1885 case VT_EMPTY:
1886 hr = S_OK;
1887 break;
1889 default:
1890 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1893 if(SUCCEEDED(hr))
1895 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1896 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1899 return hr;
1902 static HRESULT WINAPI domdoc_validate(
1903 IXMLDOMDocument2* iface,
1904 IXMLDOMParseError** err)
1906 FIXME("\n");
1907 return E_NOTIMPL;
1910 static HRESULT WINAPI domdoc_setProperty(
1911 IXMLDOMDocument2* iface,
1912 BSTR p,
1913 VARIANT var)
1915 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1917 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1919 VARIANT varStr;
1920 HRESULT hr;
1921 BSTR bstr;
1923 V_VT(&varStr) = VT_EMPTY;
1924 if (V_VT(&var) != VT_BSTR)
1926 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1927 return hr;
1928 bstr = V_BSTR(&varStr);
1930 else
1931 bstr = V_BSTR(&var);
1933 hr = S_OK;
1934 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1935 This->bUseXPath = TRUE;
1936 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1937 This->bUseXPath = FALSE;
1938 else
1939 hr = E_FAIL;
1941 VariantClear(&varStr);
1942 return hr;
1945 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1946 return E_FAIL;
1949 static HRESULT WINAPI domdoc_getProperty(
1950 IXMLDOMDocument2* iface,
1951 BSTR p,
1952 VARIANT* var)
1954 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1956 if (var == NULL)
1957 return E_INVALIDARG;
1958 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1960 V_VT(var) = VT_BSTR;
1961 if (This->bUseXPath)
1962 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1963 else
1964 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1965 return S_OK;
1968 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1969 return E_FAIL;
1972 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1974 domdoc_QueryInterface,
1975 domdoc_AddRef,
1976 domdoc_Release,
1977 domdoc_GetTypeInfoCount,
1978 domdoc_GetTypeInfo,
1979 domdoc_GetIDsOfNames,
1980 domdoc_Invoke,
1981 domdoc_get_nodeName,
1982 domdoc_get_nodeValue,
1983 domdoc_put_nodeValue,
1984 domdoc_get_nodeType,
1985 domdoc_get_parentNode,
1986 domdoc_get_childNodes,
1987 domdoc_get_firstChild,
1988 domdoc_get_lastChild,
1989 domdoc_get_previousSibling,
1990 domdoc_get_nextSibling,
1991 domdoc_get_attributes,
1992 domdoc_insertBefore,
1993 domdoc_replaceChild,
1994 domdoc_removeChild,
1995 domdoc_appendChild,
1996 domdoc_hasChildNodes,
1997 domdoc_get_ownerDocument,
1998 domdoc_cloneNode,
1999 domdoc_get_nodeTypeString,
2000 domdoc_get_text,
2001 domdoc_put_text,
2002 domdoc_get_specified,
2003 domdoc_get_definition,
2004 domdoc_get_nodeTypedValue,
2005 domdoc_put_nodeTypedValue,
2006 domdoc_get_dataType,
2007 domdoc_put_dataType,
2008 domdoc_get_xml,
2009 domdoc_transformNode,
2010 domdoc_selectNodes,
2011 domdoc_selectSingleNode,
2012 domdoc_get_parsed,
2013 domdoc_get_namespaceURI,
2014 domdoc_get_prefix,
2015 domdoc_get_baseName,
2016 domdoc_transformNodeToObject,
2017 domdoc_get_doctype,
2018 domdoc_get_implementation,
2019 domdoc_get_documentElement,
2020 domdoc_put_documentElement,
2021 domdoc_createElement,
2022 domdoc_createDocumentFragment,
2023 domdoc_createTextNode,
2024 domdoc_createComment,
2025 domdoc_createCDATASection,
2026 domdoc_createProcessingInstruction,
2027 domdoc_createAttribute,
2028 domdoc_createEntityReference,
2029 domdoc_getElementsByTagName,
2030 domdoc_createNode,
2031 domdoc_nodeFromID,
2032 domdoc_load,
2033 domdoc_get_readyState,
2034 domdoc_get_parseError,
2035 domdoc_get_url,
2036 domdoc_get_async,
2037 domdoc_put_async,
2038 domdoc_abort,
2039 domdoc_loadXML,
2040 domdoc_save,
2041 domdoc_get_validateOnParse,
2042 domdoc_put_validateOnParse,
2043 domdoc_get_resolveExternals,
2044 domdoc_put_resolveExternals,
2045 domdoc_get_preserveWhiteSpace,
2046 domdoc_put_preserveWhiteSpace,
2047 domdoc_put_onReadyStateChange,
2048 domdoc_put_onDataAvailable,
2049 domdoc_put_onTransformNode,
2050 domdoc_get_namespaces,
2051 domdoc_get_schemas,
2052 domdoc_putref_schemas,
2053 domdoc_validate,
2054 domdoc_setProperty,
2055 domdoc_getProperty
2058 /* xmldoc implementation of IObjectWithSite */
2059 static HRESULT WINAPI
2060 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2062 domdoc *This = impl_from_IObjectWithSite(iface);
2063 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2066 static ULONG WINAPI
2067 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2069 domdoc *This = impl_from_IObjectWithSite(iface);
2070 return IXMLDocument_AddRef((IXMLDocument *)This);
2073 static ULONG WINAPI
2074 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2076 domdoc *This = impl_from_IObjectWithSite(iface);
2077 return IXMLDocument_Release((IXMLDocument *)This);
2080 static HRESULT WINAPI
2081 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2083 domdoc *This = impl_from_IObjectWithSite(iface);
2085 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2087 if ( !This->site )
2088 return E_FAIL;
2090 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2093 static HRESULT WINAPI
2094 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2096 domdoc *This = impl_from_IObjectWithSite(iface);
2098 TRACE("%p %p\n", iface, punk);
2100 if(!punk)
2102 if(This->site)
2104 IUnknown_Release( This->site );
2105 This->site = NULL;
2108 return S_OK;
2111 if ( punk )
2112 IUnknown_AddRef( punk );
2114 if(This->site)
2115 IUnknown_Release( This->site );
2117 This->site = punk;
2119 return S_OK;
2122 static const IObjectWithSiteVtbl domdocObjectSite =
2124 xmldoc_ObjectWithSite_QueryInterface,
2125 xmldoc_ObjectWithSite_AddRef,
2126 xmldoc_ObjectWithSite_Release,
2127 xmldoc_SetSite,
2128 xmldoc_GetSite,
2131 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2133 domdoc *This = impl_from_IObjectSafety(iface);
2134 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2137 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2139 domdoc *This = impl_from_IObjectSafety(iface);
2140 return IXMLDocument_AddRef((IXMLDocument *)This);
2143 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2145 domdoc *This = impl_from_IObjectSafety(iface);
2146 return IXMLDocument_Release((IXMLDocument *)This);
2149 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2151 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2152 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2154 domdoc *This = impl_from_IObjectSafety(iface);
2156 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2158 if(!pdwSupportedOptions || !pdwEnabledOptions)
2159 return E_POINTER;
2161 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2162 *pdwEnabledOptions = This->safeopt;
2164 return S_OK;
2167 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2168 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2170 domdoc *This = impl_from_IObjectSafety(iface);
2172 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2174 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2175 return E_FAIL;
2177 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2178 return S_OK;
2181 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2182 xmldoc_Safety_QueryInterface,
2183 xmldoc_Safety_AddRef,
2184 xmldoc_Safety_Release,
2185 xmldoc_Safety_GetInterfaceSafetyOptions,
2186 xmldoc_Safety_SetInterfaceSafetyOptions
2190 static const tid_t domdoc_iface_tids[] = {
2191 IXMLDOMNode_tid,
2192 IXMLDOMDocument_tid,
2193 IXMLDOMDocument2_tid,
2196 static dispex_static_data_t domdoc_dispex = {
2197 NULL,
2198 IXMLDOMDocument2_tid,
2199 NULL,
2200 domdoc_iface_tids
2203 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2205 domdoc *doc;
2207 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2208 if( !doc )
2209 return E_OUTOFMEMORY;
2211 doc->lpVtbl = &domdoc_vtbl;
2212 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2213 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2214 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2215 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2216 doc->ref = 1;
2217 doc->async = VARIANT_TRUE;
2218 doc->validating = 0;
2219 doc->resolving = 0;
2220 doc->preserving = 0;
2221 doc->bUseXPath = FALSE;
2222 doc->error = S_OK;
2223 doc->schema = NULL;
2224 doc->stream = NULL;
2225 doc->site = NULL;
2226 doc->safeopt = 0;
2227 doc->bsc = NULL;
2229 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2231 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2233 TRACE("returning iface %p\n", *document);
2234 return S_OK;
2237 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2239 xmlDocPtr xmldoc;
2240 HRESULT hr;
2242 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2244 xmldoc = xmlNewDoc(NULL);
2245 if(!xmldoc)
2246 return E_OUTOFMEMORY;
2248 xmldoc->_private = create_priv();
2250 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2251 if(FAILED(hr))
2252 xmlFreeDoc(xmldoc);
2254 return hr;
2257 IUnknown* create_domdoc( xmlNodePtr document )
2259 HRESULT hr;
2260 LPVOID pObj = NULL;
2262 TRACE("(%p)\n", document);
2264 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2265 if (FAILED(hr))
2266 return NULL;
2268 return pObj;
2271 #else
2273 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2275 MESSAGE("This program tried to use a DOMDocument object, but\n"
2276 "libxml2 support was not present at compile time.\n");
2277 return E_NOTIMPL;
2280 #endif