jscript: Don't try to create property in jsdisp_call_name.
[wine.git] / dlls / msxml3 / domdoc.c
bloba7c1680f580dd3edf0bc14d3d9c49450927696e5
1 /*
2 * DOM Document implementation
4 * Copyright 2005 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #define NONAMELESSUNION
24 #include "config.h"
26 #include <stdarg.h>
27 #include <assert.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "winnls.h"
32 #include "ole2.h"
33 #include "msxml2.h"
34 #include "wininet.h"
35 #include "winreg.h"
36 #include "shlwapi.h"
37 #include "ocidl.h"
38 #include "objsafe.h"
39 #include "dispex.h"
41 #include "wine/debug.h"
42 #include "wine/list.h"
44 #include "msxml_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
48 #ifdef HAVE_LIBXML2
50 #include <libxml/xmlsave.h>
52 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};
53 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
54 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
56 typedef struct _domdoc
58 xmlnode node;
59 const struct IXMLDOMDocument2Vtbl *lpVtbl;
60 const struct IPersistStreamVtbl *lpvtblIPersistStream;
61 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
62 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
63 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
64 LONG ref;
65 VARIANT_BOOL async;
66 VARIANT_BOOL validating;
67 VARIANT_BOOL resolving;
68 VARIANT_BOOL preserving;
69 BOOL bUseXPath;
70 IXMLDOMSchemaCollection *schema;
71 bsc_t *bsc;
72 HRESULT error;
74 /* IPersistStream */
75 IStream *stream;
77 /* IObjectWithSite*/
78 IUnknown *site;
80 /* IObjectSafety */
81 DWORD safeopt;
82 } domdoc;
85 In native windows, the whole lifetime management of XMLDOMNodes is
86 managed automatically using reference counts. Wine emulates that by
87 maintaining a reference count to the document that is increased for
88 each IXMLDOMNode pointer passed out for this document. If all these
89 pointers are gone, the document is unreachable and gets freed, that
90 is, all nodes in the tree of the document get freed.
92 You are able to create nodes that are associated to a document (in
93 fact, in msxml's XMLDOM model, all nodes are associated to a document),
94 but not in the tree of that document, for example using the createFoo
95 functions from IXMLDOMDocument. These nodes do not get cleaned up
96 by libxml, so we have to do it ourselves.
98 To catch these nodes, a list of "orphan nodes" is introduced.
99 It contains pointers to all roots of node trees that are
100 associated with the document without being part of the document
101 tree. All nodes with parent==NULL (except for the document root nodes)
102 should be in the orphan node list of their document. All orphan nodes
103 get freed together with the document itself.
106 typedef struct _xmldoc_priv {
107 LONG refs;
108 struct list orphans;
109 } xmldoc_priv;
111 typedef struct _orphan_entry {
112 struct list entry;
113 xmlNode * node;
114 } orphan_entry;
116 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
118 return doc->_private;
121 static xmldoc_priv * create_priv(void)
123 xmldoc_priv *priv;
124 priv = heap_alloc( sizeof (*priv) );
126 if(priv)
128 priv->refs = 0;
129 list_init( &priv->orphans );
132 return priv;
135 static xmlDocPtr doparse( char *ptr, int len )
137 #ifdef HAVE_XMLREADMEMORY
139 * use xmlReadMemory if possible so we can suppress
140 * writing errors to stderr
142 return xmlReadMemory( ptr, len, NULL, NULL,
143 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
144 #else
145 return xmlParseMemory( ptr, len );
146 #endif
149 LONG xmldoc_add_ref(xmlDocPtr doc)
151 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
152 TRACE("%d\n", ref);
153 return ref;
156 LONG xmldoc_release(xmlDocPtr doc)
158 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
159 LONG ref = InterlockedDecrement(&priv->refs);
160 TRACE("%d\n", ref);
161 if(ref == 0)
163 orphan_entry *orphan, *orphan2;
164 TRACE("freeing docptr %p\n", doc);
166 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
168 xmlFreeNode( orphan->node );
169 heap_free( orphan );
171 heap_free(doc->_private);
173 xmlFreeDoc(doc);
176 return ref;
179 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
181 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
182 orphan_entry *entry;
184 entry = heap_alloc( sizeof (*entry) );
185 if(!entry)
186 return E_OUTOFMEMORY;
188 entry->node = node;
189 list_add_head( &priv->orphans, &entry->entry );
190 return S_OK;
193 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
195 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
196 orphan_entry *entry, *entry2;
198 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
200 if( entry->node == node )
202 list_remove( &entry->entry );
203 heap_free( entry );
204 return S_OK;
208 return S_FALSE;
211 static HRESULT attach_xmldoc( xmlnode *node, xmlDocPtr xml )
213 if(node->node)
214 xmldoc_release(node->node->doc);
216 node->node = (xmlNodePtr) xml;
217 if(node->node)
218 xmldoc_add_ref(node->node->doc);
220 return S_OK;
223 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
225 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
228 static inline xmlDocPtr get_doc( domdoc *This )
230 return (xmlDocPtr)This->node.node;
233 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
235 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
238 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
240 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
243 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
245 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
248 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
250 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
253 /************************************************************************
254 * xmldoc implementation of IPersistStream.
256 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
257 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
259 domdoc *this = impl_from_IPersistStream(iface);
260 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
263 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
264 IPersistStream *iface)
266 domdoc *this = impl_from_IPersistStream(iface);
267 return IXMLDocument_AddRef((IXMLDocument *)this);
270 static ULONG WINAPI xmldoc_IPersistStream_Release(
271 IPersistStream *iface)
273 domdoc *this = impl_from_IPersistStream(iface);
274 return IXMLDocument_Release((IXMLDocument *)this);
277 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
278 IPersistStream *iface, CLSID *classid)
280 TRACE("(%p,%p): stub!\n", iface, classid);
282 if(!classid)
283 return E_POINTER;
285 *classid = CLSID_DOMDocument2;
287 return S_OK;
290 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
291 IPersistStream *iface)
293 domdoc *This = impl_from_IPersistStream(iface);
295 FIXME("(%p->%p): stub!\n", iface, This);
297 return S_FALSE;
300 static HRESULT WINAPI xmldoc_IPersistStream_Load(
301 IPersistStream *iface, LPSTREAM pStm)
303 domdoc *This = impl_from_IPersistStream(iface);
304 HRESULT hr;
305 HGLOBAL hglobal;
306 DWORD read, written, len;
307 BYTE buf[4096];
308 char *ptr;
309 xmlDocPtr xmldoc = NULL;
311 TRACE("(%p, %p)\n", iface, pStm);
313 if (!pStm)
314 return E_INVALIDARG;
316 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
317 if (FAILED(hr))
318 return hr;
322 IStream_Read(pStm, buf, sizeof(buf), &read);
323 hr = IStream_Write(This->stream, buf, read, &written);
324 } while(SUCCEEDED(hr) && written != 0 && read != 0);
326 if (FAILED(hr))
328 ERR("Failed to copy stream\n");
329 return hr;
332 hr = GetHGlobalFromStream(This->stream, &hglobal);
333 if (FAILED(hr))
334 return hr;
336 len = GlobalSize(hglobal);
337 ptr = GlobalLock(hglobal);
338 if (len != 0)
339 xmldoc = parse_xml(ptr, len);
340 GlobalUnlock(hglobal);
342 if (!xmldoc)
344 ERR("Failed to parse xml\n");
345 return E_FAIL;
348 xmldoc->_private = create_priv();
350 return attach_xmldoc( &This->node, xmldoc );
353 static HRESULT WINAPI xmldoc_IPersistStream_Save(
354 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
356 domdoc *This = impl_from_IPersistStream(iface);
357 HRESULT hr;
358 BSTR xmlString;
360 TRACE("(%p, %p, %d)\n", iface, pStm, fClearDirty);
362 hr = IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), &xmlString );
363 if(hr == S_OK)
365 DWORD count;
366 DWORD len = strlenW(xmlString) * sizeof(WCHAR);
368 hr = IStream_Write( pStm, xmlString, len, &count );
370 SysFreeString(xmlString);
373 TRACE("ret 0x%08x\n", hr);
375 return hr;
378 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
379 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
381 TRACE("(%p, %p): stub!\n", iface, pcbSize);
382 return E_NOTIMPL;
385 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
387 xmldoc_IPersistStream_QueryInterface,
388 xmldoc_IPersistStream_AddRef,
389 xmldoc_IPersistStream_Release,
390 xmldoc_IPersistStream_GetClassID,
391 xmldoc_IPersistStream_IsDirty,
392 xmldoc_IPersistStream_Load,
393 xmldoc_IPersistStream_Save,
394 xmldoc_IPersistStream_GetSizeMax,
397 /* ISupportErrorInfo interface */
398 static HRESULT WINAPI support_error_QueryInterface(
399 ISupportErrorInfo *iface,
400 REFIID riid, void** ppvObj )
402 domdoc *This = impl_from_ISupportErrorInfo(iface);
403 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
406 static ULONG WINAPI support_error_AddRef(
407 ISupportErrorInfo *iface )
409 domdoc *This = impl_from_ISupportErrorInfo(iface);
410 return IXMLDocument_AddRef((IXMLDocument *)This);
413 static ULONG WINAPI support_error_Release(
414 ISupportErrorInfo *iface )
416 domdoc *This = impl_from_ISupportErrorInfo(iface);
417 return IXMLDocument_Release((IXMLDocument *)This);
420 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
421 ISupportErrorInfo *iface,
422 REFIID riid )
424 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
425 return S_FALSE;
428 static const struct ISupportErrorInfoVtbl support_error_vtbl =
430 support_error_QueryInterface,
431 support_error_AddRef,
432 support_error_Release,
433 support_error_InterfaceSupportsErrorInfo
436 /* IXMLDOMDocument2 interface */
437 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
439 domdoc *This = impl_from_IXMLDOMDocument2( iface );
441 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
443 *ppvObject = NULL;
445 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
446 IsEqualGUID( riid, &IID_IDispatch ) ||
447 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
448 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
450 *ppvObject = iface;
452 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
454 *ppvObject = IXMLDOMNode_from_impl(&This->node);
456 else if (IsEqualGUID(&IID_IPersistStream, riid))
458 *ppvObject = &(This->lpvtblIPersistStream);
460 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
462 *ppvObject = &(This->lpvtblIObjectWithSite);
464 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
466 *ppvObject = &This->lpvtblISupportErrorInfo;
468 else if(dispex_query_interface(&This->node.dispex, riid, ppvObject))
470 return *ppvObject ? S_OK : E_NOINTERFACE;
472 else if(IsEqualGUID(&IID_IRunnableObject, riid))
474 TRACE("IID_IRunnableObject not supported returning NULL\n");
475 return E_NOINTERFACE;
477 else
479 FIXME("interface %s not implemented\n", debugstr_guid(riid));
480 return E_NOINTERFACE;
483 IUnknown_AddRef((IUnknown*)*ppvObject);
485 return S_OK;
489 static ULONG WINAPI domdoc_AddRef(
490 IXMLDOMDocument2 *iface )
492 domdoc *This = impl_from_IXMLDOMDocument2( iface );
493 TRACE("%p\n", This );
494 return InterlockedIncrement( &This->ref );
498 static ULONG WINAPI domdoc_Release(
499 IXMLDOMDocument2 *iface )
501 domdoc *This = impl_from_IXMLDOMDocument2( iface );
502 LONG ref;
504 TRACE("%p\n", This );
506 ref = InterlockedDecrement( &This->ref );
507 if ( ref == 0 )
509 if(This->bsc)
510 detach_bsc(This->bsc);
512 if (This->site)
513 IUnknown_Release( This->site );
514 destroy_xmlnode(&This->node);
515 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
516 if (This->stream) IStream_Release(This->stream);
517 HeapFree( GetProcessHeap(), 0, This );
520 return ref;
523 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
525 domdoc *This = impl_from_IXMLDOMDocument2( iface );
527 TRACE("(%p)->(%p)\n", This, pctinfo);
529 *pctinfo = 1;
531 return S_OK;
534 static HRESULT WINAPI domdoc_GetTypeInfo(
535 IXMLDOMDocument2 *iface,
536 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
538 domdoc *This = impl_from_IXMLDOMDocument2( iface );
539 HRESULT hr;
541 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
543 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
545 return hr;
548 static HRESULT WINAPI domdoc_GetIDsOfNames(
549 IXMLDOMDocument2 *iface,
550 REFIID riid,
551 LPOLESTR* rgszNames,
552 UINT cNames,
553 LCID lcid,
554 DISPID* rgDispId)
556 domdoc *This = impl_from_IXMLDOMDocument2( iface );
557 ITypeInfo *typeinfo;
558 HRESULT hr;
560 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
561 lcid, rgDispId);
563 if(!rgszNames || cNames == 0 || !rgDispId)
564 return E_INVALIDARG;
566 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
567 if(SUCCEEDED(hr))
569 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
570 ITypeInfo_Release(typeinfo);
573 return hr;
577 static HRESULT WINAPI domdoc_Invoke(
578 IXMLDOMDocument2 *iface,
579 DISPID dispIdMember,
580 REFIID riid,
581 LCID lcid,
582 WORD wFlags,
583 DISPPARAMS* pDispParams,
584 VARIANT* pVarResult,
585 EXCEPINFO* pExcepInfo,
586 UINT* puArgErr)
588 domdoc *This = impl_from_IXMLDOMDocument2( iface );
589 ITypeInfo *typeinfo;
590 HRESULT hr;
592 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
593 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
595 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
596 if(SUCCEEDED(hr))
598 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
599 pVarResult, pExcepInfo, puArgErr);
600 ITypeInfo_Release(typeinfo);
603 return hr;
607 static HRESULT WINAPI domdoc_get_nodeName(
608 IXMLDOMDocument2 *iface,
609 BSTR* name )
611 domdoc *This = impl_from_IXMLDOMDocument2( iface );
612 return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), name );
616 static HRESULT WINAPI domdoc_get_nodeValue(
617 IXMLDOMDocument2 *iface,
618 VARIANT* value )
620 domdoc *This = impl_from_IXMLDOMDocument2( iface );
621 return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
625 static HRESULT WINAPI domdoc_put_nodeValue(
626 IXMLDOMDocument2 *iface,
627 VARIANT value)
629 domdoc *This = impl_from_IXMLDOMDocument2( iface );
630 return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), value );
634 static HRESULT WINAPI domdoc_get_nodeType(
635 IXMLDOMDocument2 *iface,
636 DOMNodeType* type )
638 domdoc *This = impl_from_IXMLDOMDocument2( iface );
639 return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), type );
643 static HRESULT WINAPI domdoc_get_parentNode(
644 IXMLDOMDocument2 *iface,
645 IXMLDOMNode** parent )
647 domdoc *This = impl_from_IXMLDOMDocument2( iface );
648 return IXMLDOMNode_get_parentNode( IXMLDOMNode_from_impl(&This->node), parent );
652 static HRESULT WINAPI domdoc_get_childNodes(
653 IXMLDOMDocument2 *iface,
654 IXMLDOMNodeList** childList )
656 domdoc *This = impl_from_IXMLDOMDocument2( iface );
657 return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), childList );
661 static HRESULT WINAPI domdoc_get_firstChild(
662 IXMLDOMDocument2 *iface,
663 IXMLDOMNode** firstChild )
665 domdoc *This = impl_from_IXMLDOMDocument2( iface );
666 return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), firstChild );
670 static HRESULT WINAPI domdoc_get_lastChild(
671 IXMLDOMDocument2 *iface,
672 IXMLDOMNode** lastChild )
674 domdoc *This = impl_from_IXMLDOMDocument2( iface );
675 return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), lastChild );
679 static HRESULT WINAPI domdoc_get_previousSibling(
680 IXMLDOMDocument2 *iface,
681 IXMLDOMNode** previousSibling )
683 domdoc *This = impl_from_IXMLDOMDocument2( iface );
684 return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), previousSibling );
688 static HRESULT WINAPI domdoc_get_nextSibling(
689 IXMLDOMDocument2 *iface,
690 IXMLDOMNode** nextSibling )
692 domdoc *This = impl_from_IXMLDOMDocument2( iface );
693 return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), nextSibling );
697 static HRESULT WINAPI domdoc_get_attributes(
698 IXMLDOMDocument2 *iface,
699 IXMLDOMNamedNodeMap** attributeMap )
701 domdoc *This = impl_from_IXMLDOMDocument2( iface );
702 return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
706 static HRESULT WINAPI domdoc_insertBefore(
707 IXMLDOMDocument2 *iface,
708 IXMLDOMNode* newChild,
709 VARIANT refChild,
710 IXMLDOMNode** outNewChild )
712 domdoc *This = impl_from_IXMLDOMDocument2( iface );
713 return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newChild, refChild, outNewChild );
717 static HRESULT WINAPI domdoc_replaceChild(
718 IXMLDOMDocument2 *iface,
719 IXMLDOMNode* newChild,
720 IXMLDOMNode* oldChild,
721 IXMLDOMNode** outOldChild)
723 domdoc *This = impl_from_IXMLDOMDocument2( iface );
724 return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newChild, oldChild, outOldChild );
728 static HRESULT WINAPI domdoc_removeChild(
729 IXMLDOMDocument2 *iface,
730 IXMLDOMNode* childNode,
731 IXMLDOMNode** oldChild)
733 domdoc *This = impl_from_IXMLDOMDocument2( iface );
734 return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), childNode, oldChild );
738 static HRESULT WINAPI domdoc_appendChild(
739 IXMLDOMDocument2 *iface,
740 IXMLDOMNode* newChild,
741 IXMLDOMNode** outNewChild)
743 domdoc *This = impl_from_IXMLDOMDocument2( iface );
744 return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newChild, outNewChild );
748 static HRESULT WINAPI domdoc_hasChildNodes(
749 IXMLDOMDocument2 *iface,
750 VARIANT_BOOL* hasChild)
752 domdoc *This = impl_from_IXMLDOMDocument2( iface );
753 return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), hasChild );
757 static HRESULT WINAPI domdoc_get_ownerDocument(
758 IXMLDOMDocument2 *iface,
759 IXMLDOMDocument** DOMDocument)
761 domdoc *This = impl_from_IXMLDOMDocument2( iface );
762 return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), DOMDocument );
766 static HRESULT WINAPI domdoc_cloneNode(
767 IXMLDOMDocument2 *iface,
768 VARIANT_BOOL deep,
769 IXMLDOMNode** cloneRoot)
771 domdoc *This = impl_from_IXMLDOMDocument2( iface );
772 return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), deep, cloneRoot );
776 static HRESULT WINAPI domdoc_get_nodeTypeString(
777 IXMLDOMDocument2 *iface,
778 BSTR* nodeType )
780 domdoc *This = impl_from_IXMLDOMDocument2( iface );
781 return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), nodeType );
785 static HRESULT WINAPI domdoc_get_text(
786 IXMLDOMDocument2 *iface,
787 BSTR* text )
789 domdoc *This = impl_from_IXMLDOMDocument2( iface );
790 return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), text );
794 static HRESULT WINAPI domdoc_put_text(
795 IXMLDOMDocument2 *iface,
796 BSTR text )
798 domdoc *This = impl_from_IXMLDOMDocument2( iface );
799 return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), text );
803 static HRESULT WINAPI domdoc_get_specified(
804 IXMLDOMDocument2 *iface,
805 VARIANT_BOOL* isSpecified )
807 domdoc *This = impl_from_IXMLDOMDocument2( iface );
808 return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), isSpecified );
812 static HRESULT WINAPI domdoc_get_definition(
813 IXMLDOMDocument2 *iface,
814 IXMLDOMNode** definitionNode )
816 domdoc *This = impl_from_IXMLDOMDocument2( iface );
817 return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), definitionNode );
821 static HRESULT WINAPI domdoc_get_nodeTypedValue(
822 IXMLDOMDocument2 *iface,
823 VARIANT* typedValue )
825 domdoc *This = impl_from_IXMLDOMDocument2( iface );
826 return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
829 static HRESULT WINAPI domdoc_put_nodeTypedValue(
830 IXMLDOMDocument2 *iface,
831 VARIANT typedValue )
833 domdoc *This = impl_from_IXMLDOMDocument2( iface );
834 return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), typedValue );
838 static HRESULT WINAPI domdoc_get_dataType(
839 IXMLDOMDocument2 *iface,
840 VARIANT* dataTypeName )
842 domdoc *This = impl_from_IXMLDOMDocument2( iface );
843 return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
847 static HRESULT WINAPI domdoc_put_dataType(
848 IXMLDOMDocument2 *iface,
849 BSTR dataTypeName )
851 domdoc *This = impl_from_IXMLDOMDocument2( iface );
852 return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), dataTypeName );
856 static HRESULT WINAPI domdoc_get_xml(
857 IXMLDOMDocument2 *iface,
858 BSTR* xmlString )
860 domdoc *This = impl_from_IXMLDOMDocument2( iface );
861 return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), xmlString );
865 static HRESULT WINAPI domdoc_transformNode(
866 IXMLDOMDocument2 *iface,
867 IXMLDOMNode* styleSheet,
868 BSTR* xmlString )
870 domdoc *This = impl_from_IXMLDOMDocument2( iface );
871 return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), styleSheet, xmlString );
875 static HRESULT WINAPI domdoc_selectNodes(
876 IXMLDOMDocument2 *iface,
877 BSTR queryString,
878 IXMLDOMNodeList** resultList )
880 domdoc *This = impl_from_IXMLDOMDocument2( iface );
881 return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), queryString, resultList );
885 static HRESULT WINAPI domdoc_selectSingleNode(
886 IXMLDOMDocument2 *iface,
887 BSTR queryString,
888 IXMLDOMNode** resultNode )
890 domdoc *This = impl_from_IXMLDOMDocument2( iface );
891 return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), queryString, resultNode );
895 static HRESULT WINAPI domdoc_get_parsed(
896 IXMLDOMDocument2 *iface,
897 VARIANT_BOOL* isParsed )
899 domdoc *This = impl_from_IXMLDOMDocument2( iface );
900 return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), isParsed );
904 static HRESULT WINAPI domdoc_get_namespaceURI(
905 IXMLDOMDocument2 *iface,
906 BSTR* namespaceURI )
908 domdoc *This = impl_from_IXMLDOMDocument2( iface );
909 return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), namespaceURI );
913 static HRESULT WINAPI domdoc_get_prefix(
914 IXMLDOMDocument2 *iface,
915 BSTR* prefixString )
917 domdoc *This = impl_from_IXMLDOMDocument2( iface );
918 return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), prefixString );
922 static HRESULT WINAPI domdoc_get_baseName(
923 IXMLDOMDocument2 *iface,
924 BSTR* nameString )
926 domdoc *This = impl_from_IXMLDOMDocument2( iface );
927 return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), nameString );
931 static HRESULT WINAPI domdoc_transformNodeToObject(
932 IXMLDOMDocument2 *iface,
933 IXMLDOMNode* stylesheet,
934 VARIANT outputObject)
936 domdoc *This = impl_from_IXMLDOMDocument2( iface );
937 return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), stylesheet, outputObject );
941 static HRESULT WINAPI domdoc_get_doctype(
942 IXMLDOMDocument2 *iface,
943 IXMLDOMDocumentType** documentType )
945 FIXME("\n");
946 return E_NOTIMPL;
950 static HRESULT WINAPI domdoc_get_implementation(
951 IXMLDOMDocument2 *iface,
952 IXMLDOMImplementation** impl )
954 if(!impl)
955 return E_INVALIDARG;
957 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
959 return S_OK;
962 static HRESULT WINAPI domdoc_get_documentElement(
963 IXMLDOMDocument2 *iface,
964 IXMLDOMElement** DOMElement )
966 domdoc *This = impl_from_IXMLDOMDocument2( iface );
967 xmlDocPtr xmldoc = NULL;
968 xmlNodePtr root = NULL;
969 IXMLDOMNode *element_node;
970 HRESULT hr;
972 TRACE("%p\n", This);
974 if(!DOMElement)
975 return E_INVALIDARG;
977 *DOMElement = NULL;
979 xmldoc = get_doc( This );
981 root = xmlDocGetRootElement( xmldoc );
982 if ( !root )
983 return S_FALSE;
985 element_node = create_node( root );
986 if(!element_node) return S_FALSE;
988 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
989 IXMLDOMNode_Release(element_node);
991 return hr;
995 static HRESULT WINAPI domdoc_put_documentElement(
996 IXMLDOMDocument2 *iface,
997 IXMLDOMElement* DOMElement )
999 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1000 IXMLDOMNode *elementNode;
1001 xmlNodePtr oldRoot;
1002 xmlnode *xmlNode;
1003 HRESULT hr;
1005 TRACE("(%p)->(%p)\n", This, DOMElement);
1007 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
1008 if(FAILED(hr))
1009 return hr;
1011 xmlNode = impl_from_IXMLDOMNode( elementNode );
1013 if(!xmlNode->node->parent)
1014 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1015 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1017 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1018 IXMLDOMNode_Release( elementNode );
1020 if(oldRoot)
1021 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1023 return S_OK;
1027 static HRESULT WINAPI domdoc_createElement(
1028 IXMLDOMDocument2 *iface,
1029 BSTR tagname,
1030 IXMLDOMElement** element )
1032 xmlNodePtr xmlnode;
1033 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1034 xmlChar *xml_name;
1035 IUnknown *elem_unk;
1036 HRESULT hr;
1038 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1040 xml_name = xmlChar_from_wchar(tagname);
1041 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1042 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1044 TRACE("created xmlptr %p\n", xmlnode);
1045 elem_unk = create_element(xmlnode);
1046 heap_free(xml_name);
1048 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1049 IUnknown_Release(elem_unk);
1050 TRACE("returning %p\n", *element);
1051 return hr;
1055 static HRESULT WINAPI domdoc_createDocumentFragment(
1056 IXMLDOMDocument2 *iface,
1057 IXMLDOMDocumentFragment** docFrag )
1059 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1060 xmlNodePtr xmlnode;
1062 TRACE("%p\n", iface);
1064 if(!docFrag)
1065 return E_INVALIDARG;
1067 *docFrag = NULL;
1069 xmlnode = xmlNewDocFragment(get_doc( This ) );
1071 if(!xmlnode)
1072 return E_FAIL;
1074 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1075 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1077 return S_OK;
1081 static HRESULT WINAPI domdoc_createTextNode(
1082 IXMLDOMDocument2 *iface,
1083 BSTR data,
1084 IXMLDOMText** text )
1086 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1087 xmlNodePtr xmlnode;
1088 xmlChar *xml_content;
1090 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1092 if(!text)
1093 return E_INVALIDARG;
1095 *text = NULL;
1097 xml_content = xmlChar_from_wchar(data);
1098 xmlnode = xmlNewText(xml_content);
1099 heap_free(xml_content);
1101 if(!xmlnode)
1102 return E_FAIL;
1104 xmlnode->doc = get_doc( This );
1105 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1107 *text = (IXMLDOMText*)create_text(xmlnode);
1109 return S_OK;
1113 static HRESULT WINAPI domdoc_createComment(
1114 IXMLDOMDocument2 *iface,
1115 BSTR data,
1116 IXMLDOMComment** comment )
1118 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1119 xmlNodePtr xmlnode;
1120 xmlChar *xml_content;
1122 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1124 if(!comment)
1125 return E_INVALIDARG;
1127 *comment = NULL;
1129 xml_content = xmlChar_from_wchar(data);
1130 xmlnode = xmlNewComment(xml_content);
1131 heap_free(xml_content);
1133 if(!xmlnode)
1134 return E_FAIL;
1136 xmlnode->doc = get_doc( This );
1137 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1139 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1141 return S_OK;
1145 static HRESULT WINAPI domdoc_createCDATASection(
1146 IXMLDOMDocument2 *iface,
1147 BSTR data,
1148 IXMLDOMCDATASection** cdata )
1150 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1151 xmlNodePtr xmlnode;
1152 xmlChar *xml_content;
1154 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1156 if(!cdata)
1157 return E_INVALIDARG;
1159 *cdata = NULL;
1161 xml_content = xmlChar_from_wchar(data);
1162 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1163 heap_free(xml_content);
1165 if(!xmlnode)
1166 return E_FAIL;
1168 xmlnode->doc = get_doc( This );
1169 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1171 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1173 return S_OK;
1177 static HRESULT WINAPI domdoc_createProcessingInstruction(
1178 IXMLDOMDocument2 *iface,
1179 BSTR target,
1180 BSTR data,
1181 IXMLDOMProcessingInstruction** pi )
1183 #ifdef HAVE_XMLNEWDOCPI
1184 xmlNodePtr xmlnode;
1185 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1186 xmlChar *xml_target, *xml_content;
1188 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1190 if(!pi)
1191 return E_INVALIDARG;
1193 if(!target || lstrlenW(target) == 0)
1194 return E_FAIL;
1196 xml_target = xmlChar_from_wchar(target);
1197 xml_content = xmlChar_from_wchar(data);
1199 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1200 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1201 TRACE("created xmlptr %p\n", xmlnode);
1202 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1204 heap_free(xml_content);
1205 heap_free(xml_target);
1207 return S_OK;
1208 #else
1209 FIXME("Libxml 2.6.15 or greater required.\n");
1210 return E_NOTIMPL;
1211 #endif
1215 static HRESULT WINAPI domdoc_createAttribute(
1216 IXMLDOMDocument2 *iface,
1217 BSTR name,
1218 IXMLDOMAttribute** attribute )
1220 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1221 xmlNodePtr xmlnode;
1222 xmlChar *xml_name;
1224 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1226 if(!attribute)
1227 return E_INVALIDARG;
1229 *attribute = NULL;
1231 xml_name = xmlChar_from_wchar(name);
1232 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1233 heap_free(xml_name);
1235 if(!xmlnode)
1236 return E_FAIL;
1238 xmlnode->doc = get_doc( This );
1239 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1241 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1243 return S_OK;
1247 static HRESULT WINAPI domdoc_createEntityReference(
1248 IXMLDOMDocument2 *iface,
1249 BSTR name,
1250 IXMLDOMEntityReference** entityRef )
1252 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1253 xmlNodePtr xmlnode;
1254 xmlChar *xml_name;
1256 TRACE("%p\n", iface);
1258 if(!entityRef)
1259 return E_INVALIDARG;
1261 *entityRef = NULL;
1263 xml_name = xmlChar_from_wchar(name);
1264 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1265 heap_free(xml_name);
1267 if(!xmlnode)
1268 return E_FAIL;
1270 xmlnode->doc = get_doc( This );
1271 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1273 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1275 return S_OK;
1279 static HRESULT WINAPI domdoc_getElementsByTagName(
1280 IXMLDOMDocument2 *iface,
1281 BSTR tagName,
1282 IXMLDOMNodeList** resultList )
1284 static const WCHAR xpathformat[] =
1285 { '/','/','*','[','l','o','c','a','l','-','n','a','m','e','(',')','=','\'','%','s','\'',']',0 };
1286 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1287 LPWSTR szPattern;
1288 HRESULT hr;
1289 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1291 if (tagName[0] == '*' && tagName[1] == 0)
1293 szPattern = heap_alloc(sizeof(WCHAR)*4);
1294 szPattern[0] = szPattern[1] = '/';
1295 szPattern[2] = '*';
1296 szPattern[3] = 0;
1298 else
1300 szPattern = heap_alloc(sizeof(WCHAR)*(20+lstrlenW(tagName)+1));
1301 wsprintfW(szPattern, xpathformat, tagName);
1304 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1305 heap_free(szPattern);
1307 return hr;
1310 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1312 VARIANT tmp;
1313 HRESULT hr;
1315 VariantInit(&tmp);
1316 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1317 if(FAILED(hr))
1318 return E_INVALIDARG;
1320 *type = V_I4(&tmp);
1322 return S_OK;
1325 static HRESULT WINAPI domdoc_createNode(
1326 IXMLDOMDocument2 *iface,
1327 VARIANT Type,
1328 BSTR name,
1329 BSTR namespaceURI,
1330 IXMLDOMNode** node )
1332 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1333 DOMNodeType node_type;
1334 xmlNodePtr xmlnode = NULL;
1335 xmlChar *xml_name;
1336 HRESULT hr;
1338 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1340 if(namespaceURI && namespaceURI[0])
1341 FIXME("nodes with namespaces currently not supported.\n");
1343 hr = get_node_type(Type, &node_type);
1344 if(FAILED(hr))
1345 return hr;
1347 TRACE("node_type %d\n", node_type);
1349 xml_name = xmlChar_from_wchar(name);
1351 switch(node_type)
1353 case NODE_ELEMENT:
1354 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1355 *node = create_node(xmlnode);
1356 TRACE("created %p\n", xmlnode);
1357 break;
1358 case NODE_ATTRIBUTE:
1359 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1360 if(xmlnode)
1362 xmlnode->doc = get_doc( This );
1364 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1367 TRACE("created %p\n", xmlnode);
1368 break;
1370 default:
1371 FIXME("unhandled node type %d\n", node_type);
1372 break;
1375 heap_free(xml_name);
1377 if(xmlnode && *node)
1379 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1380 return S_OK;
1383 return E_FAIL;
1386 static HRESULT WINAPI domdoc_nodeFromID(
1387 IXMLDOMDocument2 *iface,
1388 BSTR idString,
1389 IXMLDOMNode** node )
1391 FIXME("\n");
1392 return E_NOTIMPL;
1395 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1397 domdoc *This = obj;
1398 xmlDocPtr xmldoc;
1400 xmldoc = doparse( ptr, len );
1401 if(xmldoc) {
1402 xmldoc->_private = create_priv();
1403 return attach_xmldoc(&This->node, xmldoc);
1406 return S_OK;
1409 static HRESULT doread( domdoc *This, LPWSTR filename )
1411 bsc_t *bsc;
1412 HRESULT hr;
1414 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1415 if(FAILED(hr))
1416 return hr;
1418 if(This->bsc)
1419 detach_bsc(This->bsc);
1421 This->bsc = bsc;
1422 return S_OK;
1425 static HRESULT WINAPI domdoc_load(
1426 IXMLDOMDocument2 *iface,
1427 VARIANT xmlSource,
1428 VARIANT_BOOL* isSuccessful )
1430 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1431 LPWSTR filename = NULL;
1432 HRESULT hr = S_FALSE;
1433 IXMLDOMDocument2 *pNewDoc = NULL;
1434 IStream *pStream = NULL;
1435 xmlDocPtr xmldoc;
1437 TRACE("type %d\n", V_VT(&xmlSource) );
1439 *isSuccessful = VARIANT_FALSE;
1441 assert( &This->node );
1443 switch( V_VT(&xmlSource) )
1445 case VT_BSTR:
1446 filename = V_BSTR(&xmlSource);
1447 break;
1448 case VT_UNKNOWN:
1449 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1450 if(hr == S_OK)
1452 if(pNewDoc)
1454 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1455 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1456 hr = attach_xmldoc(&This->node, xmldoc);
1458 if(SUCCEEDED(hr))
1459 *isSuccessful = VARIANT_TRUE;
1461 return hr;
1464 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1465 if(hr == S_OK)
1467 IPersistStream *pDocStream;
1468 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1469 if(hr == S_OK)
1471 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1472 IStream_Release(pStream);
1473 if(hr == S_OK)
1475 *isSuccessful = VARIANT_TRUE;
1477 TRACE("Using ID_IStream to load Document\n");
1478 return S_OK;
1480 else
1482 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1485 else
1487 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1490 else
1492 /* ISequentialStream */
1493 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1495 break;
1496 default:
1497 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1500 TRACE("filename (%s)\n", debugstr_w(filename));
1502 if ( filename )
1504 hr = doread( This, filename );
1506 if ( FAILED(hr) )
1507 This->error = E_FAIL;
1508 else
1510 hr = This->error = S_OK;
1511 *isSuccessful = VARIANT_TRUE;
1515 if(!filename || FAILED(hr)) {
1516 xmldoc = xmlNewDoc(NULL);
1517 xmldoc->_private = create_priv();
1518 hr = attach_xmldoc(&This->node, xmldoc);
1519 if(SUCCEEDED(hr))
1520 hr = S_FALSE;
1523 TRACE("ret (%d)\n", hr);
1525 return hr;
1529 static HRESULT WINAPI domdoc_get_readyState(
1530 IXMLDOMDocument2 *iface,
1531 LONG *value )
1533 FIXME("\n");
1534 return E_NOTIMPL;
1538 static HRESULT WINAPI domdoc_get_parseError(
1539 IXMLDOMDocument2 *iface,
1540 IXMLDOMParseError** errorObj )
1542 BSTR error_string = NULL;
1543 static const WCHAR err[] = {'e','r','r','o','r',0};
1544 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1546 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1548 if(This->error)
1549 error_string = SysAllocString(err);
1551 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1552 if(!*errorObj) return E_OUTOFMEMORY;
1553 return S_OK;
1557 static HRESULT WINAPI domdoc_get_url(
1558 IXMLDOMDocument2 *iface,
1559 BSTR* urlString )
1561 FIXME("\n");
1562 return E_NOTIMPL;
1566 static HRESULT WINAPI domdoc_get_async(
1567 IXMLDOMDocument2 *iface,
1568 VARIANT_BOOL* isAsync )
1570 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1572 TRACE("%p <- %d\n", isAsync, This->async);
1573 *isAsync = This->async;
1574 return S_OK;
1578 static HRESULT WINAPI domdoc_put_async(
1579 IXMLDOMDocument2 *iface,
1580 VARIANT_BOOL isAsync )
1582 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1584 TRACE("%d\n", isAsync);
1585 This->async = isAsync;
1586 return S_OK;
1590 static HRESULT WINAPI domdoc_abort(
1591 IXMLDOMDocument2 *iface )
1593 FIXME("\n");
1594 return E_NOTIMPL;
1598 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1600 UINT len, blen = SysStringLen( bstr );
1601 LPSTR str;
1603 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1604 str = heap_alloc( len );
1605 if ( !str )
1606 return FALSE;
1607 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1608 *plen = len;
1609 *pstr = str;
1610 return TRUE;
1613 static HRESULT WINAPI domdoc_loadXML(
1614 IXMLDOMDocument2 *iface,
1615 BSTR bstrXML,
1616 VARIANT_BOOL* isSuccessful )
1618 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1619 xmlDocPtr xmldoc = NULL;
1620 char *str;
1621 int len;
1622 HRESULT hr = S_FALSE, hr2;
1624 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1626 assert ( &This->node );
1628 if ( isSuccessful )
1630 *isSuccessful = VARIANT_FALSE;
1632 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1634 xmldoc = doparse( str, len );
1635 heap_free( str );
1636 if ( !xmldoc )
1637 This->error = E_FAIL;
1638 else
1640 hr = This->error = S_OK;
1641 *isSuccessful = VARIANT_TRUE;
1645 if(!xmldoc)
1646 xmldoc = xmlNewDoc(NULL);
1648 xmldoc->_private = create_priv();
1649 hr2 = attach_xmldoc( &This->node, xmldoc );
1650 if( FAILED(hr2) )
1651 hr = hr2;
1653 return hr;
1656 static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
1657 int len)
1659 DWORD written = -1;
1661 if(!WriteFile(ctx, buffer, len, &written, NULL))
1663 WARN("write error\n");
1664 return -1;
1666 else
1667 return written;
1670 static int XMLCALL domdoc_save_closecallback(void *ctx)
1672 return CloseHandle(ctx) ? 0 : -1;
1675 static HRESULT WINAPI domdoc_save(
1676 IXMLDOMDocument2 *iface,
1677 VARIANT destination )
1679 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1680 HANDLE handle;
1681 xmlSaveCtxtPtr ctx;
1682 HRESULT ret = S_OK;
1684 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1685 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1687 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1689 FIXME("Unhandled vt %d\n", V_VT(&destination));
1690 return S_FALSE;
1693 if(V_VT(&destination) == VT_UNKNOWN)
1695 IUnknown *pUnk = V_UNKNOWN(&destination);
1696 IXMLDOMDocument *pDocument;
1698 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1699 if(ret == S_OK)
1701 BSTR bXML;
1702 VARIANT_BOOL bSuccessful;
1704 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1705 if(ret == S_OK)
1707 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1709 SysFreeString(bXML);
1712 IXMLDOMDocument_Release(pDocument);
1715 TRACE("ret %d\n", ret);
1717 return ret;
1720 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1721 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1722 if( handle == INVALID_HANDLE_VALUE )
1724 WARN("failed to create file\n");
1725 return S_FALSE;
1728 /* disable top XML declaration */
1729 ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
1730 handle, NULL, XML_SAVE_NO_DECL);
1731 if (!ctx)
1733 CloseHandle(handle);
1734 return S_FALSE;
1737 if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
1738 /* will close file through close callback */
1739 xmlSaveClose(ctx);
1741 return ret;
1744 static HRESULT WINAPI domdoc_get_validateOnParse(
1745 IXMLDOMDocument2 *iface,
1746 VARIANT_BOOL* isValidating )
1748 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1750 TRACE("%p <- %d\n", isValidating, This->validating);
1751 *isValidating = This->validating;
1752 return S_OK;
1756 static HRESULT WINAPI domdoc_put_validateOnParse(
1757 IXMLDOMDocument2 *iface,
1758 VARIANT_BOOL isValidating )
1760 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1762 TRACE("%d\n", isValidating);
1763 This->validating = isValidating;
1764 return S_OK;
1768 static HRESULT WINAPI domdoc_get_resolveExternals(
1769 IXMLDOMDocument2 *iface,
1770 VARIANT_BOOL* isResolving )
1772 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1774 TRACE("%p <- %d\n", isResolving, This->resolving);
1775 *isResolving = This->resolving;
1776 return S_OK;
1780 static HRESULT WINAPI domdoc_put_resolveExternals(
1781 IXMLDOMDocument2 *iface,
1782 VARIANT_BOOL isResolving )
1784 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1786 TRACE("%d\n", isResolving);
1787 This->resolving = isResolving;
1788 return S_OK;
1792 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1793 IXMLDOMDocument2 *iface,
1794 VARIANT_BOOL* isPreserving )
1796 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1798 TRACE("%p <- %d\n", isPreserving, This->preserving);
1799 *isPreserving = This->preserving;
1800 return S_OK;
1804 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1805 IXMLDOMDocument2 *iface,
1806 VARIANT_BOOL isPreserving )
1808 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1810 TRACE("%d\n", isPreserving);
1811 This->preserving = isPreserving;
1812 return S_OK;
1816 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1817 IXMLDOMDocument2 *iface,
1818 VARIANT readyStateChangeSink )
1820 FIXME("\n");
1821 return E_NOTIMPL;
1825 static HRESULT WINAPI domdoc_put_onDataAvailable(
1826 IXMLDOMDocument2 *iface,
1827 VARIANT onDataAvailableSink )
1829 FIXME("\n");
1830 return E_NOTIMPL;
1833 static HRESULT WINAPI domdoc_put_onTransformNode(
1834 IXMLDOMDocument2 *iface,
1835 VARIANT onTransformNodeSink )
1837 FIXME("\n");
1838 return E_NOTIMPL;
1841 static HRESULT WINAPI domdoc_get_namespaces(
1842 IXMLDOMDocument2* iface,
1843 IXMLDOMSchemaCollection** schemaCollection )
1845 FIXME("\n");
1846 return E_NOTIMPL;
1849 static HRESULT WINAPI domdoc_get_schemas(
1850 IXMLDOMDocument2* iface,
1851 VARIANT* var1 )
1853 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1854 HRESULT hr = S_FALSE;
1855 IXMLDOMSchemaCollection *cur_schema = This->schema;
1857 TRACE("(%p)->(%p)\n", This, var1);
1859 VariantInit(var1); /* Test shows we don't call VariantClear here */
1860 V_VT(var1) = VT_NULL;
1862 if(cur_schema)
1864 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1865 if(SUCCEEDED(hr))
1866 V_VT(var1) = VT_DISPATCH;
1868 return hr;
1871 static HRESULT WINAPI domdoc_putref_schemas(
1872 IXMLDOMDocument2* iface,
1873 VARIANT var1)
1875 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1876 HRESULT hr = E_FAIL;
1877 IXMLDOMSchemaCollection *new_schema = NULL;
1879 FIXME("(%p): semi-stub\n", This);
1880 switch(V_VT(&var1))
1882 case VT_UNKNOWN:
1883 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1884 break;
1886 case VT_DISPATCH:
1887 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1888 break;
1890 case VT_NULL:
1891 case VT_EMPTY:
1892 hr = S_OK;
1893 break;
1895 default:
1896 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1899 if(SUCCEEDED(hr))
1901 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1902 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1905 return hr;
1908 static HRESULT WINAPI domdoc_validate(
1909 IXMLDOMDocument2* iface,
1910 IXMLDOMParseError** err)
1912 FIXME("\n");
1913 return E_NOTIMPL;
1916 static HRESULT WINAPI domdoc_setProperty(
1917 IXMLDOMDocument2* iface,
1918 BSTR p,
1919 VARIANT var)
1921 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1923 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1925 VARIANT varStr;
1926 HRESULT hr;
1927 BSTR bstr;
1929 V_VT(&varStr) = VT_EMPTY;
1930 if (V_VT(&var) != VT_BSTR)
1932 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1933 return hr;
1934 bstr = V_BSTR(&varStr);
1936 else
1937 bstr = V_BSTR(&var);
1939 hr = S_OK;
1940 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1941 This->bUseXPath = TRUE;
1942 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1943 This->bUseXPath = FALSE;
1944 else
1945 hr = E_FAIL;
1947 VariantClear(&varStr);
1948 return hr;
1951 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1952 return E_FAIL;
1955 static HRESULT WINAPI domdoc_getProperty(
1956 IXMLDOMDocument2* iface,
1957 BSTR p,
1958 VARIANT* var)
1960 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1962 if (var == NULL)
1963 return E_INVALIDARG;
1964 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1966 V_VT(var) = VT_BSTR;
1967 if (This->bUseXPath)
1968 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1969 else
1970 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1971 return S_OK;
1974 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1975 return E_FAIL;
1978 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1980 domdoc_QueryInterface,
1981 domdoc_AddRef,
1982 domdoc_Release,
1983 domdoc_GetTypeInfoCount,
1984 domdoc_GetTypeInfo,
1985 domdoc_GetIDsOfNames,
1986 domdoc_Invoke,
1987 domdoc_get_nodeName,
1988 domdoc_get_nodeValue,
1989 domdoc_put_nodeValue,
1990 domdoc_get_nodeType,
1991 domdoc_get_parentNode,
1992 domdoc_get_childNodes,
1993 domdoc_get_firstChild,
1994 domdoc_get_lastChild,
1995 domdoc_get_previousSibling,
1996 domdoc_get_nextSibling,
1997 domdoc_get_attributes,
1998 domdoc_insertBefore,
1999 domdoc_replaceChild,
2000 domdoc_removeChild,
2001 domdoc_appendChild,
2002 domdoc_hasChildNodes,
2003 domdoc_get_ownerDocument,
2004 domdoc_cloneNode,
2005 domdoc_get_nodeTypeString,
2006 domdoc_get_text,
2007 domdoc_put_text,
2008 domdoc_get_specified,
2009 domdoc_get_definition,
2010 domdoc_get_nodeTypedValue,
2011 domdoc_put_nodeTypedValue,
2012 domdoc_get_dataType,
2013 domdoc_put_dataType,
2014 domdoc_get_xml,
2015 domdoc_transformNode,
2016 domdoc_selectNodes,
2017 domdoc_selectSingleNode,
2018 domdoc_get_parsed,
2019 domdoc_get_namespaceURI,
2020 domdoc_get_prefix,
2021 domdoc_get_baseName,
2022 domdoc_transformNodeToObject,
2023 domdoc_get_doctype,
2024 domdoc_get_implementation,
2025 domdoc_get_documentElement,
2026 domdoc_put_documentElement,
2027 domdoc_createElement,
2028 domdoc_createDocumentFragment,
2029 domdoc_createTextNode,
2030 domdoc_createComment,
2031 domdoc_createCDATASection,
2032 domdoc_createProcessingInstruction,
2033 domdoc_createAttribute,
2034 domdoc_createEntityReference,
2035 domdoc_getElementsByTagName,
2036 domdoc_createNode,
2037 domdoc_nodeFromID,
2038 domdoc_load,
2039 domdoc_get_readyState,
2040 domdoc_get_parseError,
2041 domdoc_get_url,
2042 domdoc_get_async,
2043 domdoc_put_async,
2044 domdoc_abort,
2045 domdoc_loadXML,
2046 domdoc_save,
2047 domdoc_get_validateOnParse,
2048 domdoc_put_validateOnParse,
2049 domdoc_get_resolveExternals,
2050 domdoc_put_resolveExternals,
2051 domdoc_get_preserveWhiteSpace,
2052 domdoc_put_preserveWhiteSpace,
2053 domdoc_put_onReadyStateChange,
2054 domdoc_put_onDataAvailable,
2055 domdoc_put_onTransformNode,
2056 domdoc_get_namespaces,
2057 domdoc_get_schemas,
2058 domdoc_putref_schemas,
2059 domdoc_validate,
2060 domdoc_setProperty,
2061 domdoc_getProperty
2064 /* xmldoc implementation of IObjectWithSite */
2065 static HRESULT WINAPI
2066 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2068 domdoc *This = impl_from_IObjectWithSite(iface);
2069 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2072 static ULONG WINAPI
2073 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2075 domdoc *This = impl_from_IObjectWithSite(iface);
2076 return IXMLDocument_AddRef((IXMLDocument *)This);
2079 static ULONG WINAPI
2080 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2082 domdoc *This = impl_from_IObjectWithSite(iface);
2083 return IXMLDocument_Release((IXMLDocument *)This);
2086 static HRESULT WINAPI
2087 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2089 domdoc *This = impl_from_IObjectWithSite(iface);
2091 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2093 if ( !This->site )
2094 return E_FAIL;
2096 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2099 static HRESULT WINAPI
2100 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2102 domdoc *This = impl_from_IObjectWithSite(iface);
2104 TRACE("%p %p\n", iface, punk);
2106 if(!punk)
2108 if(This->site)
2110 IUnknown_Release( This->site );
2111 This->site = NULL;
2114 return S_OK;
2117 if ( punk )
2118 IUnknown_AddRef( punk );
2120 if(This->site)
2121 IUnknown_Release( This->site );
2123 This->site = punk;
2125 return S_OK;
2128 static const IObjectWithSiteVtbl domdocObjectSite =
2130 xmldoc_ObjectWithSite_QueryInterface,
2131 xmldoc_ObjectWithSite_AddRef,
2132 xmldoc_ObjectWithSite_Release,
2133 xmldoc_SetSite,
2134 xmldoc_GetSite,
2137 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2139 domdoc *This = impl_from_IObjectSafety(iface);
2140 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2143 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2145 domdoc *This = impl_from_IObjectSafety(iface);
2146 return IXMLDocument_AddRef((IXMLDocument *)This);
2149 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2151 domdoc *This = impl_from_IObjectSafety(iface);
2152 return IXMLDocument_Release((IXMLDocument *)This);
2155 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2157 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2158 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2160 domdoc *This = impl_from_IObjectSafety(iface);
2162 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2164 if(!pdwSupportedOptions || !pdwEnabledOptions)
2165 return E_POINTER;
2167 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2168 *pdwEnabledOptions = This->safeopt;
2170 return S_OK;
2173 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2174 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2176 domdoc *This = impl_from_IObjectSafety(iface);
2178 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2180 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2181 return E_FAIL;
2183 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2184 return S_OK;
2187 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2188 xmldoc_Safety_QueryInterface,
2189 xmldoc_Safety_AddRef,
2190 xmldoc_Safety_Release,
2191 xmldoc_Safety_GetInterfaceSafetyOptions,
2192 xmldoc_Safety_SetInterfaceSafetyOptions
2196 static const tid_t domdoc_iface_tids[] = {
2197 IXMLDOMNode_tid,
2198 IXMLDOMDocument_tid,
2199 IXMLDOMDocument2_tid,
2202 static dispex_static_data_t domdoc_dispex = {
2203 NULL,
2204 IXMLDOMDocument2_tid,
2205 NULL,
2206 domdoc_iface_tids
2209 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2211 domdoc *doc;
2213 doc = heap_alloc( sizeof (*doc) );
2214 if( !doc )
2215 return E_OUTOFMEMORY;
2217 doc->lpVtbl = &domdoc_vtbl;
2218 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2219 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2220 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2221 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2222 doc->ref = 1;
2223 doc->async = VARIANT_TRUE;
2224 doc->validating = 0;
2225 doc->resolving = 0;
2226 doc->preserving = 0;
2227 doc->bUseXPath = FALSE;
2228 doc->error = S_OK;
2229 doc->schema = NULL;
2230 doc->stream = NULL;
2231 doc->site = NULL;
2232 doc->safeopt = 0;
2233 doc->bsc = NULL;
2235 init_xmlnode(&doc->node, (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2237 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2239 TRACE("returning iface %p\n", *document);
2240 return S_OK;
2243 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2245 xmlDocPtr xmldoc;
2246 HRESULT hr;
2248 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2250 xmldoc = xmlNewDoc(NULL);
2251 if(!xmldoc)
2252 return E_OUTOFMEMORY;
2254 xmldoc->_private = create_priv();
2256 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2257 if(FAILED(hr))
2258 xmlFreeDoc(xmldoc);
2260 return hr;
2263 IUnknown* create_domdoc( xmlNodePtr document )
2265 HRESULT hr;
2266 LPVOID pObj = NULL;
2268 TRACE("(%p)\n", document);
2270 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2271 if (FAILED(hr))
2272 return NULL;
2274 return pObj;
2277 #else
2279 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2281 MESSAGE("This program tried to use a DOMDocument object, but\n"
2282 "libxml2 support was not present at compile time.\n");
2283 return E_NOTIMPL;
2286 #endif