deferwindowpos commit
[wine/wine64.git] / dlls / msxml3 / domdoc.c
bloba24f16fa97e78e9a2f36ebcc4ae149970979b7b9
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 const struct IXMLDOMDocument2Vtbl *lpVtbl;
57 const struct IPersistStreamVtbl *lpvtblIPersistStream;
58 const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
59 const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
60 const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
61 LONG ref;
62 VARIANT_BOOL async;
63 VARIANT_BOOL validating;
64 VARIANT_BOOL resolving;
65 VARIANT_BOOL preserving;
66 BOOL bUseXPath;
67 IUnknown *node_unk;
68 IXMLDOMNode *node;
69 IXMLDOMSchemaCollection *schema;
70 bsc_t *bsc;
71 HRESULT error;
73 /* IPersistStream */
74 IStream *stream;
76 /* IObjectWithSite*/
77 IUnknown *site;
79 /* IObjectSafety */
80 DWORD safeopt;
82 /* IDispatchEx */
83 DispatchEx dispex;
84 } domdoc;
87 In native windows, the whole lifetime management of XMLDOMNodes is
88 managed automatically using reference counts. Wine emulates that by
89 maintaining a reference count to the document that is increased for
90 each IXMLDOMNode pointer passed out for this document. If all these
91 pointers are gone, the document is unreachable and gets freed, that
92 is, all nodes in the tree of the document get freed.
94 You are able to create nodes that are associated to a document (in
95 fact, in msxml's XMLDOM model, all nodes are associated to a document),
96 but not in the tree of that document, for example using the createFoo
97 functions from IXMLDOMDocument. These nodes do not get cleaned up
98 by libxml, so we have to do it ourselves.
100 To catch these nodes, a list of "orphan nodes" is introduced.
101 It contains pointers to all roots of node trees that are
102 associated with the document without being part of the document
103 tree. All nodes with parent==NULL (except for the document root nodes)
104 should be in the orphan node list of their document. All orphan nodes
105 get freed together with the document itself.
108 typedef struct _xmldoc_priv {
109 LONG refs;
110 struct list orphans;
111 } xmldoc_priv;
113 typedef struct _orphan_entry {
114 struct list entry;
115 xmlNode * node;
116 } orphan_entry;
118 static inline xmldoc_priv * priv_from_xmlDocPtr(xmlDocPtr doc)
120 return doc->_private;
123 static xmldoc_priv * create_priv(void)
125 xmldoc_priv *priv;
126 priv = HeapAlloc( GetProcessHeap(), 0, sizeof (*priv) );
128 if(priv)
130 priv->refs = 0;
131 list_init( &priv->orphans );
134 return priv;
137 static xmlDocPtr doparse( char *ptr, int len )
139 #ifdef HAVE_XMLREADMEMORY
141 * use xmlReadMemory if possible so we can suppress
142 * writing errors to stderr
144 return xmlReadMemory( ptr, len, NULL, NULL,
145 XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
146 #else
147 return xmlParseMemory( ptr, len );
148 #endif
151 LONG xmldoc_add_ref(xmlDocPtr doc)
153 LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
154 TRACE("%d\n", ref);
155 return ref;
158 LONG xmldoc_release(xmlDocPtr doc)
160 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
161 LONG ref = InterlockedDecrement(&priv->refs);
162 TRACE("%d\n", ref);
163 if(ref == 0)
165 orphan_entry *orphan, *orphan2;
166 TRACE("freeing docptr %p\n", doc);
168 LIST_FOR_EACH_ENTRY_SAFE( orphan, orphan2, &priv->orphans, orphan_entry, entry )
170 xmlFreeNode( orphan->node );
171 HeapFree( GetProcessHeap(), 0, orphan );
173 HeapFree(GetProcessHeap(), 0, doc->_private);
175 xmlFreeDoc(doc);
178 return ref;
181 HRESULT xmldoc_add_orphan(xmlDocPtr doc, xmlNodePtr node)
183 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
184 orphan_entry *entry;
186 entry = HeapAlloc( GetProcessHeap(), 0, sizeof (*entry) );
187 if(!entry)
188 return E_OUTOFMEMORY;
190 entry->node = node;
191 list_add_head( &priv->orphans, &entry->entry );
192 return S_OK;
195 HRESULT xmldoc_remove_orphan(xmlDocPtr doc, xmlNodePtr node)
197 xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
198 orphan_entry *entry, *entry2;
200 LIST_FOR_EACH_ENTRY_SAFE( entry, entry2, &priv->orphans, orphan_entry, entry )
202 if( entry->node == node )
204 list_remove( &entry->entry );
205 HeapFree( GetProcessHeap(), 0, entry );
206 return S_OK;
210 return S_FALSE;
213 static HRESULT attach_xmldoc( IXMLDOMNode *node, xmlDocPtr xml )
215 xmlnode *This = impl_from_IXMLDOMNode( node );
217 if(This->node)
218 xmldoc_release(This->node->doc);
220 This->node = (xmlNodePtr) xml;
221 if(This->node)
222 xmldoc_add_ref(This->node->doc);
224 return S_OK;
227 static inline domdoc *impl_from_IXMLDOMDocument2( IXMLDOMDocument2 *iface )
229 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpVtbl));
232 static inline xmlDocPtr get_doc( domdoc *This )
234 return (xmlDocPtr) xmlNodePtr_from_domnode( This->node, XML_DOCUMENT_NODE );
237 static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
239 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
242 static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
244 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectWithSite));
247 static inline domdoc *impl_from_IObjectSafety(IObjectSafety *iface)
249 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIObjectSafety));
252 static inline domdoc *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
254 return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblISupportErrorInfo));
257 /************************************************************************
258 * xmldoc implementation of IPersistStream.
260 static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
261 IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
263 domdoc *this = impl_from_IPersistStream(iface);
264 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
267 static ULONG WINAPI xmldoc_IPersistStream_AddRef(
268 IPersistStream *iface)
270 domdoc *this = impl_from_IPersistStream(iface);
271 return IXMLDocument_AddRef((IXMLDocument *)this);
274 static ULONG WINAPI xmldoc_IPersistStream_Release(
275 IPersistStream *iface)
277 domdoc *this = impl_from_IPersistStream(iface);
278 return IXMLDocument_Release((IXMLDocument *)this);
281 static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
282 IPersistStream *iface, CLSID *classid)
284 TRACE("(%p,%p): stub!\n", iface, classid);
286 if(!classid)
287 return E_POINTER;
289 *classid = CLSID_DOMDocument2;
291 return S_OK;
294 static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
295 IPersistStream *iface)
297 domdoc *This = impl_from_IPersistStream(iface);
299 FIXME("(%p->%p): stub!\n", iface, This);
301 return S_FALSE;
304 static HRESULT WINAPI xmldoc_IPersistStream_Load(
305 IPersistStream *iface, LPSTREAM pStm)
307 domdoc *This = impl_from_IPersistStream(iface);
308 HRESULT hr;
309 HGLOBAL hglobal;
310 DWORD read, written, len;
311 BYTE buf[4096];
312 char *ptr;
313 xmlDocPtr xmldoc = NULL;
315 TRACE("(%p, %p)\n", iface, pStm);
317 if (!pStm)
318 return E_INVALIDARG;
320 hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
321 if (FAILED(hr))
322 return hr;
326 IStream_Read(pStm, buf, sizeof(buf), &read);
327 hr = IStream_Write(This->stream, buf, read, &written);
328 } while(SUCCEEDED(hr) && written != 0 && read != 0);
330 if (FAILED(hr))
332 ERR("Failed to copy stream\n");
333 return hr;
336 hr = GetHGlobalFromStream(This->stream, &hglobal);
337 if (FAILED(hr))
338 return hr;
340 len = GlobalSize(hglobal);
341 ptr = GlobalLock(hglobal);
342 if (len != 0)
343 xmldoc = parse_xml(ptr, len);
344 GlobalUnlock(hglobal);
346 if (!xmldoc)
348 ERR("Failed to parse xml\n");
349 return E_FAIL;
352 xmldoc->_private = create_priv();
354 return attach_xmldoc( This->node, xmldoc );
357 static HRESULT WINAPI xmldoc_IPersistStream_Save(
358 IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
360 FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);
361 return E_NOTIMPL;
364 static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
365 IPersistStream *iface, ULARGE_INTEGER *pcbSize)
367 TRACE("(%p, %p): stub!\n", iface, pcbSize);
368 return E_NOTIMPL;
371 static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
373 xmldoc_IPersistStream_QueryInterface,
374 xmldoc_IPersistStream_AddRef,
375 xmldoc_IPersistStream_Release,
376 xmldoc_IPersistStream_GetClassID,
377 xmldoc_IPersistStream_IsDirty,
378 xmldoc_IPersistStream_Load,
379 xmldoc_IPersistStream_Save,
380 xmldoc_IPersistStream_GetSizeMax,
383 /* ISupportErrorInfo interface */
384 static HRESULT WINAPI support_error_QueryInterface(
385 ISupportErrorInfo *iface,
386 REFIID riid, void** ppvObj )
388 domdoc *This = impl_from_ISupportErrorInfo(iface);
389 return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
392 static ULONG WINAPI support_error_AddRef(
393 ISupportErrorInfo *iface )
395 domdoc *This = impl_from_ISupportErrorInfo(iface);
396 return IXMLDocument_AddRef((IXMLDocument *)This);
399 static ULONG WINAPI support_error_Release(
400 ISupportErrorInfo *iface )
402 domdoc *This = impl_from_ISupportErrorInfo(iface);
403 return IXMLDocument_Release((IXMLDocument *)This);
406 static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
407 ISupportErrorInfo *iface,
408 REFIID riid )
410 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
411 return S_FALSE;
414 static const struct ISupportErrorInfoVtbl support_error_vtbl =
416 support_error_QueryInterface,
417 support_error_AddRef,
418 support_error_Release,
419 support_error_InterfaceSupportsErrorInfo
422 /* IXMLDOMDocument2 interface */
423 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
425 domdoc *This = impl_from_IXMLDOMDocument2( iface );
427 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
429 *ppvObject = NULL;
431 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
432 IsEqualGUID( riid, &IID_IDispatch ) ||
433 IsEqualGUID( riid, &IID_IXMLDOMDocument ) ||
434 IsEqualGUID( riid, &IID_IXMLDOMDocument2 ) )
436 *ppvObject = iface;
438 else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
440 return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
442 else if (IsEqualGUID(&IID_IPersistStream, riid))
444 *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
446 else if (IsEqualGUID(&IID_IObjectWithSite, riid))
448 *ppvObject = (IObjectWithSite*)&(This->lpvtblIObjectWithSite);
450 else if( IsEqualGUID( riid, &IID_ISupportErrorInfo ))
452 *ppvObject = &This->lpvtblISupportErrorInfo;
454 else if(dispex_query_interface(&This->dispex, riid, ppvObject))
456 return *ppvObject ? S_OK : E_NOINTERFACE;
458 else if(IsEqualGUID(&IID_IRunnableObject, riid))
460 TRACE("IID_IRunnableObject not supported returning NULL\n");
461 return E_NOINTERFACE;
463 else
465 FIXME("interface %s not implemented\n", debugstr_guid(riid));
466 return E_NOINTERFACE;
469 IXMLDOMDocument_AddRef( iface );
471 return S_OK;
475 static ULONG WINAPI domdoc_AddRef(
476 IXMLDOMDocument2 *iface )
478 domdoc *This = impl_from_IXMLDOMDocument2( iface );
479 TRACE("%p\n", This );
480 return InterlockedIncrement( &This->ref );
484 static ULONG WINAPI domdoc_Release(
485 IXMLDOMDocument2 *iface )
487 domdoc *This = impl_from_IXMLDOMDocument2( iface );
488 LONG ref;
490 TRACE("%p\n", This );
492 ref = InterlockedDecrement( &This->ref );
493 if ( ref == 0 )
495 if(This->bsc)
496 detach_bsc(This->bsc);
498 if (This->site)
499 IUnknown_Release( This->site );
500 IUnknown_Release( This->node_unk );
501 if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
502 if (This->stream) IStream_Release(This->stream);
503 HeapFree( GetProcessHeap(), 0, This );
506 return ref;
509 static HRESULT WINAPI domdoc_GetTypeInfoCount( IXMLDOMDocument2 *iface, UINT* pctinfo )
511 domdoc *This = impl_from_IXMLDOMDocument2( iface );
513 TRACE("(%p)->(%p)\n", This, pctinfo);
515 *pctinfo = 1;
517 return S_OK;
520 static HRESULT WINAPI domdoc_GetTypeInfo(
521 IXMLDOMDocument2 *iface,
522 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
524 domdoc *This = impl_from_IXMLDOMDocument2( iface );
525 HRESULT hr;
527 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
529 hr = get_typeinfo(IXMLDOMDocument2_tid, ppTInfo);
531 return hr;
534 static HRESULT WINAPI domdoc_GetIDsOfNames(
535 IXMLDOMDocument2 *iface,
536 REFIID riid,
537 LPOLESTR* rgszNames,
538 UINT cNames,
539 LCID lcid,
540 DISPID* rgDispId)
542 domdoc *This = impl_from_IXMLDOMDocument2( iface );
543 ITypeInfo *typeinfo;
544 HRESULT hr;
546 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
547 lcid, rgDispId);
549 if(!rgszNames || cNames == 0 || !rgDispId)
550 return E_INVALIDARG;
552 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
553 if(SUCCEEDED(hr))
555 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
556 ITypeInfo_Release(typeinfo);
559 return hr;
563 static HRESULT WINAPI domdoc_Invoke(
564 IXMLDOMDocument2 *iface,
565 DISPID dispIdMember,
566 REFIID riid,
567 LCID lcid,
568 WORD wFlags,
569 DISPPARAMS* pDispParams,
570 VARIANT* pVarResult,
571 EXCEPINFO* pExcepInfo,
572 UINT* puArgErr)
574 domdoc *This = impl_from_IXMLDOMDocument2( iface );
575 ITypeInfo *typeinfo;
576 HRESULT hr;
578 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
579 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
581 hr = get_typeinfo(IXMLDOMDocument2_tid, &typeinfo);
582 if(SUCCEEDED(hr))
584 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
585 pVarResult, pExcepInfo, puArgErr);
586 ITypeInfo_Release(typeinfo);
589 return hr;
593 static HRESULT WINAPI domdoc_get_nodeName(
594 IXMLDOMDocument2 *iface,
595 BSTR* name )
597 domdoc *This = impl_from_IXMLDOMDocument2( iface );
598 return IXMLDOMNode_get_nodeName( This->node, name );
602 static HRESULT WINAPI domdoc_get_nodeValue(
603 IXMLDOMDocument2 *iface,
604 VARIANT* value )
606 domdoc *This = impl_from_IXMLDOMDocument2( iface );
607 return IXMLDOMNode_get_nodeValue( This->node, value );
611 static HRESULT WINAPI domdoc_put_nodeValue(
612 IXMLDOMDocument2 *iface,
613 VARIANT value)
615 domdoc *This = impl_from_IXMLDOMDocument2( iface );
616 return IXMLDOMNode_put_nodeValue( This->node, value );
620 static HRESULT WINAPI domdoc_get_nodeType(
621 IXMLDOMDocument2 *iface,
622 DOMNodeType* type )
624 domdoc *This = impl_from_IXMLDOMDocument2( iface );
625 return IXMLDOMNode_get_nodeType( This->node, type );
629 static HRESULT WINAPI domdoc_get_parentNode(
630 IXMLDOMDocument2 *iface,
631 IXMLDOMNode** parent )
633 domdoc *This = impl_from_IXMLDOMDocument2( iface );
634 return IXMLDOMNode_get_parentNode( This->node, parent );
638 static HRESULT WINAPI domdoc_get_childNodes(
639 IXMLDOMDocument2 *iface,
640 IXMLDOMNodeList** childList )
642 domdoc *This = impl_from_IXMLDOMDocument2( iface );
643 return IXMLDOMNode_get_childNodes( This->node, childList );
647 static HRESULT WINAPI domdoc_get_firstChild(
648 IXMLDOMDocument2 *iface,
649 IXMLDOMNode** firstChild )
651 domdoc *This = impl_from_IXMLDOMDocument2( iface );
652 return IXMLDOMNode_get_firstChild( This->node, firstChild );
656 static HRESULT WINAPI domdoc_get_lastChild(
657 IXMLDOMDocument2 *iface,
658 IXMLDOMNode** lastChild )
660 domdoc *This = impl_from_IXMLDOMDocument2( iface );
661 return IXMLDOMNode_get_lastChild( This->node, lastChild );
665 static HRESULT WINAPI domdoc_get_previousSibling(
666 IXMLDOMDocument2 *iface,
667 IXMLDOMNode** previousSibling )
669 domdoc *This = impl_from_IXMLDOMDocument2( iface );
670 return IXMLDOMNode_get_previousSibling( This->node, previousSibling );
674 static HRESULT WINAPI domdoc_get_nextSibling(
675 IXMLDOMDocument2 *iface,
676 IXMLDOMNode** nextSibling )
678 domdoc *This = impl_from_IXMLDOMDocument2( iface );
679 return IXMLDOMNode_get_nextSibling( This->node, nextSibling );
683 static HRESULT WINAPI domdoc_get_attributes(
684 IXMLDOMDocument2 *iface,
685 IXMLDOMNamedNodeMap** attributeMap )
687 domdoc *This = impl_from_IXMLDOMDocument2( iface );
688 return IXMLDOMNode_get_attributes( This->node, attributeMap );
692 static HRESULT WINAPI domdoc_insertBefore(
693 IXMLDOMDocument2 *iface,
694 IXMLDOMNode* newChild,
695 VARIANT refChild,
696 IXMLDOMNode** outNewChild )
698 domdoc *This = impl_from_IXMLDOMDocument2( iface );
699 return IXMLDOMNode_insertBefore( This->node, newChild, refChild, outNewChild );
703 static HRESULT WINAPI domdoc_replaceChild(
704 IXMLDOMDocument2 *iface,
705 IXMLDOMNode* newChild,
706 IXMLDOMNode* oldChild,
707 IXMLDOMNode** outOldChild)
709 domdoc *This = impl_from_IXMLDOMDocument2( iface );
710 return IXMLDOMNode_replaceChild( This->node, newChild, oldChild, outOldChild );
714 static HRESULT WINAPI domdoc_removeChild(
715 IXMLDOMDocument2 *iface,
716 IXMLDOMNode* childNode,
717 IXMLDOMNode** oldChild)
719 domdoc *This = impl_from_IXMLDOMDocument2( iface );
720 return IXMLDOMNode_removeChild( This->node, childNode, oldChild );
724 static HRESULT WINAPI domdoc_appendChild(
725 IXMLDOMDocument2 *iface,
726 IXMLDOMNode* newChild,
727 IXMLDOMNode** outNewChild)
729 domdoc *This = impl_from_IXMLDOMDocument2( iface );
730 return IXMLDOMNode_appendChild( This->node, newChild, outNewChild );
734 static HRESULT WINAPI domdoc_hasChildNodes(
735 IXMLDOMDocument2 *iface,
736 VARIANT_BOOL* hasChild)
738 domdoc *This = impl_from_IXMLDOMDocument2( iface );
739 return IXMLDOMNode_hasChildNodes( This->node, hasChild );
743 static HRESULT WINAPI domdoc_get_ownerDocument(
744 IXMLDOMDocument2 *iface,
745 IXMLDOMDocument** DOMDocument)
747 domdoc *This = impl_from_IXMLDOMDocument2( iface );
748 return IXMLDOMNode_get_ownerDocument( This->node, DOMDocument );
752 static HRESULT WINAPI domdoc_cloneNode(
753 IXMLDOMDocument2 *iface,
754 VARIANT_BOOL deep,
755 IXMLDOMNode** cloneRoot)
757 domdoc *This = impl_from_IXMLDOMDocument2( iface );
758 return IXMLDOMNode_cloneNode( This->node, deep, cloneRoot );
762 static HRESULT WINAPI domdoc_get_nodeTypeString(
763 IXMLDOMDocument2 *iface,
764 BSTR* nodeType )
766 domdoc *This = impl_from_IXMLDOMDocument2( iface );
767 return IXMLDOMNode_get_nodeTypeString( This->node, nodeType );
771 static HRESULT WINAPI domdoc_get_text(
772 IXMLDOMDocument2 *iface,
773 BSTR* text )
775 domdoc *This = impl_from_IXMLDOMDocument2( iface );
776 return IXMLDOMNode_get_text( This->node, text );
780 static HRESULT WINAPI domdoc_put_text(
781 IXMLDOMDocument2 *iface,
782 BSTR text )
784 domdoc *This = impl_from_IXMLDOMDocument2( iface );
785 return IXMLDOMNode_put_text( This->node, text );
789 static HRESULT WINAPI domdoc_get_specified(
790 IXMLDOMDocument2 *iface,
791 VARIANT_BOOL* isSpecified )
793 domdoc *This = impl_from_IXMLDOMDocument2( iface );
794 return IXMLDOMNode_get_specified( This->node, isSpecified );
798 static HRESULT WINAPI domdoc_get_definition(
799 IXMLDOMDocument2 *iface,
800 IXMLDOMNode** definitionNode )
802 domdoc *This = impl_from_IXMLDOMDocument2( iface );
803 return IXMLDOMNode_get_definition( This->node, definitionNode );
807 static HRESULT WINAPI domdoc_get_nodeTypedValue(
808 IXMLDOMDocument2 *iface,
809 VARIANT* typedValue )
811 domdoc *This = impl_from_IXMLDOMDocument2( iface );
812 return IXMLDOMNode_get_nodeTypedValue( This->node, typedValue );
815 static HRESULT WINAPI domdoc_put_nodeTypedValue(
816 IXMLDOMDocument2 *iface,
817 VARIANT typedValue )
819 domdoc *This = impl_from_IXMLDOMDocument2( iface );
820 return IXMLDOMNode_put_nodeTypedValue( This->node, typedValue );
824 static HRESULT WINAPI domdoc_get_dataType(
825 IXMLDOMDocument2 *iface,
826 VARIANT* dataTypeName )
828 domdoc *This = impl_from_IXMLDOMDocument2( iface );
829 return IXMLDOMNode_get_dataType( This->node, dataTypeName );
833 static HRESULT WINAPI domdoc_put_dataType(
834 IXMLDOMDocument2 *iface,
835 BSTR dataTypeName )
837 domdoc *This = impl_from_IXMLDOMDocument2( iface );
838 return IXMLDOMNode_put_dataType( This->node, dataTypeName );
842 static HRESULT WINAPI domdoc_get_xml(
843 IXMLDOMDocument2 *iface,
844 BSTR* xmlString )
846 domdoc *This = impl_from_IXMLDOMDocument2( iface );
847 return IXMLDOMNode_get_xml( This->node, xmlString );
851 static HRESULT WINAPI domdoc_transformNode(
852 IXMLDOMDocument2 *iface,
853 IXMLDOMNode* styleSheet,
854 BSTR* xmlString )
856 domdoc *This = impl_from_IXMLDOMDocument2( iface );
857 return IXMLDOMNode_transformNode( This->node, styleSheet, xmlString );
861 static HRESULT WINAPI domdoc_selectNodes(
862 IXMLDOMDocument2 *iface,
863 BSTR queryString,
864 IXMLDOMNodeList** resultList )
866 domdoc *This = impl_from_IXMLDOMDocument2( iface );
867 return IXMLDOMNode_selectNodes( This->node, queryString, resultList );
871 static HRESULT WINAPI domdoc_selectSingleNode(
872 IXMLDOMDocument2 *iface,
873 BSTR queryString,
874 IXMLDOMNode** resultNode )
876 domdoc *This = impl_from_IXMLDOMDocument2( iface );
877 return IXMLDOMNode_selectSingleNode( This->node, queryString, resultNode );
881 static HRESULT WINAPI domdoc_get_parsed(
882 IXMLDOMDocument2 *iface,
883 VARIANT_BOOL* isParsed )
885 domdoc *This = impl_from_IXMLDOMDocument2( iface );
886 return IXMLDOMNode_get_parsed( This->node, isParsed );
890 static HRESULT WINAPI domdoc_get_namespaceURI(
891 IXMLDOMDocument2 *iface,
892 BSTR* namespaceURI )
894 domdoc *This = impl_from_IXMLDOMDocument2( iface );
895 return IXMLDOMNode_get_namespaceURI( This->node, namespaceURI );
899 static HRESULT WINAPI domdoc_get_prefix(
900 IXMLDOMDocument2 *iface,
901 BSTR* prefixString )
903 domdoc *This = impl_from_IXMLDOMDocument2( iface );
904 return IXMLDOMNode_get_prefix( This->node, prefixString );
908 static HRESULT WINAPI domdoc_get_baseName(
909 IXMLDOMDocument2 *iface,
910 BSTR* nameString )
912 domdoc *This = impl_from_IXMLDOMDocument2( iface );
913 return IXMLDOMNode_get_baseName( This->node, nameString );
917 static HRESULT WINAPI domdoc_transformNodeToObject(
918 IXMLDOMDocument2 *iface,
919 IXMLDOMNode* stylesheet,
920 VARIANT outputObject)
922 domdoc *This = impl_from_IXMLDOMDocument2( iface );
923 return IXMLDOMNode_transformNodeToObject( This->node, stylesheet, outputObject );
927 static HRESULT WINAPI domdoc_get_doctype(
928 IXMLDOMDocument2 *iface,
929 IXMLDOMDocumentType** documentType )
931 FIXME("\n");
932 return E_NOTIMPL;
936 static HRESULT WINAPI domdoc_get_implementation(
937 IXMLDOMDocument2 *iface,
938 IXMLDOMImplementation** impl )
940 if(!impl)
941 return E_INVALIDARG;
943 *impl = (IXMLDOMImplementation*)create_doc_Implementation();
945 return S_OK;
948 static HRESULT WINAPI domdoc_get_documentElement(
949 IXMLDOMDocument2 *iface,
950 IXMLDOMElement** DOMElement )
952 domdoc *This = impl_from_IXMLDOMDocument2( iface );
953 xmlDocPtr xmldoc = NULL;
954 xmlNodePtr root = NULL;
955 IXMLDOMNode *element_node;
956 HRESULT hr;
958 TRACE("%p %p\n", This, This->node);
960 if(!DOMElement)
961 return E_INVALIDARG;
963 *DOMElement = NULL;
965 xmldoc = get_doc( This );
967 root = xmlDocGetRootElement( xmldoc );
968 if ( !root )
969 return S_FALSE;
971 element_node = create_node( root );
972 if(!element_node) return S_FALSE;
974 hr = IXMLDOMNode_QueryInterface(element_node, &IID_IXMLDOMElement, (LPVOID*)DOMElement);
975 IXMLDOMNode_Release(element_node);
977 return hr;
981 static HRESULT WINAPI domdoc_put_documentElement(
982 IXMLDOMDocument2 *iface,
983 IXMLDOMElement* DOMElement )
985 domdoc *This = impl_from_IXMLDOMDocument2( iface );
986 IXMLDOMNode *elementNode;
987 xmlNodePtr oldRoot;
988 xmlnode *xmlNode;
989 HRESULT hr;
991 TRACE("(%p)->(%p)\n", This, DOMElement);
993 hr = IXMLDOMElement_QueryInterface( DOMElement, &IID_IXMLDOMNode, (void**)&elementNode );
994 if(FAILED(hr))
995 return hr;
997 xmlNode = impl_from_IXMLDOMNode( elementNode );
999 if(!xmlNode->node->parent)
1000 if(xmldoc_remove_orphan(xmlNode->node->doc, xmlNode->node) != S_OK)
1001 WARN("%p is not an orphan of %p\n", xmlNode->node->doc, xmlNode->node);
1003 oldRoot = xmlDocSetRootElement( get_doc(This), xmlNode->node);
1004 IXMLDOMNode_Release( elementNode );
1006 if(oldRoot)
1007 xmldoc_add_orphan(oldRoot->doc, oldRoot);
1009 return S_OK;
1013 static HRESULT WINAPI domdoc_createElement(
1014 IXMLDOMDocument2 *iface,
1015 BSTR tagname,
1016 IXMLDOMElement** element )
1018 xmlNodePtr xmlnode;
1019 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1020 xmlChar *xml_name;
1021 IUnknown *elem_unk;
1022 HRESULT hr;
1024 TRACE("%p->(%s,%p)\n", iface, debugstr_w(tagname), element);
1026 xml_name = xmlChar_from_wchar((WCHAR*)tagname);
1027 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1028 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1030 TRACE("created xmlptr %p\n", xmlnode);
1031 elem_unk = create_element(xmlnode, NULL);
1032 HeapFree(GetProcessHeap(), 0, xml_name);
1034 hr = IUnknown_QueryInterface(elem_unk, &IID_IXMLDOMElement, (void **)element);
1035 IUnknown_Release(elem_unk);
1036 TRACE("returning %p\n", *element);
1037 return hr;
1041 static HRESULT WINAPI domdoc_createDocumentFragment(
1042 IXMLDOMDocument2 *iface,
1043 IXMLDOMDocumentFragment** docFrag )
1045 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1046 xmlNodePtr xmlnode;
1048 TRACE("%p\n", iface);
1050 if(!docFrag)
1051 return E_INVALIDARG;
1053 *docFrag = NULL;
1055 xmlnode = xmlNewDocFragment(get_doc( This ) );
1057 if(!xmlnode)
1058 return E_FAIL;
1060 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1061 *docFrag = (IXMLDOMDocumentFragment*)create_doc_fragment(xmlnode);
1063 return S_OK;
1067 static HRESULT WINAPI domdoc_createTextNode(
1068 IXMLDOMDocument2 *iface,
1069 BSTR data,
1070 IXMLDOMText** text )
1072 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1073 xmlNodePtr xmlnode;
1074 xmlChar *xml_content;
1076 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), text);
1078 if(!text)
1079 return E_INVALIDARG;
1081 *text = NULL;
1083 xml_content = xmlChar_from_wchar((WCHAR*)data);
1084 xmlnode = xmlNewText(xml_content);
1085 HeapFree(GetProcessHeap(), 0, xml_content);
1087 if(!xmlnode)
1088 return E_FAIL;
1090 xmlnode->doc = get_doc( This );
1091 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1093 *text = (IXMLDOMText*)create_text(xmlnode);
1095 return S_OK;
1099 static HRESULT WINAPI domdoc_createComment(
1100 IXMLDOMDocument2 *iface,
1101 BSTR data,
1102 IXMLDOMComment** comment )
1104 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1105 xmlNodePtr xmlnode;
1106 xmlChar *xml_content;
1108 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), comment);
1110 if(!comment)
1111 return E_INVALIDARG;
1113 *comment = NULL;
1115 xml_content = xmlChar_from_wchar((WCHAR*)data);
1116 xmlnode = xmlNewComment(xml_content);
1117 HeapFree(GetProcessHeap(), 0, xml_content);
1119 if(!xmlnode)
1120 return E_FAIL;
1122 xmlnode->doc = get_doc( This );
1123 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1125 *comment = (IXMLDOMComment*)create_comment(xmlnode);
1127 return S_OK;
1131 static HRESULT WINAPI domdoc_createCDATASection(
1132 IXMLDOMDocument2 *iface,
1133 BSTR data,
1134 IXMLDOMCDATASection** cdata )
1136 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1137 xmlNodePtr xmlnode;
1138 xmlChar *xml_content;
1140 TRACE("%p->(%s %p)\n", iface, debugstr_w(data), cdata);
1142 if(!cdata)
1143 return E_INVALIDARG;
1145 *cdata = NULL;
1147 xml_content = xmlChar_from_wchar((WCHAR*)data);
1148 xmlnode = xmlNewCDataBlock(get_doc( This ), xml_content, strlen( (char*)xml_content) );
1149 HeapFree(GetProcessHeap(), 0, xml_content);
1151 if(!xmlnode)
1152 return E_FAIL;
1154 xmlnode->doc = get_doc( This );
1155 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1157 *cdata = (IXMLDOMCDATASection*)create_cdata(xmlnode);
1159 return S_OK;
1163 static HRESULT WINAPI domdoc_createProcessingInstruction(
1164 IXMLDOMDocument2 *iface,
1165 BSTR target,
1166 BSTR data,
1167 IXMLDOMProcessingInstruction** pi )
1169 #ifdef HAVE_XMLNEWDOCPI
1170 xmlNodePtr xmlnode;
1171 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1172 xmlChar *xml_target, *xml_content;
1174 TRACE("%p->(%s %s %p)\n", iface, debugstr_w(target), debugstr_w(data), pi);
1176 if(!pi)
1177 return E_INVALIDARG;
1179 if(!target || lstrlenW(target) == 0)
1180 return E_FAIL;
1182 xml_target = xmlChar_from_wchar((WCHAR*)target);
1183 xml_content = xmlChar_from_wchar((WCHAR*)data);
1185 xmlnode = xmlNewDocPI(get_doc(This), xml_target, xml_content);
1186 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1187 TRACE("created xmlptr %p\n", xmlnode);
1188 *pi = (IXMLDOMProcessingInstruction*)create_pi(xmlnode);
1190 HeapFree(GetProcessHeap(), 0, xml_content);
1191 HeapFree(GetProcessHeap(), 0, xml_target);
1193 return S_OK;
1194 #else
1195 FIXME("Libxml 2.6.15 or greater required.\n");
1196 return E_NOTIMPL;
1197 #endif
1201 static HRESULT WINAPI domdoc_createAttribute(
1202 IXMLDOMDocument2 *iface,
1203 BSTR name,
1204 IXMLDOMAttribute** attribute )
1206 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1207 xmlNodePtr xmlnode;
1208 xmlChar *xml_name;
1210 TRACE("%p->(%s %p)\n", iface, debugstr_w(name), attribute);
1212 if(!attribute)
1213 return E_INVALIDARG;
1215 *attribute = NULL;
1217 xml_name = xmlChar_from_wchar((WCHAR*)name);
1218 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1219 HeapFree(GetProcessHeap(), 0, xml_name);
1221 if(!xmlnode)
1222 return E_FAIL;
1224 xmlnode->doc = get_doc( This );
1225 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1227 *attribute = (IXMLDOMAttribute*)create_attribute(xmlnode);
1229 return S_OK;
1233 static HRESULT WINAPI domdoc_createEntityReference(
1234 IXMLDOMDocument2 *iface,
1235 BSTR name,
1236 IXMLDOMEntityReference** entityRef )
1238 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1239 xmlNodePtr xmlnode;
1240 xmlChar *xml_name;
1242 TRACE("%p\n", iface);
1244 if(!entityRef)
1245 return E_INVALIDARG;
1247 *entityRef = NULL;
1249 xml_name = xmlChar_from_wchar((WCHAR*)name);
1250 xmlnode = xmlNewReference(get_doc( This ), xml_name );
1251 HeapFree(GetProcessHeap(), 0, xml_name);
1253 if(!xmlnode)
1254 return E_FAIL;
1256 xmlnode->doc = get_doc( This );
1257 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1259 *entityRef = (IXMLDOMEntityReference*)create_doc_entity_ref(xmlnode);
1261 return S_OK;
1265 static HRESULT WINAPI domdoc_getElementsByTagName(
1266 IXMLDOMDocument2 *iface,
1267 BSTR tagName,
1268 IXMLDOMNodeList** resultList )
1270 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1271 LPWSTR szPattern;
1272 HRESULT hr;
1273 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(tagName), resultList);
1275 szPattern = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(2+lstrlenW(tagName)+1));
1276 szPattern[0] = szPattern[1] = '/';
1277 lstrcpyW(szPattern + 2, tagName);
1279 hr = queryresult_create((xmlNodePtr)get_doc(This), szPattern, resultList);
1280 HeapFree(GetProcessHeap(), 0, szPattern);
1282 return hr;
1285 static HRESULT get_node_type(VARIANT Type, DOMNodeType * type)
1287 VARIANT tmp;
1288 HRESULT hr;
1290 VariantInit(&tmp);
1291 hr = VariantChangeType(&tmp, &Type, 0, VT_I4);
1292 if(FAILED(hr))
1293 return E_INVALIDARG;
1295 *type = V_I4(&tmp);
1297 return S_OK;
1300 static HRESULT WINAPI domdoc_createNode(
1301 IXMLDOMDocument2 *iface,
1302 VARIANT Type,
1303 BSTR name,
1304 BSTR namespaceURI,
1305 IXMLDOMNode** node )
1307 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1308 DOMNodeType node_type;
1309 xmlNodePtr xmlnode = NULL;
1310 xmlChar *xml_name;
1311 HRESULT hr;
1313 TRACE("(%p)->(type,%s,%s,%p)\n", This, debugstr_w(name), debugstr_w(namespaceURI), node);
1315 hr = get_node_type(Type, &node_type);
1316 if(FAILED(hr))
1317 return hr;
1319 TRACE("node_type %d\n", node_type);
1321 xml_name = xmlChar_from_wchar((WCHAR*)name);
1323 switch(node_type)
1325 case NODE_ELEMENT:
1326 xmlnode = xmlNewDocNode(get_doc(This), NULL, xml_name, NULL);
1327 *node = create_node(xmlnode);
1328 TRACE("created %p\n", xmlnode);
1329 break;
1330 case NODE_ATTRIBUTE:
1331 xmlnode = (xmlNode *)xmlNewProp(NULL, xml_name, NULL);
1332 if(xmlnode)
1334 xmlnode->doc = get_doc( This );
1336 *node = (IXMLDOMNode*)create_attribute(xmlnode);
1339 TRACE("created %p\n", xmlnode);
1340 break;
1342 default:
1343 FIXME("unhandled node type %d\n", node_type);
1344 break;
1347 HeapFree(GetProcessHeap(), 0, xml_name);
1349 if(xmlnode && *node)
1351 xmldoc_add_orphan(xmlnode->doc, xmlnode);
1352 return S_OK;
1355 return E_FAIL;
1358 static HRESULT WINAPI domdoc_nodeFromID(
1359 IXMLDOMDocument2 *iface,
1360 BSTR idString,
1361 IXMLDOMNode** node )
1363 FIXME("\n");
1364 return E_NOTIMPL;
1367 static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
1369 domdoc *This = obj;
1370 xmlDocPtr xmldoc;
1372 xmldoc = doparse( ptr, len );
1373 if(xmldoc) {
1374 xmldoc->_private = create_priv();
1375 return attach_xmldoc(This->node, xmldoc);
1378 return S_OK;
1381 static HRESULT doread( domdoc *This, LPWSTR filename )
1383 bsc_t *bsc;
1384 HRESULT hr;
1386 hr = bind_url(filename, domdoc_onDataAvailable, This, &bsc);
1387 if(FAILED(hr))
1388 return hr;
1390 if(This->bsc)
1391 detach_bsc(This->bsc);
1393 This->bsc = bsc;
1394 return S_OK;
1397 static HRESULT WINAPI domdoc_load(
1398 IXMLDOMDocument2 *iface,
1399 VARIANT xmlSource,
1400 VARIANT_BOOL* isSuccessful )
1402 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1403 LPWSTR filename = NULL;
1404 HRESULT hr = S_FALSE;
1405 IXMLDOMDocument2 *pNewDoc = NULL;
1406 IStream *pStream = NULL;
1407 xmlDocPtr xmldoc;
1409 TRACE("type %d\n", V_VT(&xmlSource) );
1411 *isSuccessful = VARIANT_FALSE;
1413 assert( This->node );
1415 switch( V_VT(&xmlSource) )
1417 case VT_BSTR:
1418 filename = V_BSTR(&xmlSource);
1419 break;
1420 case VT_UNKNOWN:
1421 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IXMLDOMDocument2, (void**)&pNewDoc);
1422 if(hr == S_OK)
1424 if(pNewDoc)
1426 domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );
1427 xmldoc = xmlCopyDoc(get_doc(newDoc), 1);
1428 hr = attach_xmldoc(This->node, xmldoc);
1430 if(SUCCEEDED(hr))
1431 *isSuccessful = VARIANT_TRUE;
1433 return hr;
1436 hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream, (void**)&pStream);
1437 if(hr == S_OK)
1439 IPersistStream *pDocStream;
1440 hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
1441 if(hr == S_OK)
1443 hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
1444 IStream_Release(pStream);
1445 if(hr == S_OK)
1447 *isSuccessful = VARIANT_TRUE;
1449 TRACE("Using ID_IStream to load Document\n");
1450 return S_OK;
1452 else
1454 ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);
1457 else
1459 ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);
1462 else
1464 /* ISequentialStream */
1465 FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr, pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);
1467 break;
1468 default:
1469 FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));
1472 TRACE("filename (%s)\n", debugstr_w(filename));
1474 if ( filename )
1476 hr = doread( This, filename );
1478 if ( FAILED(hr) )
1479 This->error = E_FAIL;
1480 else
1482 hr = This->error = S_OK;
1483 *isSuccessful = VARIANT_TRUE;
1487 if(!filename || FAILED(hr)) {
1488 xmldoc = xmlNewDoc(NULL);
1489 xmldoc->_private = create_priv();
1490 hr = attach_xmldoc(This->node, xmldoc);
1491 if(SUCCEEDED(hr))
1492 hr = S_FALSE;
1495 TRACE("ret (%d)\n", hr);
1497 return hr;
1501 static HRESULT WINAPI domdoc_get_readyState(
1502 IXMLDOMDocument2 *iface,
1503 long* value )
1505 FIXME("\n");
1506 return E_NOTIMPL;
1510 static HRESULT WINAPI domdoc_get_parseError(
1511 IXMLDOMDocument2 *iface,
1512 IXMLDOMParseError** errorObj )
1514 BSTR error_string = NULL;
1515 static const WCHAR err[] = {'e','r','r','o','r',0};
1516 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1518 FIXME("(%p)->(%p): creating a dummy parseError\n", iface, errorObj);
1520 if(This->error)
1521 error_string = SysAllocString(err);
1523 *errorObj = create_parseError(This->error, NULL, error_string, NULL, 0, 0, 0);
1524 if(!*errorObj) return E_OUTOFMEMORY;
1525 return S_OK;
1529 static HRESULT WINAPI domdoc_get_url(
1530 IXMLDOMDocument2 *iface,
1531 BSTR* urlString )
1533 FIXME("\n");
1534 return E_NOTIMPL;
1538 static HRESULT WINAPI domdoc_get_async(
1539 IXMLDOMDocument2 *iface,
1540 VARIANT_BOOL* isAsync )
1542 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1544 TRACE("%p <- %d\n", isAsync, This->async);
1545 *isAsync = This->async;
1546 return S_OK;
1550 static HRESULT WINAPI domdoc_put_async(
1551 IXMLDOMDocument2 *iface,
1552 VARIANT_BOOL isAsync )
1554 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1556 TRACE("%d\n", isAsync);
1557 This->async = isAsync;
1558 return S_OK;
1562 static HRESULT WINAPI domdoc_abort(
1563 IXMLDOMDocument2 *iface )
1565 FIXME("\n");
1566 return E_NOTIMPL;
1570 static BOOL bstr_to_utf8( BSTR bstr, char **pstr, int *plen )
1572 UINT len, blen = SysStringLen( bstr );
1573 LPSTR str;
1575 len = WideCharToMultiByte( CP_UTF8, 0, bstr, blen, NULL, 0, NULL, NULL );
1576 str = HeapAlloc( GetProcessHeap(), 0, len );
1577 if ( !str )
1578 return FALSE;
1579 WideCharToMultiByte( CP_UTF8, 0, bstr, blen, str, len, NULL, NULL );
1580 *plen = len;
1581 *pstr = str;
1582 return TRUE;
1585 static HRESULT WINAPI domdoc_loadXML(
1586 IXMLDOMDocument2 *iface,
1587 BSTR bstrXML,
1588 VARIANT_BOOL* isSuccessful )
1590 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1591 xmlDocPtr xmldoc = NULL;
1592 char *str;
1593 int len;
1594 HRESULT hr = S_FALSE, hr2;
1596 TRACE("%p %s %p\n", This, debugstr_w( bstrXML ), isSuccessful );
1598 assert ( This->node );
1600 if ( isSuccessful )
1602 *isSuccessful = VARIANT_FALSE;
1604 if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
1606 xmldoc = doparse( str, len );
1607 HeapFree( GetProcessHeap(), 0, str );
1608 if ( !xmldoc )
1609 This->error = E_FAIL;
1610 else
1612 hr = This->error = S_OK;
1613 *isSuccessful = VARIANT_TRUE;
1617 if(!xmldoc)
1618 xmldoc = xmlNewDoc(NULL);
1620 xmldoc->_private = create_priv();
1621 hr2 = attach_xmldoc( This->node, xmldoc );
1622 if( FAILED(hr2) )
1623 hr = hr2;
1625 return hr;
1629 static HRESULT WINAPI domdoc_save(
1630 IXMLDOMDocument2 *iface,
1631 VARIANT destination )
1633 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1634 HANDLE handle;
1635 xmlChar *mem, *p;
1636 int size;
1637 HRESULT ret = S_OK;
1638 DWORD written;
1640 TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
1641 V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
1643 if(V_VT(&destination) != VT_BSTR && V_VT(&destination) != VT_UNKNOWN)
1645 FIXME("Unhandled vt %d\n", V_VT(&destination));
1646 return S_FALSE;
1649 if(V_VT(&destination) == VT_UNKNOWN)
1651 IUnknown *pUnk = V_UNKNOWN(&destination);
1652 IXMLDOMDocument *pDocument;
1654 ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
1655 if(ret == S_OK)
1657 BSTR bXML;
1658 VARIANT_BOOL bSuccessful;
1660 ret = IXMLDOMDocument_get_xml(iface, &bXML);
1661 if(ret == S_OK)
1663 ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
1665 SysFreeString(bXML);
1668 IXMLDOMDocument_Release(pDocument);
1671 TRACE("ret %d\n", ret);
1673 return ret;
1676 handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
1677 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
1678 if( handle == INVALID_HANDLE_VALUE )
1680 WARN("failed to create file\n");
1681 return S_FALSE;
1684 xmlDocDumpMemory(get_doc(This), &mem, &size);
1687 * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
1688 * MSXML adds XML declaration only for processing instruction nodes.
1689 * We skip the first XML declaration generated by libxml2 to get exactly what we need.
1691 p = mem;
1692 if(size > 2 && p[0] == '<' && p[1] == '?') {
1693 while(p < mem+size && (p[0] != '?' || p[1] != '>'))
1694 p++;
1695 p += 2;
1696 while(p < mem+size && isspace(*p))
1697 p++;
1698 size -= p-mem;
1701 if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
1703 WARN("write error\n");
1704 ret = S_FALSE;
1707 xmlFree(mem);
1708 CloseHandle(handle);
1709 return ret;
1712 static HRESULT WINAPI domdoc_get_validateOnParse(
1713 IXMLDOMDocument2 *iface,
1714 VARIANT_BOOL* isValidating )
1716 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1718 TRACE("%p <- %d\n", isValidating, This->validating);
1719 *isValidating = This->validating;
1720 return S_OK;
1724 static HRESULT WINAPI domdoc_put_validateOnParse(
1725 IXMLDOMDocument2 *iface,
1726 VARIANT_BOOL isValidating )
1728 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1730 TRACE("%d\n", isValidating);
1731 This->validating = isValidating;
1732 return S_OK;
1736 static HRESULT WINAPI domdoc_get_resolveExternals(
1737 IXMLDOMDocument2 *iface,
1738 VARIANT_BOOL* isResolving )
1740 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1742 TRACE("%p <- %d\n", isResolving, This->resolving);
1743 *isResolving = This->resolving;
1744 return S_OK;
1748 static HRESULT WINAPI domdoc_put_resolveExternals(
1749 IXMLDOMDocument2 *iface,
1750 VARIANT_BOOL isResolving )
1752 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1754 TRACE("%d\n", isResolving);
1755 This->resolving = isResolving;
1756 return S_OK;
1760 static HRESULT WINAPI domdoc_get_preserveWhiteSpace(
1761 IXMLDOMDocument2 *iface,
1762 VARIANT_BOOL* isPreserving )
1764 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1766 TRACE("%p <- %d\n", isPreserving, This->preserving);
1767 *isPreserving = This->preserving;
1768 return S_OK;
1772 static HRESULT WINAPI domdoc_put_preserveWhiteSpace(
1773 IXMLDOMDocument2 *iface,
1774 VARIANT_BOOL isPreserving )
1776 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1778 TRACE("%d\n", isPreserving);
1779 This->preserving = isPreserving;
1780 return S_OK;
1784 static HRESULT WINAPI domdoc_put_onReadyStateChange(
1785 IXMLDOMDocument2 *iface,
1786 VARIANT readyStateChangeSink )
1788 FIXME("\n");
1789 return E_NOTIMPL;
1793 static HRESULT WINAPI domdoc_put_onDataAvailable(
1794 IXMLDOMDocument2 *iface,
1795 VARIANT onDataAvailableSink )
1797 FIXME("\n");
1798 return E_NOTIMPL;
1801 static HRESULT WINAPI domdoc_put_onTransformNode(
1802 IXMLDOMDocument2 *iface,
1803 VARIANT onTransformNodeSink )
1805 FIXME("\n");
1806 return E_NOTIMPL;
1809 static HRESULT WINAPI domdoc_get_namespaces(
1810 IXMLDOMDocument2* iface,
1811 IXMLDOMSchemaCollection** schemaCollection )
1813 FIXME("\n");
1814 return E_NOTIMPL;
1817 static HRESULT WINAPI domdoc_get_schemas(
1818 IXMLDOMDocument2* iface,
1819 VARIANT* var1 )
1821 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1822 HRESULT hr = S_FALSE;
1823 IXMLDOMSchemaCollection *cur_schema = This->schema;
1825 TRACE("(%p)->(%p)\n", This, var1);
1827 VariantInit(var1); /* Test shows we don't call VariantClear here */
1828 V_VT(var1) = VT_NULL;
1830 if(cur_schema)
1832 hr = IXMLDOMSchemaCollection_QueryInterface(cur_schema, &IID_IDispatch, (void**)&V_DISPATCH(var1));
1833 if(SUCCEEDED(hr))
1834 V_VT(var1) = VT_DISPATCH;
1836 return hr;
1839 static HRESULT WINAPI domdoc_putref_schemas(
1840 IXMLDOMDocument2* iface,
1841 VARIANT var1)
1843 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1844 HRESULT hr = E_FAIL;
1845 IXMLDOMSchemaCollection *new_schema = NULL;
1847 FIXME("(%p): semi-stub\n", This);
1848 switch(V_VT(&var1))
1850 case VT_UNKNOWN:
1851 hr = IUnknown_QueryInterface(V_UNKNOWN(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1852 break;
1854 case VT_DISPATCH:
1855 hr = IDispatch_QueryInterface(V_DISPATCH(&var1), &IID_IXMLDOMSchemaCollection, (void**)&new_schema);
1856 break;
1858 case VT_NULL:
1859 case VT_EMPTY:
1860 hr = S_OK;
1861 break;
1863 default:
1864 WARN("Can't get schema from vt %x\n", V_VT(&var1));
1867 if(SUCCEEDED(hr))
1869 IXMLDOMSchemaCollection *old_schema = InterlockedExchangePointer((void**)&This->schema, new_schema);
1870 if(old_schema) IXMLDOMSchemaCollection_Release(old_schema);
1873 return hr;
1876 static HRESULT WINAPI domdoc_validate(
1877 IXMLDOMDocument2* iface,
1878 IXMLDOMParseError** err)
1880 FIXME("\n");
1881 return E_NOTIMPL;
1884 static HRESULT WINAPI domdoc_setProperty(
1885 IXMLDOMDocument2* iface,
1886 BSTR p,
1887 VARIANT var)
1889 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1891 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1893 VARIANT varStr;
1894 HRESULT hr;
1895 BSTR bstr;
1897 V_VT(&varStr) = VT_EMPTY;
1898 if (V_VT(&var) != VT_BSTR)
1900 if (FAILED(hr = VariantChangeType(&varStr, &var, 0, VT_BSTR)))
1901 return hr;
1902 bstr = V_BSTR(&varStr);
1904 else
1905 bstr = V_BSTR(&var);
1907 hr = S_OK;
1908 if (lstrcmpiW(bstr, SZ_VALUE_XPATH) == 0)
1909 This->bUseXPath = TRUE;
1910 else if (lstrcmpiW(bstr, SZ_VALUE_XSLPATTERN) == 0)
1911 This->bUseXPath = FALSE;
1912 else
1913 hr = E_FAIL;
1915 VariantClear(&varStr);
1916 return hr;
1919 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1920 return E_FAIL;
1923 static HRESULT WINAPI domdoc_getProperty(
1924 IXMLDOMDocument2* iface,
1925 BSTR p,
1926 VARIANT* var)
1928 domdoc *This = impl_from_IXMLDOMDocument2( iface );
1930 if (var == NULL)
1931 return E_INVALIDARG;
1932 if (lstrcmpiW(p, SZ_PROPERTY_SELECTION_LANGUAGE) == 0)
1934 V_VT(var) = VT_BSTR;
1935 if (This->bUseXPath)
1936 V_BSTR(var) = SysAllocString(SZ_VALUE_XPATH);
1937 else
1938 V_BSTR(var) = SysAllocString(SZ_VALUE_XSLPATTERN);
1939 return S_OK;
1942 FIXME("Unknown property %s\n", wine_dbgstr_w(p));
1943 return E_FAIL;
1946 static const struct IXMLDOMDocument2Vtbl domdoc_vtbl =
1948 domdoc_QueryInterface,
1949 domdoc_AddRef,
1950 domdoc_Release,
1951 domdoc_GetTypeInfoCount,
1952 domdoc_GetTypeInfo,
1953 domdoc_GetIDsOfNames,
1954 domdoc_Invoke,
1955 domdoc_get_nodeName,
1956 domdoc_get_nodeValue,
1957 domdoc_put_nodeValue,
1958 domdoc_get_nodeType,
1959 domdoc_get_parentNode,
1960 domdoc_get_childNodes,
1961 domdoc_get_firstChild,
1962 domdoc_get_lastChild,
1963 domdoc_get_previousSibling,
1964 domdoc_get_nextSibling,
1965 domdoc_get_attributes,
1966 domdoc_insertBefore,
1967 domdoc_replaceChild,
1968 domdoc_removeChild,
1969 domdoc_appendChild,
1970 domdoc_hasChildNodes,
1971 domdoc_get_ownerDocument,
1972 domdoc_cloneNode,
1973 domdoc_get_nodeTypeString,
1974 domdoc_get_text,
1975 domdoc_put_text,
1976 domdoc_get_specified,
1977 domdoc_get_definition,
1978 domdoc_get_nodeTypedValue,
1979 domdoc_put_nodeTypedValue,
1980 domdoc_get_dataType,
1981 domdoc_put_dataType,
1982 domdoc_get_xml,
1983 domdoc_transformNode,
1984 domdoc_selectNodes,
1985 domdoc_selectSingleNode,
1986 domdoc_get_parsed,
1987 domdoc_get_namespaceURI,
1988 domdoc_get_prefix,
1989 domdoc_get_baseName,
1990 domdoc_transformNodeToObject,
1991 domdoc_get_doctype,
1992 domdoc_get_implementation,
1993 domdoc_get_documentElement,
1994 domdoc_put_documentElement,
1995 domdoc_createElement,
1996 domdoc_createDocumentFragment,
1997 domdoc_createTextNode,
1998 domdoc_createComment,
1999 domdoc_createCDATASection,
2000 domdoc_createProcessingInstruction,
2001 domdoc_createAttribute,
2002 domdoc_createEntityReference,
2003 domdoc_getElementsByTagName,
2004 domdoc_createNode,
2005 domdoc_nodeFromID,
2006 domdoc_load,
2007 domdoc_get_readyState,
2008 domdoc_get_parseError,
2009 domdoc_get_url,
2010 domdoc_get_async,
2011 domdoc_put_async,
2012 domdoc_abort,
2013 domdoc_loadXML,
2014 domdoc_save,
2015 domdoc_get_validateOnParse,
2016 domdoc_put_validateOnParse,
2017 domdoc_get_resolveExternals,
2018 domdoc_put_resolveExternals,
2019 domdoc_get_preserveWhiteSpace,
2020 domdoc_put_preserveWhiteSpace,
2021 domdoc_put_onReadyStateChange,
2022 domdoc_put_onDataAvailable,
2023 domdoc_put_onTransformNode,
2024 domdoc_get_namespaces,
2025 domdoc_get_schemas,
2026 domdoc_putref_schemas,
2027 domdoc_validate,
2028 domdoc_setProperty,
2029 domdoc_getProperty
2032 /* xmldoc implementation of IObjectWithSite */
2033 static HRESULT WINAPI
2034 xmldoc_ObjectWithSite_QueryInterface( IObjectWithSite* iface, REFIID riid, void** ppvObject )
2036 domdoc *This = impl_from_IObjectWithSite(iface);
2037 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppvObject );
2040 static ULONG WINAPI
2041 xmldoc_ObjectWithSite_AddRef( IObjectWithSite* iface )
2043 domdoc *This = impl_from_IObjectWithSite(iface);
2044 return IXMLDocument_AddRef((IXMLDocument *)This);
2047 static ULONG WINAPI
2048 xmldoc_ObjectWithSite_Release( IObjectWithSite* iface )
2050 domdoc *This = impl_from_IObjectWithSite(iface);
2051 return IXMLDocument_Release((IXMLDocument *)This);
2054 static HRESULT WINAPI
2055 xmldoc_GetSite( IObjectWithSite *iface, REFIID iid, void ** ppvSite )
2057 domdoc *This = impl_from_IObjectWithSite(iface);
2059 TRACE("%p %s %p\n", This, debugstr_guid( iid ), ppvSite );
2061 if ( !This->site )
2062 return E_FAIL;
2064 return IUnknown_QueryInterface( This->site, iid, ppvSite );
2067 static HRESULT WINAPI
2068 xmldoc_SetSite( IObjectWithSite *iface, IUnknown *punk )
2070 domdoc *This = impl_from_IObjectWithSite(iface);
2072 TRACE("%p %p\n", iface, punk);
2074 if(!punk)
2076 if(This->site)
2078 IUnknown_Release( This->site );
2079 This->site = NULL;
2082 return S_OK;
2085 if ( punk )
2086 IUnknown_AddRef( punk );
2088 if(This->site)
2089 IUnknown_Release( This->site );
2091 This->site = punk;
2093 return S_OK;
2096 static const IObjectWithSiteVtbl domdocObjectSite =
2098 xmldoc_ObjectWithSite_QueryInterface,
2099 xmldoc_ObjectWithSite_AddRef,
2100 xmldoc_ObjectWithSite_Release,
2101 xmldoc_SetSite,
2102 xmldoc_GetSite,
2105 static HRESULT WINAPI xmldoc_Safety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
2107 domdoc *This = impl_from_IObjectSafety(iface);
2108 return IXMLDocument_QueryInterface( (IXMLDocument *)This, riid, ppv );
2111 static ULONG WINAPI xmldoc_Safety_AddRef(IObjectSafety *iface)
2113 domdoc *This = impl_from_IObjectSafety(iface);
2114 return IXMLDocument_AddRef((IXMLDocument *)This);
2117 static ULONG WINAPI xmldoc_Safety_Release(IObjectSafety *iface)
2119 domdoc *This = impl_from_IObjectSafety(iface);
2120 return IXMLDocument_Release((IXMLDocument *)This);
2123 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_SECURITY_MANAGER)
2125 static HRESULT WINAPI xmldoc_Safety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2126 DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
2128 domdoc *This = impl_from_IObjectSafety(iface);
2130 TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
2132 if(!pdwSupportedOptions || !pdwEnabledOptions)
2133 return E_POINTER;
2135 *pdwSupportedOptions = SUPPORTED_OPTIONS;
2136 *pdwEnabledOptions = This->safeopt;
2138 return S_OK;
2141 static HRESULT WINAPI xmldoc_Safety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
2142 DWORD dwOptionSetMask, DWORD dwEnabledOptions)
2144 domdoc *This = impl_from_IObjectSafety(iface);
2146 TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
2148 if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
2149 return E_FAIL;
2151 This->safeopt = dwEnabledOptions & dwEnabledOptions;
2152 return S_OK;
2155 static const IObjectSafetyVtbl domdocObjectSafetyVtbl = {
2156 xmldoc_Safety_QueryInterface,
2157 xmldoc_Safety_AddRef,
2158 xmldoc_Safety_Release,
2159 xmldoc_Safety_GetInterfaceSafetyOptions,
2160 xmldoc_Safety_SetInterfaceSafetyOptions
2164 static const tid_t domdoc_iface_tids[] = {
2165 IXMLDOMNode_tid,
2166 IXMLDOMDocument_tid,
2167 IXMLDOMDocument2_tid,
2170 static dispex_static_data_t domdoc_dispex = {
2171 NULL,
2172 IXMLDOMDocument2_tid,
2173 NULL,
2174 domdoc_iface_tids
2177 HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument2 **document)
2179 domdoc *doc;
2180 HRESULT hr;
2182 doc = HeapAlloc( GetProcessHeap(), 0, sizeof (*doc) );
2183 if( !doc )
2184 return E_OUTOFMEMORY;
2186 doc->lpVtbl = &domdoc_vtbl;
2187 doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
2188 doc->lpvtblIObjectWithSite = &domdocObjectSite;
2189 doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
2190 doc->lpvtblISupportErrorInfo = &support_error_vtbl;
2191 doc->ref = 1;
2192 doc->async = 0;
2193 doc->validating = 0;
2194 doc->resolving = 0;
2195 doc->preserving = 0;
2196 doc->bUseXPath = FALSE;
2197 doc->error = S_OK;
2198 doc->schema = NULL;
2199 doc->stream = NULL;
2200 doc->site = NULL;
2201 doc->safeopt = 0;
2202 doc->bsc = NULL;
2204 doc->node_unk = create_basic_node( (xmlNodePtr)xmldoc, (IUnknown*)&doc->lpVtbl );
2205 if(!doc->node_unk)
2207 HeapFree(GetProcessHeap(), 0, doc);
2208 return E_FAIL;
2211 hr = IUnknown_QueryInterface(doc->node_unk, &IID_IXMLDOMNode, (LPVOID*)&doc->node);
2212 if(FAILED(hr))
2214 IUnknown_Release(doc->node_unk);
2215 HeapFree( GetProcessHeap(), 0, doc );
2216 return E_FAIL;
2219 init_dispex(&doc->dispex, (IUnknown*)&doc->lpVtbl, &domdoc_dispex);
2221 /* The ref on doc->node is actually looped back into this object, so release it */
2222 IXMLDOMNode_Release(doc->node);
2224 *document = (IXMLDOMDocument2*)&doc->lpVtbl;
2226 TRACE("returning iface %p\n", *document);
2227 return S_OK;
2230 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2232 xmlDocPtr xmldoc;
2233 HRESULT hr;
2235 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2237 xmldoc = xmlNewDoc(NULL);
2238 if(!xmldoc)
2239 return E_OUTOFMEMORY;
2241 xmldoc->_private = create_priv();
2243 hr = DOMDocument_create_from_xmldoc(xmldoc, (IXMLDOMDocument2**)ppObj);
2244 if(FAILED(hr))
2245 xmlFreeDoc(xmldoc);
2247 return hr;
2250 IUnknown* create_domdoc( xmlNodePtr document )
2252 HRESULT hr;
2253 LPVOID pObj = NULL;
2255 TRACE("(%p)\n", document);
2257 hr = DOMDocument_create_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument2**)&pObj);
2258 if (FAILED(hr))
2259 return NULL;
2261 return (IUnknown*)pObj;
2264 #else
2266 HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2268 MESSAGE("This program tried to use a DOMDocument object, but\n"
2269 "libxml2 support was not present at compile time.\n");
2270 return E_NOTIMPL;
2273 #endif