push 8b07bf1f08b23b9893a622b47d2be359556765b1
[wine/hacks.git] / dlls / msxml3 / domdoc.c
blobbe19e566ff4ee398f978f7c1f6dcd72456bfbfd3
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 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1283 LPWSTR szPattern;
1284 HRESULT hr;
1285 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1287 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1288 szPattern[0] = szPattern[1] = '/';
1289 lstrcpyW(szPattern + 2, tagName);
1291 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1292 HeapFree(GetProcessHeap(), 0, szPattern);
1294 return hr;
1297 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1299 VARIANT tmp;
1300 HRESULT hr;
1302 VariantInit(&tmp);
1303 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1304 if(FAILED(hr))
1305 return E_INVALIDARG;
1307 *type = V_I4(&tmp);
1309 return S_OK;
1312 static HRESULT WINAPI domdoc_createNode(
1313 IXMLDOMDocument2 *iface,
1314 VARIANT Type,
1315 BSTR name,
1316 BSTR namespaceURI,
1317 IXMLDOMNode** node )
1319 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1320 DOMNodeType node_type;
1321 xmlNodePtr xmlnode = NULL;
1322 xmlChar *xml_name;
1323 HRESULT hr;
1325 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1327 if(namespaceURI && namespaceURI[0])
1328 FIXME("nodes with namespaces currently not supported.\n");
1330 hr = get_node_type(Type, &node_type);
1331 if(FAILED(hr))
1332 return hr;
1334 TRACE("node_type %d\n", node_type);
1336 xml_name = xmlChar_from_wchar(name);
1338 switch(node_type)
1340 case NODE_ELEMENT:
1341 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1342 *node = create_node(xmlnode);
1343 TRACE("created %p\n", xmlnode);
1344 break;
1345 case NODE_ATTRIBUTE:
1346 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1347 if(xmlnode)
1349 xmlnode->doc = get_doc( This );
1351 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1354 TRACE("created %p\n", xmlnode);
1355 break;
1357 default:
1358 FIXME("unhandled node type %d\n", node_type);
1359 break;
1362 HeapFree(GetProcessHeap(), 0, xml_name);
1364 if(xmlnode && *node)
1366 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1367 return S_OK;
1370 return E_FAIL;
1373 static HRESULT WINAPI domdoc_nodeFromID(
1374 IXMLDOMDocument2 *iface,
1375 BSTR idString,
1376 IXMLDOMNode** node )
1378 FIXME("\n");
1379 return E_NOTIMPL;
1382 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1384 domdoc *This = obj;
1385 xmlDocPtr xmldoc;
1387 xmldoc = doparse( ptr, len );
1388 if(xmldoc) {
1389 xmldoc->_private = create_priv();
1390 return attach_xmldoc(&This->node, xmldoc);
1393 return S_OK;
1396 static HRESULT doread( domdoc *This, LPWSTR filename )
1398 bsc_t *bsc;
1399 HRESULT hr;
1401 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1402 if(FAILED(hr))
1403 return hr;
1405 if(This->bsc)
1406 detach_bsc(This->bsc);
1408 This->bsc = bsc;
1409 return S_OK;
1412 static HRESULT WINAPI domdoc_load(
1413 IXMLDOMDocument2 *iface,
1414 VARIANT xmlSource,
1415 VARIANT_BOOL* isSuccessful )
1417 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1418 LPWSTR filename = NULL;
1419 HRESULT hr = S_FALSE;
1420 IXMLDOMDocument2 *pNewDoc = NULL;
1421 IStream *pStream = NULL;
1422 xmlDocPtr xmldoc;
1424 TRACE("type %d\n", V_VT(&xmlSource) );
1426 *isSuccessful = VARIANT_FALSE;
1428 assert( &This->node );
1430 switch( V_VT(&xmlSource) )
1432 case VT_BSTR:
1433 filename = V_BSTR(&xmlSource);
1434 break;
1435 case VT_UNKNOWN:
1436 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1437 if(hr == S_OK)
1439 if(pNewDoc)
1441 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1442 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1443 hr = attach_xmldoc(&This->node, xmldoc);
1445 if(SUCCEEDED(hr))
1446 *isSuccessful = VARIANT_TRUE;
1448 return hr;
1451 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1452 if(hr == S_OK)
1454 IPersistStream *pDocStream;
1455 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1456 if(hr == S_OK)
1458 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1459 IStream_Release(pStream);
1460 if(hr == S_OK)
1462 *isSuccessful = VARIANT_TRUE;
1464 TRACE("Using ID_IStream to load Document\n");
1465 return S_OK;
1467 else
1469 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1472 else
1474 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1477 else
1479 /* ISequentialStream */
1480 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1482 break;
1483 default:
1484 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1487 TRACE("filename (%s)\n", debugstr_w(filename));
1489 if ( filename )
1491 hr = doread( This, filename );
1493 if ( FAILED(hr) )
1494 This->error = E_FAIL;
1495 else
1497 hr = This->error = S_OK;
1498 *isSuccessful = VARIANT_TRUE;
1502 if(!filename || FAILED(hr)) {
1503 xmldoc = xmlNewDoc(NULL);
1504 xmldoc->_private = create_priv();
1505 hr = attach_xmldoc(&This->node, xmldoc);
1506 if(SUCCEEDED(hr))
1507 hr = S_FALSE;
1510 TRACE("ret (%d)\n", hr);
1512 return hr;
1516 static HRESULT WINAPI domdoc_get_readyState(
1517 IXMLDOMDocument2 *iface,
1518 LONG *value )
1520 FIXME("\n");
1521 return E_NOTIMPL;
1525 static HRESULT WINAPI domdoc_get_parseError(
1526 IXMLDOMDocument2 *iface,
1527 IXMLDOMParseError** errorObj )
1529 BSTR error_string = NULL;
1530 static const WCHAR err[] = {'e','r','r','o','r',0};
1531 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1533 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1535 if(This->error)
1536 error_string = SysAllocString(err);
1538 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1539 if(!*errorObj) return E_OUTOFMEMORY;
1540 return S_OK;
1544 static HRESULT WINAPI domdoc_get_url(
1545 IXMLDOMDocument2 *iface,
1546 BSTR* urlString )
1548 FIXME("\n");
1549 return E_NOTIMPL;
1553 static HRESULT WINAPI domdoc_get_async(
1554 IXMLDOMDocument2 *iface,
1555 VARIANT_BOOL* isAsync )
1557 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1559 TRACE("%p <- %d\n", isAsync, This->async);
1560 *isAsync = This->async;
1561 return S_OK;
1565 static HRESULT WINAPI domdoc_put_async(
1566 IXMLDOMDocument2 *iface,
1567 VARIANT_BOOL isAsync )
1569 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1571 TRACE("%d\n", isAsync);
1572 This->async = isAsync;
1573 return S_OK;
1577 static HRESULT WINAPI domdoc_abort(
1578 IXMLDOMDocument2 *iface )
1580 FIXME("\n");
1581 return E_NOTIMPL;
1585 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1587 UINT len, blen = SysStringLen( bstr );
1588 LPSTR str;
1590 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1591 str = HeapAlloc( GetProcessHeap(), 0, len );
1592 if ( !str )
1593 return FALSE;
1594 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1595 *plen = len;
1596 *pstr = str;
1597 return TRUE;
1600 static HRESULT WINAPI domdoc_loadXML(
1601 IXMLDOMDocument2 *iface,
1602 BSTR bstrXML,
1603 VARIANT_BOOL* isSuccessful )
1605 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1606 xmlDocPtr xmldoc = NULL;
1607 char *str;
1608 int len;
1609 HRESULT hr = S_FALSE, hr2;
1611 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1613 assert ( &This->node );
1615 if ( isSuccessful )
1617 *isSuccessful = VARIANT_FALSE;
1619 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1621 xmldoc = doparse( str, len );
1622 HeapFree( GetProcessHeap(), 0, str );
1623 if ( !xmldoc )
1624 This->error = E_FAIL;
1625 else
1627 hr = This->error = S_OK;
1628 *isSuccessful = VARIANT_TRUE;
1632 if(!xmldoc)
1633 xmldoc = xmlNewDoc(NULL);
1635 xmldoc->_private = create_priv();
1636 hr2 = attach_xmldoc( &This->node, xmldoc );
1637 if( FAILED(hr2) )
1638 hr = hr2;
1640 return hr;
1644 static HRESULT WINAPI domdoc_save(
1645 IXMLDOMDocument2 *iface,
1646 VARIANT destination )
1648 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1649 HANDLE handle;
1650 xmlChar *mem, *p;
1651 int size;
1652 HRESULT ret = S_OK;
1653 DWORD written;
1655 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1656 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1658 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1660 FIXME("Unhandled vt %d\n", V_VT(&destination));
1661 return S_FALSE;
1664 if(V_VT(&destination) == VT_UNKNOWN)
1666 IUnknown *pUnk = V_UNKNOWN(&destination);
1667 IXMLDOMDocument *pDocument;
1669 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1670 if(ret == S_OK)
1672 BSTR bXML;
1673 VARIANT_BOOL bSuccessful;
1675 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1676 if(ret == S_OK)
1678 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1680 SysFreeString(bXML);
1683 IXMLDOMDocument_Release(pDocument);
1686 TRACE("ret %d\n", ret);
1688 return ret;
1691 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1692 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1693 if( handle == INVALID_HANDLE_VALUE )
1695 WARN("failed to create file\n");
1696 return S_FALSE;
1699 xmlDocDumpMemory(get_doc(This), &mem, &size);
1702 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1703 * MSXML adds XML declaration only for processing instruction nodes.
1704 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1706 p = mem;
1707 if(size > 2 && p[0] == '<' && p[1] == '?') {
1708 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1709 p++;
1710 p += 2;
1711 while(p < mem+size && isspace(*p))
1712 p++;
1713 size -= p-mem;
1716 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1718 WARN("write error\n");
1719 ret = S_FALSE;
1722 xmlFree(mem);
1723 CloseHandle(handle);
1724 return ret;
1727 static HRESULT WINAPI domdoc_get_validateOnParse(
1728 IXMLDOMDocument2 *iface,
1729 VARIANT_BOOL* isValidating )
1731 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1733 TRACE("%p <- %d\n", isValidating, This->validating);
1734 *isValidating = This->validating;
1735 return S_OK;
1739 static HRESULT WINAPI domdoc_put_validateOnParse(
1740 IXMLDOMDocument2 *iface,
1741 VARIANT_BOOL isValidating )
1743 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1745 TRACE("%d\n", isValidating);
1746 This->validating = isValidating;
1747 return S_OK;
1751 static HRESULT WINAPI domdoc_get_resolveExternals(
1752 IXMLDOMDocument2 *iface,
1753 VARIANT_BOOL* isResolving )
1755 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1757 TRACE("%p <- %d\n", isResolving, This->resolving);
1758 *isResolving = This->resolving;
1759 return S_OK;
1763 static HRESULT WINAPI domdoc_put_resolveExternals(
1764 IXMLDOMDocument2 *iface,
1765 VARIANT_BOOL isResolving )
1767 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1769 TRACE("%d\n", isResolving);
1770 This->resolving = isResolving;
1771 return S_OK;
1775 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1776 IXMLDOMDocument2 *iface,
1777 VARIANT_BOOL* isPreserving )
1779 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1781 TRACE("%p <- %d\n", isPreserving, This->preserving);
1782 *isPreserving = This->preserving;
1783 return S_OK;
1787 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1788 IXMLDOMDocument2 *iface,
1789 VARIANT_BOOL isPreserving )
1791 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1793 TRACE("%d\n", isPreserving);
1794 This->preserving = isPreserving;
1795 return S_OK;
1799 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1800 IXMLDOMDocument2 *iface,
1801 VARIANT readyStateChangeSink )
1803 FIXME("\n");
1804 return E_NOTIMPL;
1808 static HRESULT WINAPI domdoc_put_onDataAvailable(
1809 IXMLDOMDocument2 *iface,
1810 VARIANT onDataAvailableSink )
1812 FIXME("\n");
1813 return E_NOTIMPL;
1816 static HRESULT WINAPI domdoc_put_onTransformNode(
1817 IXMLDOMDocument2 *iface,
1818 VARIANT onTransformNodeSink )
1820 FIXME("\n");
1821 return E_NOTIMPL;
1824 static HRESULT WINAPI domdoc_get_namespaces(
1825 IXMLDOMDocument2* iface,
1826 IXMLDOMSchemaCollection** schemaCollection )
1828 FIXME("\n");
1829 return E_NOTIMPL;
1832 static HRESULT WINAPI domdoc_get_schemas(
1833 IXMLDOMDocument2* iface,
1834 VARIANT* var1 )
1836 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1837 HRESULT hr = S_FALSE;
1838 IXMLDOMSchemaCollection *cur_schema = This->schema;
1840 TRACE("(%p)->(%p)\n", This, var1);
1842 VariantInit(var1); /* Test shows we don't call VariantClear here */
1843 V_VT(var1) = VT_NULL;
1845 if(cur_schema)
1847 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1848 if(SUCCEEDED(hr))
1849 V_VT(var1) = VT_DISPATCH;
1851 return hr;
1854 static HRESULT WINAPI domdoc_putref_schemas(
1855 IXMLDOMDocument2* iface,
1856 VARIANT var1)
1858 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1859 HRESULT hr = E_FAIL;
1860 IXMLDOMSchemaCollection *new_schema = NULL;
1862 FIXME("(%p): semi-stub\n", This);
1863 switch(V_VT(&var1))
1865 case VT_UNKNOWN:
1866 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1867 break;
1869 case VT_DISPATCH:
1870 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1871 break;
1873 case VT_NULL:
1874 case VT_EMPTY:
1875 hr = S_OK;
1876 break;
1878 default:
1879 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1882 if(SUCCEEDED(hr))
1884 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1885 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1888 return hr;
1891 static HRESULT WINAPI domdoc_validate(
1892 IXMLDOMDocument2* iface,
1893 IXMLDOMParseError** err)
1895 FIXME("\n");
1896 return E_NOTIMPL;
1899 static HRESULT WINAPI domdoc_setProperty(
1900 IXMLDOMDocument2* iface,
1901 BSTR p,
1902 VARIANT var)
1904 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1906 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1908 VARIANT varStr;
1909 HRESULT hr;
1910 BSTR bstr;
1912 V_VT(&varStr) = VT_EMPTY;
1913 if (V_VT(&var) != VT_BSTR)
1915 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1916 return hr;
1917 bstr = V_BSTR(&varStr);
1919 else
1920 bstr = V_BSTR(&var);
1922 hr = S_OK;
1923 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1924 This->bUseXPath = TRUE;
1925 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1926 This->bUseXPath = FALSE;
1927 else
1928 hr = E_FAIL;
1930 VariantClear(&varStr);
1931 return hr;
1934 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1935 return E_FAIL;
1938 static HRESULT WINAPI domdoc_getProperty(
1939 IXMLDOMDocument2* iface,
1940 BSTR p,
1941 VARIANT* var)
1943 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1945 if (var == NULL)
1946 return E_INVALIDARG;
1947 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1949 V_VT(var) = VT_BSTR;
1950 if (This->bUseXPath)
1951 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1952 else
1953 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1954 return S_OK;
1957 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1958 return E_FAIL;
1961 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1963 domdoc_QueryInterface,
1964 domdoc_AddRef,
1965 domdoc_Release,
1966 domdoc_GetTypeInfoCount,
1967 domdoc_GetTypeInfo,
1968 domdoc_GetIDsOfNames,
1969 domdoc_Invoke,
1970 domdoc_get_nodeName,
1971 domdoc_get_nodeValue,
1972 domdoc_put_nodeValue,
1973 domdoc_get_nodeType,
1974 domdoc_get_parentNode,
1975 domdoc_get_childNodes,
1976 domdoc_get_firstChild,
1977 domdoc_get_lastChild,
1978 domdoc_get_previousSibling,
1979 domdoc_get_nextSibling,
1980 domdoc_get_attributes,
1981 domdoc_insertBefore,
1982 domdoc_replaceChild,
1983 domdoc_removeChild,
1984 domdoc_appendChild,
1985 domdoc_hasChildNodes,
1986 domdoc_get_ownerDocument,
1987 domdoc_cloneNode,
1988 domdoc_get_nodeTypeString,
1989 domdoc_get_text,
1990 domdoc_put_text,
1991 domdoc_get_specified,
1992 domdoc_get_definition,
1993 domdoc_get_nodeTypedValue,
1994 domdoc_put_nodeTypedValue,
1995 domdoc_get_dataType,
1996 domdoc_put_dataType,
1997 domdoc_get_xml,
1998 domdoc_transformNode,
1999 domdoc_selectNodes,
2000 domdoc_selectSingleNode,
2001 domdoc_get_parsed,
2002 domdoc_get_namespaceURI,
2003 domdoc_get_prefix,
2004 domdoc_get_baseName,
2005 domdoc_transformNodeToObject,
2006 domdoc_get_doctype,
2007 domdoc_get_implementation,
2008 domdoc_get_documentElement,
2009 domdoc_put_documentElement,
2010 domdoc_createElement,
2011 domdoc_createDocumentFragment,
2012 domdoc_createTextNode,
2013 domdoc_createComment,
2014 domdoc_createCDATASection,
2015 domdoc_createProcessingInstruction,
2016 domdoc_createAttribute,
2017 domdoc_createEntityReference,
2018 domdoc_getElementsByTagName,
2019 domdoc_createNode,
2020 domdoc_nodeFromID,
2021 domdoc_load,
2022 domdoc_get_readyState,
2023 domdoc_get_parseError,
2024 domdoc_get_url,
2025 domdoc_get_async,
2026 domdoc_put_async,
2027 domdoc_abort,
2028 domdoc_loadXML,
2029 domdoc_save,
2030 domdoc_get_validateOnParse,
2031 domdoc_put_validateOnParse,
2032 domdoc_get_resolveExternals,
2033 domdoc_put_resolveExternals,
2034 domdoc_get_preserveWhiteSpace,
2035 domdoc_put_preserveWhiteSpace,
2036 domdoc_put_onReadyStateChange,
2037 domdoc_put_onDataAvailable,
2038 domdoc_put_onTransformNode,
2039 domdoc_get_namespaces,
2040 domdoc_get_schemas,
2041 domdoc_putref_schemas,
2042 domdoc_validate,
2043 domdoc_setProperty,
2044 domdoc_getProperty
2047 /* xmldoc implementation of IObjectWithSite */
2048 static HRESULT WINAPI
2049 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2051 domdoc *This = impl_from_IObjectWithSite(iface);
2052 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2055 static ULONG WINAPI
2056 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2058 domdoc *This = impl_from_IObjectWithSite(iface);
2059 return IXMLDocument_AddRef((IXMLDocument *)This);
2062 static ULONG WINAPI
2063 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2065 domdoc *This = impl_from_IObjectWithSite(iface);
2066 return IXMLDocument_Release((IXMLDocument *)This);
2069 static HRESULT WINAPI
2070 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2072 domdoc *This = impl_from_IObjectWithSite(iface);
2074 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2076 if ( !This->site )
2077 return E_FAIL;
2079 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2082 static HRESULT WINAPI
2083 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2085 domdoc *This = impl_from_IObjectWithSite(iface);
2087 TRACE("%p %p\n", iface, punk);
2089 if(!punk)
2091 if(This->site)
2093 IUnknown_Release( This->site );
2094 This->site = NULL;
2097 return S_OK;
2100 if ( punk )
2101 IUnknown_AddRef( punk );
2103 if(This->site)
2104 IUnknown_Release( This->site );
2106 This->site = punk;
2108 return S_OK;
2111 static const IObjectWithSiteVtbl domdocObjectSite =
2113 xmldoc_ObjectWithSite_QueryInterface,
2114 xmldoc_ObjectWithSite_AddRef,
2115 xmldoc_ObjectWithSite_Release,
2116 xmldoc_SetSite,
2117 xmldoc_GetSite,
2120 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2122 domdoc *This = impl_from_IObjectSafety(iface);
2123 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2126 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2128 domdoc *This = impl_from_IObjectSafety(iface);
2129 return IXMLDocument_AddRef((IXMLDocument *)This);
2132 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2134 domdoc *This = impl_from_IObjectSafety(iface);
2135 return IXMLDocument_Release((IXMLDocument *)This);
2138 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2140 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2141 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2143 domdoc *This = impl_from_IObjectSafety(iface);
2145 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2147 if(!pdwSupportedOptions || !pdwEnabledOptions)
2148 return E_POINTER;
2150 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2151 *pdwEnabledOptions = This->safeopt;
2153 return S_OK;
2156 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2157 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2159 domdoc *This = impl_from_IObjectSafety(iface);
2161 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2163 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2164 return E_FAIL;
2166 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2167 return S_OK;
2170 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2171 xmldoc_Safety_QueryInterface,
2172 xmldoc_Safety_AddRef,
2173 xmldoc_Safety_Release,
2174 xmldoc_Safety_GetInterfaceSafetyOptions,
2175 xmldoc_Safety_SetInterfaceSafetyOptions
2179 static const tid_t domdoc_iface_tids[] = {
2180 IXMLDOMNode_tid,
2181 IXMLDOMDocument_tid,
2182 IXMLDOMDocument2_tid,
2185 static dispex_static_data_t domdoc_dispex = {
2186 NULL,
2187 IXMLDOMDocument2_tid,
2188 NULL,
2189 domdoc_iface_tids
2192 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2194 domdoc *doc;
2196 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2197 if( !doc )
2198 return E_OUTOFMEMORY;
2200 doc->lpVtbl = &domdoc_vtbl;
2201 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2202 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2203 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2204 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2205 doc->ref = 1;
2206 doc->async = VARIANT_TRUE;
2207 doc->validating = 0;
2208 doc->resolving = 0;
2209 doc->preserving = 0;
2210 doc->bUseXPath = FALSE;
2211 doc->error = S_OK;
2212 doc->schema = NULL;
2213 doc->stream = NULL;
2214 doc->site = NULL;
2215 doc->safeopt = 0;
2216 doc->bsc = NULL;
2218 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2220 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2222 TRACE("returning iface %p\n", *document);
2223 return S_OK;
2226 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2228 xmlDocPtr xmldoc;
2229 HRESULT hr;
2231 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2233 xmldoc = xmlNewDoc(NULL);
2234 if(!xmldoc)
2235 return E_OUTOFMEMORY;
2237 xmldoc->_private = create_priv();
2239 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2240 if(FAILED(hr))
2241 xmlFreeDoc(xmldoc);
2243 return hr;
2246 IUnknown* create_domdoc( xmlNodePtr document )
2248 HRESULT hr;
2249 LPVOID pObj = NULL;
2251 TRACE("(%p)\n", document);
2253 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2254 if (FAILED(hr))
2255 return NULL;
2257 return pObj;
2260 #else
2262 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2264 MESSAGE("This program tried to use a DOMDocument object, but\n"
2265 "libxml2 support was not present at compile time.\n");
2266 return E_NOTIMPL;
2269 #endif